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

2012年(12)

2011年(24)

2010年(24)

2009年(75)

2008年(42)

我的朋友

分类: C/C++

2009-11-16 22:50:11

     这两天忙于修改apache连接resin的模块中的一个问题,一致没有继续读coreutils,今天继续,不能停止,今天读的是readlink.c,作用是把符号连接的值打印出来

/* readlink -- display value of a symbolic link.
显示符号连接的值  */

/* Written by Dmitry V. Levin */

//包含4个标准的头文件
#include
#include
#include
#include
//包含5个本地的头文件,下面的程序会用到这些头文件里的定义
#include "system.h"
#include "canonicalize.h"
#include "error.h"
#include "xreadlink.h"
#include "quote.h"

/* The official name of this program (e.g., no `g' prefix).  */
#define PROGRAM_NAME "readlink"//定义宏PROGRAM_NAME,其值是一个字符串,含义为程序的名称

#define AUTHORS "Dmitry V. Levin"//定义宏AUTHORS,其值也是个字符串,意义为作者的名字

/* Name this program was run with.  */
char *program_name;//声明一个全局字符指针变量

/* If true, do not output the trailing newline.  */
static bool no_newline;//声明全局静态布尔变量no_newline

/* If true, report error messages.  */
static bool verbose;//声明全局静态布尔变量verbose,看注释这个变量用来决定是否打印错误信息

static struct option const longopts[] =
{
  {"canonicalize", no_argument, NULL, 'f'},
  {"canonicalize-existing", no_argument, NULL, 'e'},
  {"canonicalize-missing", no_argument, NULL, 'm'},
  {"no-newline", no_argument, NULL, 'n'},
  {"quiet", no_argument, NULL, 'q'},
  {"silent", no_argument, NULL, 's'},
  {"verbose", no_argument, NULL, 'v'},
  {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//否则,打印下面的这一段字符串
    {
      printf (_("Usage: %s [OPTION]... FILE\n"), program_name);
      fputs (_("Display value of a symbolic link on standard output.\n\n"),
         stdout);
      fputs (_("\
  -f, --canonicalize            canonicalize by following every symlink in\n\
                                every component of the given name recursively;\n\
                                all but the last component must exist\n\
  -e, --canonicalize-existing   canonicalize by following every symlink in\n\
                                every component of the given name recursively,\n\
                                all components must exist\n\
"), stdout);
      fputs (_("\
  -m, --canonicalize-missing    canonicalize by following every symlink in\n\
                                every component of the given name recursively,\n\
                                without requirements on components existence\n\
  -n, --no-newline              do not output the trailing newline\n\
  -q, --quiet,\n\
  -s, --silent                  suppress most error messages\n\
  -v, --verbose                 report error messages\n\
"), stdout);
      fputs (HELP_OPTION_DESCRIPTION, stdout);
      fputs (VERSION_OPTION_DESCRIPTION, stdout);
      printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
    }
  exit (status);//帮助函数调用后,不是return返回,而是直接退出程序
}

int
main (int argc, char **argv)//main函数的实现部分
{
  /* If not -1, use this method to canonicalize.  */
  int can_mode = -1;//定义整型变量can_mode,初始值为-1,如果值不是-1,则使用这个方法来示例,下面继续看

  /* File name to canonicalize.  */
  const char *fname;//定义一个字符指针常量fname,是用来示例的文件名

  /* Result of canonicalize.  */
  char *value;//声明字符指针变量,用来保存示例的结果

  int optc;//声明整型变量optc

  initialize_main (&argc, &argv);//下面的5步操作都是标准的可移植程序的写法
  program_name = argv[0];
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);

  atexit (close_stdout);//登记出口函数

  while ((optc = getopt_long (argc, argv, "efmnqsv", longopts, NULL)) != -1)
    {//这个while循环的循环条件是,调用getopt_long函数,结果保存在整型变量optc中,如果optc的值不为-1,则循环继续,否则退出循环
      switch (optc)//每次得到一个optc的值,都进入switch语句进行分支选择
    {
    case 'e'://如果optc的值是字符e,则将整型变量can_mode的值设置为CAN_EXISTING,下面的各个分支都类似,根据得到的optc的值,给相应的变量赋值
      can_mode = CAN_EXISTING;
      break;
    case 'f':
      can_mode = CAN_ALL_BUT_LAST;
      break;
    case 'm':
      can_mode = CAN_MISSING;
      break;
    case 'n':
      no_newline = true;
      break;
    case 'q':
    case 's':
      verbose = false;//这个技巧在书上看到过,如果optc是q或者s都执行这个赋值
      break;
    case 'v':
      verbose = true;
      break;
    case_GETOPT_HELP_CHAR;
    case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
    default:
      usage (EXIT_FAILURE);//如果不匹配上面列出来的,则调用帮助函数并退出程序
    }
    }

  if (optind >= argc)//上面的while循环结束后,如果optind大于或者等于argc的值,则调用error函数并调用帮助函数
    {
      error (0, 0, _("missing operand"));
      usage (EXIT_FAILURE);
    }

  fname = argv[optind++];//程序执行到这里,将argv[optind]赋给fname,并增加optind的值

  if (optind < argc)//如果加1后,optind的值小于argc,也说明有错误,这时候调用error函数并打印帮助信息,然后退出程序
    {
      error (0, 0, _("extra operand %s"), quote (argv[optind]));
      usage (EXIT_FAILURE);
    }

  value = (can_mode != -1
       ? canonicalize_filename_mode (fname, can_mode)
       : xreadlink (fname));
  /*
这是一个条件语句,首先来判断can_mode是否等于-1,如果不等于,则执行:前面的语句,调用canonicalize_filename_mode函数
否则调用xreadlink函数,最后得到的值赋给value
  */
  if (value)//如果value不是0,则执行下面的语句块
    {
      printf ("%s%s", value, (no_newline ? "" : "\n"));//打印value,并判断是否打印回车符
      free (value);//释放value占用的内存空间
      return EXIT_SUCCESS;//main函数返回成功状态
    }

  if (verbose)//如果verbose的值不是0,则调用error函数
    error (EXIT_FAILURE, errno, "%s", fname);

  return EXIT_FAILURE;//返回失败
}
/*
此程序最主要的还是得到value的值,那个条件语句里调用的两个函数才是关键所在,是在头文件定义的。
*/

阅读(1441) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~