busybox源码剖析(3)---cat.c

      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 }

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

你可能感兴趣的:(cat)