Chinaunix首页 | 论坛 | 博客
  • 博客访问: 929100
  • 博文数量: 177
  • 博客积分: 8613
  • 博客等级: 中将
  • 技术积分: 2835
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-12 04:16
文章分类
文章存档

2012年(12)

2011年(24)

2010年(24)

2009年(75)

2008年(42)

我的朋友

分类: C/C++

2009-11-09 22:42:18

    这两天忙着改写一个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) |
给主人留下些什么吧!~~