cat显示一个文件的内容。需要注意的是,cat并不能处理目录。

 1 extern int cat_main(int argc, char **argv)
 2 {
 3     int status = EXIT_SUCCESS;
 4 
 5     if (argc == 1) {
 6         print_file(stdin);
 7         return status;
 8     }
 9 
10     while (--argc > 0) {
11         if(!(strcmp(*++argv, "-"))) {
12             print_file(stdin);
13         } else if (print_file_by_name(*argv) == FALSE) {
14             status = EXIT_FAILURE;
15         }
16     }
17     return status;
18 }

      当输入cat或者是cat -时,都会调用print_file函数。

1 extern void print_file(FILE *file)
2 {
3     fflush(stdout);
4     copyfd(fileno(file), fileno(stdout));//将file文件的内容拷贝到stdout
5     fclose(file);
6 }

      显然,print_file(stdin)就是将stdin的内容拷贝到stdout。即输入什么,就输出什么。

 

V658tekiMacBook-Pro:busybox-0.60.3 neilhappy$ cat -
input--stdin
input--stdin

 

      当cat filename时,进入print_file_by_name函数。

      


1
extern int print_file_by_name(char *filename) 2 { 3 struct stat statBuf; 4 int status = TRUE; 5 6 if(is_directory(filename, TRUE, &statBuf)==TRUE) { 7 error_msg("%s: Is directory", filename); 8 status = FALSE; 9 } else { 10 FILE *f = wfopen(filename, "r"); 11 if(f!=NULL) 12 print_file(f); 13 else 14 status = FALSE; 15 } 16 17 return status; 18 }

      is_directory判断是否是目录。如果不是目录,就用pring_file函数打印。要注意,这里的TRUE参数决定了只使用stat(不考虑符号链接)。

 1 int is_directory(const char *fileName, const int followLinks, struct stat *statBuf)
 2 {
 3     int status;
 4     int didMalloc = 0;
 5 
 6     if (statBuf == NULL) {
 7         statBuf = (struct stat *)xmalloc(sizeof(struct stat));
 8         ++didMalloc;
 9     }
10 
11     if (followLinks == TRUE)
12         status = stat(fileName, statBuf);
13     else
14         status = lstat(fileName, statBuf);
15 
16     if (status < 0 || !(S_ISDIR(statBuf->st_mode))) {
17         status = FALSE;
18     }
19     else status = TRUE;
20 
21     if (didMalloc) {
22         free(statBuf);
23         statBuf = NULL;
24     }
25     return status;
26 }

       整个流程的结构非常清晰。

posted on 2013-02-15 12:25  NeilHappy  阅读(2250)  评论(3编辑  收藏  举报