这两天忙于修改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的值,那个条件语句里调用的两个函数才是关键所在,是在头文件定义的。
*/
阅读(1430) | 评论(0) | 转发(0) |