linux下ls命令(支持-R参数)的c语言实现:
#include <stdio.h> #include <sys/types.h> #include <dirent.h> #include <sys/stat.h> #include <pwd.h> #include <grp.h> #include <string.h> void do_ls(char *); void do_stat(char *,char *); void show_file_info(char *,struct stat *,char *); void mode_to_letters(int ,char []); char * uid_to_name(uid_t); char * gid_to_name(gid_t); int recursive = 0; int main(int argc,char * argv[]) { int i; for(i = 1;i < argc;i++) { if(strcmp(argv[i],"-R") == 0) { recursive = 1; break; } } if(argc == 1 && recursive == 0) do_ls("."); else if(argc == 2 && recursive == 1) do_ls("."); else { int index = 1; while(argc > 1) { if(strcmp(argv[index],"-R") != 0) do_ls(argv[index]); index++; argc--; } } return 0; } void do_ls(char * path) { DIR * dir; struct dirent * direntp; if((dir = opendir(path)) != NULL) { while((direntp = readdir(dir)) != NULL) { char absolute_pathname[255]; strcpy(absolute_pathname,path); strcat(absolute_pathname,"/"); strcat(absolute_pathname,direntp->d_name); printf("%s\n",absolute_pathname); do_stat(absolute_pathname,direntp->d_name); } closedir(dir); } else fprintf(stderr,"can't open %s",path); } void do_stat(char * absolute_filename,char * filename) { struct stat s; if(lstat(absolute_filename,&s) == -1) perror(absolute_filename); else show_file_info(absolute_filename,&s,filename); } void show_file_info(char * absolute_filename,struct stat * info,char * filename) { char mode[11]; mode_to_letters(info->st_mode,mode); printf("%s ",mode); printf("%d ",info->st_nlink); printf("%s ",uid_to_name(info->st_uid)); printf("%s ",gid_to_name(info->st_gid)); printf("%d ",info->st_size); printf("%.12s ",4+ctime(&info->st_mtime)); printf("\n"); if(recursive == 1) { if(S_ISDIR(info->st_mode) && strcmp(filename,".") != 0 && strcmp(filename,"..") != 0) do_ls(absolute_filename); } } void mode_to_letters(int mode,char * c_mode) { strcpy(c_mode,"----------"); if(S_ISDIR(mode)) c_mode[0] = 'd'; if(S_ISCHR(mode)) c_mode[0] = 'c'; if(S_ISBLK(mode)) c_mode[0] = 'b'; if(mode & S_IRUSR) c_mode[1] = 'r'; if(mode & S_IWUSR) c_mode[2] = 'w'; if(mode & S_IXUSR) c_mode[3] = 'x'; if(mode & S_IRGRP) c_mode[4] = 'r'; if(mode & S_IWGRP) c_mode[5] = 'w'; if(mode & S_IXGRP) c_mode[6] = 'x'; if(mode & S_IROTH) c_mode[7] = 'r'; if(mode & S_IWOTH) c_mode[8] = 'w'; if(mode & S_IXOTH) c_mode[9] = 'x'; if(mode & S_ISUID) c_mode[3] = 's'; if(mode & S_ISGID) c_mode[6] = 's'; if(mode & S_ISVTX) c_mode[9] = 's'; } char * uid_to_name(uid_t uid) { struct passwd * passwd_pointer; passwd_pointer = getpwuid(uid); return passwd_pointer->pw_name; } char * gid_to_name(gid_t gid) { struct group * group_pointer; static char numstr[10]; if((group_pointer = getgrgid(gid)) == NULL) { sprintf(numstr,"%d",gid); return numstr; } return group_pointer->gr_name; }