Linux基礎—ls功能的簡單實現
簡單的ls實現,首先,我們需要遍歷參數目錄下的各個文件,再根據文件相應的性質,讀取文件的權限,用戶組,用戶名,大小,最后一次訪問的時間,再根據文件名排序后依次顯示。
具體的函數聲明如下:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <sys/stat.h> 5 #include <fcntl.h> 6 #include <unistd.h> 7 #include <dirent.h> 8 #include <sys/types.h> 9 #include <pwd.h> 10 #include <grp.h> 11 #include <time.h> 12 #define CNT 256 13 int file_name(DIR *fp, char *path, char name[][CNT]); 14 void str_sort(char name[][CNT], int cnt); 15 void mode_to_char(mode_t mode, char *buf); 16 char *time_change(char *time); 17 void show(char name[][CNT], int cnt); |
目錄的遍歷,我們需要知道目錄下讀取到的文件個數,所以需要返回相應的int型值。
目錄的遍歷實現如下:
1intfile_name(DIR*fp,char*path,charname[][CNT]) 2{ 3intcnt=0; 4structdirent*p; 5while((p=readdir(fp))!=NULL) 6{ 7if(strncmp(p->d_name,".",1)==0||strncmp(p->d_name,"..",2)==0) 8continue; 9strcpy(name[cnt],path); 10strcat(name[cnt],"/"); 11strcat(name[cnt],p->d_name); 12cnt++; 13} 14closedir(fp); 15returncnt; 16} |
然后我們需要了解文件的權限,文件權限保存在相對應的參數char *buf中。
文件權限的解讀實現如下:
1 void mode_to_char (mode_t mode, char *buf) 2 { 3 memset(buf, '-', 10); 4 if(S_ISDIR(mode)) 5 buf[0] = 'd'; 6 if(mode & S_IRUSR) 7 buf[1] = 'r'; 8 if(mode & S_IWUSR) 9 buf[2] = 'w'; 10 if(mode & S_IXUSR) 11 buf[3] = 'x'; 12 if(mode & S_IRGRP) 13 buf[4] = 'r'; 14 if(mode & S_IWGRP) 15 buf[5] = 'w'; 16 if(mode & S_IXGRP) 17 buf[6] = 'x'; 18 if(mode & S_IROTH) 19 buf[7] = 'r'; 20 if(mode & S_IWOTH) 21 buf[8] = 'w'; 22 if(mode & S_IXOTH) 23 buf[9] = 'x'; 24 } |
想應的,時間的顯示不需要那么精確,所以我們應適當的縮短時間精確度。
時間的顯示實現如下:
1 char *time_change(char *time)
2 {
3 int index = strlen(time) - 1;
4 for(; time[index] != ':'; index --);
5 time[index] = '\0';
6 return time + 4;
7 }
然后,我們需要根據文件名稱按照字典序排序。
排序的實現如下:
1 void str_sort(char name[][CNT], int cnt) 2 { 3 int index, pos; 4 char str[CNT]; 5 for(pos = 1; pos < cnt; pos ++) 6 { 7 strcpy(str, name[pos]); 8 for(index = pos - 1; index >= 0; index --) 9 if(strcmp(name[index], str) > 0) 10 strcpy(name[index + 1], name[index]); 11 else 12 break; 13 strcpy(name[index + 1], str); 14 } 15 } |
最后,我們在編寫一個簡單的show()函數,來顯示各個文件的信息。
show函數實現如下:
1 void show(char name[][CNT], int cnt) 2 { 3 int index; 4 char mode[10]; 5 char *str; 6 struct stat buf; 7 for(index = 0; index < cnt; index ++) 8 { 9 memset(&buf, 0, sizeof(buf)); 10 if(stat(name[index], &buf) == -1) 11 { 12 printf("stat error!!\n"); 13 exit(1); 14 } 15 mode_to_char(buf.st_mode, mode); 16 str = ctime(&buf.st_atime); 17 str = time_change(str); 18 int i; 19 for(i = strlen(name[index]) - 1; name[index][i] != '/'; i --); 20 i++; 21 printf("%10s.%2d %5s %5s%5d%13s %s\n", mode, buf.st_nlink, getpwuid(buf.st_uid)->pw_name, getgrgid(buf.st_gid)->gr_name, buf.st_size, str, name[index] + i); 22 } 23 } |
這里需要注意:
getpwuid()返回的不是我們要的用戶名,我們需要的是該結構體中的一個變量——pw_name,同樣的getgrid()也應做相應的轉換。
測試代碼如下:
1 #include "head.h" 2 int main(int argc, char *argv[]) 3 { 4 DIR *fp; 5 char name[CNT][CNT]; 6 int cnt; 7 fp = opendir(argv[1]); 8 if(fp == NULL) 9 { 10 printf("opendir error!!\n"); 11 exit(1); 12 } 13 cnt = file_name(fp, argv[1], name); 14 str_sort(name, cnt); 15 show(name, cnt); 16 return 0; 17 } |
posted on 2014-10-14 09:47 順其自然EVO 閱讀(163) 評論(0) 編輯 收藏 所屬分類: 測試學習專欄