这两天忙着改写一个apache的模块,上周5在分析的mkfifo.c今天终于注释完了,学习要坚持啊,不能give up
/* mkfifo -- make fifo's (named pipes)
Copyright (C) 90, 91, 1995-2006 Free Software Foundation, Inc.
创建命名管道
*/
/* David MacKenzie */
//包含进来4个标准的头文件
#include
#include
#include
#include
//包含4个本地的头文件
#include "system.h"
#include "error.h"
#include "modechange.h"
#include "quote.h"
/* The official name of this program (e.g., no `g' prefix). */
#define PROGRAM_NAME "mkfifo"//定义宏PROGRAM_NAME,其值是一个字符串
#define AUTHORS "David MacKenzie"//定义宏AUTHORS,其值是一个字符串
/* The name this program was run with. */
char *program_name;//定义全局字符指针变量program_name
//定义一个静态的option结构类型的结构体数组,有3个元素
static struct option const longopts[] =
{
{"mode", required_argument, NULL, 'm'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
};
void
usage (int status)//帮助函数
{
if (status != EXIT_SUCCESS)//如果得到的形参status不等于EXIT_SUCCESS,则往标准错误上打印一个字符串,提示用户使用--help帮助
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
else//否则,如果status等于EXIT_SUCCESS,则打印下面的语句块里的字符串
{
printf (_("Usage: %s [OPTION] NAME...\n"), program_name);
fputs (_("\
Create named pipes (FIFOs) with the given NAMEs.\n\
\n\
"), stdout);//这些字符串都是打印到标准输出的,这一行表达了程序的作用,创建命名管道
fputs (_("\
Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (_("\
-m, --mode=MODE set file permission bits to MODE, not a=rw - umask\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
}
exit (status);//调用完usage函数后,退出程序。
}
int
main (int argc, char **argv)//标准的main函数定义
{//google了一下,说这个mode_t类型其实就是unsigned int类型
mode_t newmode;
char const *specified_mode = NULL;//定义一个字符指针常量,其值为NULL
int exit_status = EXIT_SUCCESS;//初始化一个整型变量exit_status,其值为宏EXIT_SUCCESS
int optc;//声明整型变量optc
initialize_main (&argc, &argv);//初始化命令行参数
program_name = argv[0];//将命令行参数的第一个字符串赋给字符指针变量program_name
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
atexit (close_stdout);//登记出口函数
//下面的这个while循环是将getopt_long函数调用后的返回值赋给optc,判断optc的值如果不是-1,则进行switch判断
while ((optc = getopt_long (argc, argv, "m:", longopts, NULL)) != -1)
{
switch (optc)
{
case 'm'://如果optc的值等于字符m,则将指针specified_mode的值改变为optarg,optarg是调用函数getopt_long后得到的值
specified_mode = optarg;
break;
//下面的这两个case判断是在头文件system.h里面定义的宏,跳过去查看即可,有了source insight,看代码的确方便多了
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default://如果optc的值不匹配上面列出来的,则调用usage帮助函数,并退出程序。
usage (EXIT_FAILURE);
}
}
if (optind == argc)//如果optind的值等于argc的值,则调用error函数并调用usage函数,最终终止了程序
{
error (0, 0, _("missing operand"));
usage (EXIT_FAILURE);
}
newmode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);//为newmode赋值,这个赋值方式估计是mode_t类型的变量的赋值方式了
if (specified_mode)//如果specified_mode不是空指针
{//初始化一个struct mode_change类型的指针,其值是由mode_compile函数得到的值,mode_compile函数我没有man到,不知道怎么弄的
struct mode_change *change = mode_compile (specified_mode);
if (!change)//如果上一步调用mode_compile后,得到的是个空指针,则报错
error (EXIT_FAILURE, 0, _("invalid mode"));
//程序继续执行,newmode的值是调用函数mode_adjust得到的,mode_adjust函数我没有man到,也没有google到,这也和上面的初始化类似的是一个mode_t类型的值
newmode = mode_adjust (newmode, false, umask (0), change, NULL);
//调用free函数,释放change指针指向的内存空间
free (change);
if (newmode & ~S_IRWXUGO)//括号里的意思是用newmode和S_IRWXUGO按位取反后的二进制数进行与操作,如果最终的值是非0的值,则:
error (EXIT_FAILURE, 0,
_("mode must specify only file permission bits"));//调用error函数
}
for (; optind < argc; ++optind)//此循环的条件是optind小于argc,调整语句是增加optind的值
if (mkfifo (argv[optind], newmode) != 0)//这里是这个程序关键的地方,说白了就是调用库函数mkfifo,库函数的第一个参数是路径名,第二个参数是mode,函数返回0代表成功,失败则返回非0值,这时候就调用error函数报错了
{
error (0, errno, _("cannot create fifo %s"), quote (argv[optind]));
exit_status = EXIT_FAILURE;//调用库函数mkfifo失败后,将exit_status的值改变为EXIT_FAILURE
}
exit (exit_status);//程序的退出状态是exit_status的值
}
阅读(1589) | 评论(0) | 转发(0) |