Chinaunix首页 | 论坛 | 博客

分类: LINUX

2011-10-11 13:48:08

接着分析:
这段是将刚才那些模糊匹配的结构写入stderr文件.
 _IO_flockfile (stderr);它完成的是用本线程对stderr进行加锁,目的是它占用用来输出错误信息给终端。[code]
 563   int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
 564                       ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; /*==++>  #define _IO_FLAGS2_NOTCANCEL 2*/
 565
 566                       __fxprintf (NULL, "%s", buf);1、______________---------------->
 567
 568                       ((_IO_FILE *) stderr)->_flags2 = old_flags2;
 569                       _IO_funlockfile (stderr);  /*解锁,把缓冲区释放*/
 570
 571                       free (buf);
 572                     }
 573                 }
[/code][code]
此结构定义在libio/libio.h,               stderr是个io文件。
 271 struct _IO_FILE {
  272   int _flags;           /* High-order word is _IO_MAGIC; rest is flags. */
  273 #define _IO_file_flags _flags /*=======>文件中有定义*/
  274
  275   /* The following pointers correspond to the C++ streambuf protocol. */
 . . .  . .
  306   char _shortbuf[1];
  307
  308   /*  char* _save_gptr;  char* _save_egptr; */
  309
  310   _IO_lock_t *_lock;
  311 #ifdef _IO_USE_OLD_IO_FILE
  312 };
[/code][code]
1、_____________-------------------->
 30 __fxprintf (FILE *fp, const char *fmt, ...) /*将数据打印到某个文件中*/
   31 {
   32   if (fp == NULL)
   33     fp = stderr;  /*这里是stderr文件*/
   34
   35   va_list ap;           /*va_list是规定指向一个可变参数的动态指针结构*/
   36   va_start (ap, fmt);    /*初始化为指向第一个元素*/
   37
   38   int res;
   39   if (_IO_fwide (fp, 0) > 0)
   40     {
   41       size_t len = strlen (fmt) + 1;  /*size_t使用 详见博客size_t。*/
   42       wchar_t wfmt[len];                 /*GNU Libc规定wchar_t为32位*/
   43       for (size_t i = 0; i < len; ++i)   
   44         {
   45           assert (isascii (fmt[i]));  /*断言是数组内字符是ascii码*/
   46           wfmt[i] = fmt[i];  /*将其中的值赋给wfmt[i];*/
   47         }
   48       res = __vfwprintf (fp, wfmt, ap); /*写入文件中  外部定义的 extern int __vfwprintf (__FILE *__restrict __s, __const wchar_t *__restrict __format,__gnuc_va_list __arg)*/
   49     }
   50   else
   51     res = INTUSE(_IO_vfprintf) (fp, fmt, ap); /*输入文件*/
   52
   53   va_end (ap);
   54
   55   return res;
   56 }
[/code][code]
<---------------------_________________
/*如果没有定义libc和libio等就用这种直接写的方式*/
 574 #else
 575               fprintf (stderr,
 576                        _("%s: option '%s' is ambiguous; possibilities:"),
 577                        argv[0], argv[d->optind]);
 578               do
 579                 {
 580                   fprintf (stderr, " '--%s'", ambig_list->p->name);
 581                   ambig_list = ambig_list->next;
 582                 }
 583               while (ambig_list != NULL);
 584
 585               fputc ('\n', stderr);
 586 #endif
 587             }
 588           d->__nextchar += strlen (d->__nextchar); /*nextchar 是指针类型,指向下一个*/
 589           d->optind++;                     /*下个选项*/
 590           d->optopt = 0;              
 591           return '?';  /*返回0*/
 592         }这些是将所有的模糊匹配的都打印出来*/
 594       while (ambig_list != NULL)
 595         {
 596           struct option_list *pn = ambig_list->next;
 597           free (ambig_list);
 598           ambig_list = pn;
 599         }
整层函数都是返回错误提示的。比如返回?的字符值。如果有参数并且短选项为空,代表没有短选项那么就打印?的字符值否则打印:的字符值。
[/code][code]
<----------------__________________
返回到 ,这里将optind等参数根据返回情况从新赋值*/
1128 _getopt_internal (int argc, char **argv, const char *optstring,
1129                   const struct option *longopts, int *longind, int long_only,
1130                   int posixly_correct)
1131 {
1132   int result;
1133
1134   getopt_data.optind = optind;
1135   getopt_data.opterr = opterr;
1136       
1137   result = _getopt_internal_r (argc, argv, optstring, longopts,
1138                                longind, long_only, &getopt_data,
1139                                posixly_correct);
1140
1141   optind = getopt_data.optind;
1142   optarg = getopt_data.optarg;
1143   optopt = getopt_data.optopt;
1144
1145   return result;  /*返回的仍然是上面的那些字符,如果返回的是-1,说明查找到了选项*/
}
[/code][code]
<------------------------_____________________
 927   while ((retconf = getopt_long (argc, argv,
 928                                 short_options, long_options, &longindex)) != -1)
 929     {
 930       int confval;
 931       bool userrc_ret = true;
 932       struct cmdline_option *config_opt;
 933       confval = long_options[longindex].val;
 934       config_opt = &option_data[confval & ~BOOLEAN_NEG_MARKER];
 935       if (strcmp (config_opt->long_name, "config") == 0)
 936         {
 937           userrc_ret &= run_wgetrc (optarg);  /*run_wgetrc记录数据optarg文件中*/3、_____--->
 938           use_userconfig = true;
 939         }
 940       if (!userrc_ret) /*如果返回NULL,说明出错*/
 941         {
 942           printf ("Exiting due to error in %s\n", optarg);
 943           exit (2);
 944         }
 945       else  /*如果没有注册,就直接返回错误*/
 946         break;  
 947     }
[/code][code] 将一些可以接受的模式打印进一个文件中,供应用程序判断。和防火墙类似,好像再从用户这里得到规则。
3、__________----------------->
 529 bool  
 530 run_wgetrc (const char *file)
 531 {     
 532   FILE *fp;
 533   char *line;
 534   int ln;
 535   int errcnt = 0;
 536       
 537   fp = fopen (file, "r"); 打开optarg文件。
 538   if (!fp)
 539     {     
 540       fprintf (stderr, _("%s: Cannot read %s (%s).\n"), exec_name,
 541                file, strerror (errno));
 542       return true;                      /* not a fatal error */
 543     }
 544   ln = 1;                       
 545   while ((line = read_whole_line (fp)) != NULL) 
 546     { 
 547       char *com = NULL, *val = NULL;
 548       int comind;
 549
 550       /* Parse the line.  解析行中的参数*/
 551       switch (parse_line (line, &com, &val, &comind)) /*这个函数返回命令和参数*/
 552         {
 553         case line_ok:  
 554           /* If everything is OK, set the value.  */
 555           if (!setval_internal_tilde (comind, com, val))  /*这里是将命令的可接受的模式列表(从home开始)组合起来并把他们放入&opt.place指向的地址。
 556             {
 557               fprintf (stderr, _("%s: Error in %s at line %d.\n"),
 558                        exec_name, file, ln);
 559               ++errcnt;
 560             }
 561           break;
 562         case line_syntax_error:  /*其他的错误就打印出来*'/
 563           fprintf (stderr, _("%s: Syntax error in %s at line %d.\n"),
 564                    exec_name, file, ln);
 565           ++errcnt;
 566           break;
 567         case line_unknown_command:
 568           fprintf (stderr, _("%s: Unknown command %s in %s at line %d.\n"),
 569                    exec_name, quote (com), file, ln);
 570           ++errcnt;
 571           break;
 572         case line_empty:
 573           break;
 574         default:
 575           abort ();
 576         }
 577       xfree_null (com); /*释放*/
 578       xfree_null (val);
 579       xfree (line);
 580       ++ln;
 581     }
 582   fclose (fp);
 583
 584   return errcnt == 0;
 585 }
[/code]
阅读(959) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~