系統呼叫實現Linux命令 ls -al
阿新 • • 發佈:2019-01-04
二話不說直接上程式碼(這是我之前在網易部落格上寫的搬過來)
ls.c 如下:
main.c如下:#include "ls.h" /**********************************************************************/ //將路徑定位到argv[1]目錄下 開啟該目錄 返回指標指向該檔案 //讀取檔案 每讀取一次檔案目錄下的指標方向後移 並返回檔案屬性結構體 //由於讀取檔案時的檔案屬性結構體不完整 //所以將檔案指標指向的檔名傳入stat函式得到該檔名的詳細屬性 //獲取時間時 注意範圍 具體規則將man手冊 man localtime //注意型別的對應關係 /**********************************************************************/ void ls_al(char path[]){ //將目錄切換到輸入的資料夾下argv[1] if(-1 == chdir(path)){ ERR_PRINT("<ls.h>In ls_al:chdir"); } /*開啟使用者輸入的資料夾argv[1]*/ //DIR *opendir(const char *name); //輸入資料夾路徑名 //返回一個指向該資料夾指標 DIR *dir = opendir(path);//DIR* 類似 FILE* /*讀取當前資料夾下的資訊*/ //struct dirent *readdir(DIR *dirp); //輸入一個資料夾指標 //返回一個該資料夾下的資訊結構體 struct dirent *dir_info = readdir(dir); // It returns NULL on reaching the end of the directory struct stat info_buf; //目錄下所有檔案詳細資訊結構體 char file_style = '-'; //檔案型別 char power[10] = "---------"; //各使用者對檔案許可權 int dev_main,dev_sub; //裝置驅動號 int file_size; //檔案大小 struct tm *time_struct; //時間結構體 localtime(info_buf.st_atime); while(NULL != dir_info){ // It returns NULL on reaching the end of the directory /*獲取某個檔案的詳細資訊存入結構體info_buf*/ //int stat(const char *path, struct stat *buf); //輸入目錄下的某個檔名 要存入的結構體 if(-1 == stat(dir_info->d_name,&info_buf)) ERR_PRINT("<ls.h>In ls_al:stat"); time_struct = localtime(&info_buf.st_atime);//根據最後一次訪問的時間(秒數)獲取本地世紀結構體 /*獲取檔案的型別*/ switch(info_buf.st_mode & S_IFMT){ case S_IFSOCK:file_style = 's';break; case S_IFLNK :file_style = 'l';break; case S_IFREG :file_style = '-';break; case S_IFBLK :file_style = 'b';break; case S_IFDIR :file_style = 'd';break; case S_IFCHR :file_style = 'c';break; case S_IFIFO :file_style = 'p';break; } /*獲取USR GRP OTH 的許可權*/ power[0] = ((info_buf.st_mode & S_IRWXU) & S_IRUSR) ? 'r' : '-'; power[1] = ((info_buf.st_mode & S_IRWXU) & S_IWUSR) ? 'w' : '-'; power[2] = ((info_buf.st_mode & S_IRWXU) & S_IXUSR) ? 'x' : '-'; power[3] = ((info_buf.st_mode & S_IRWXG) & S_IRGRP) ? 'r' : '-'; power[4] = ((info_buf.st_mode & S_IRWXG) & S_IWGRP) ? 'w' : '-'; power[5] = ((info_buf.st_mode & S_IRWXG) & S_IXGRP) ? 'x' : '-'; power[6] = ((info_buf.st_mode & S_IRWXO) & S_IROTH) ? 'r' : '-'; power[7] = ((info_buf.st_mode & S_IRWXO) & S_IWOTH) ? 'w' : '-'; power[8] = ((info_buf.st_mode & S_IRWXO) & S_IXOTH) ? 'x' : '-'; /*獲取目錄下某個檔案的UID GID*/ //struct passwd *getpwuid(uid_t uid); //struct group *getgrgid(gid_t gid); //輸入某個檔案的ID 由結構體info_buf.st_uid,info_buf.st_gid獲得 //返回一個結構體 裡面包含ID名 struct passwd *uid_struct = getpwuid(info_buf.st_uid); struct group *gid_struct = getgrgid(info_buf.st_gid); /*獲取非裝置驅動檔案大小 和 裝置驅動的主驅動號和副驅動號 dev_main & dev_sub*/ if('b' == file_style || 'c' == file_style){//(裝置檔案) dev_main = (info_buf.st_rdev>>8)&0XFF; dev_sub = (info_buf.st_rdev>>0)&0XFF; //列印某一個檔案的詳細資訊(裝置檔案) printf("%c%s %3d %8s %8s %3d,%3d %4d-%d-%d %2d:%2d:%2d %s \n" ,file_style //檔案型別 ,power //使用者對檔案的許可權 ,info_buf.st_nlink //檔案連結號 ,uid_struct->pw_name //UID name ,gid_struct->gr_name //GID name ,dev_main //主驅動號 ,dev_sub //副驅動號 ,time_struct->tm_year+1900//年月日時分秒 ,time_struct->tm_mon+1 ,time_struct->tm_mday ,time_struct->tm_hour ,time_struct->tm_min ,time_struct->tm_sec ,dir_info->d_name //檔名 ); } else{//(非裝置檔案) file_size = info_buf.st_size; //列印某一個檔案的詳細資訊(非裝置檔案) printf("%c%s %3d %8s %8s %7d %4d-%d-%d %2d:%2d:%2d %s \n" ,file_style //檔案型別 ,power //使用者對檔案的許可權 ,info_buf.st_nlink //檔案連結號 ,uid_struct->pw_name //UID name ,gid_struct->gr_name //GID name ,file_size //檔案大小 ,time_struct->tm_year+1900//年月日時分秒 ,time_struct->tm_mon+1 ,time_struct->tm_mday ,time_struct->tm_hour ,time_struct->tm_min ,time_struct->tm_sec ,dir_info->d_name //檔名 ); } //檔案指標下移一位 讀取下一個檔案(每讀取一次 dir指標下移一位 類似指標) dir_info = readdir(dir); } }
#include "alldef.h"#include "ls.h"
/*
* 功能:C語言實現 ls -al 命令
* 作者:KayChan
* 日期:2015-08-05
*/
int main(int argc,char *argv[]){
ls_al(argv[1]);
return 0;
}
執行: ./ls + pathname