天天看點

[Linux高并發伺服器]模拟實作 ls -l 指令

[Linux高并發伺服器]模拟實作ls -l指令

參考:​​牛客LINUX高并發伺服器教程​​

利用state函數模拟實作ls -l指令

[Linux高并發伺服器]模拟實作 ls -l 指令

使用​

​ls -l​

​指令傳回了以下資訊

  • 檔案類型
  • 檔案權限
  • 連接配接數
  • 檔案所屬使用者
  • 檔案所屬組
  • 檔案大小
  • 檔案上次修改時間
  • 檔案名

我們通過stat函數擷取stat結構體資訊

[Linux高并發伺服器]模拟實作 ls -l 指令

主要講講比較難實作的幾個子產品

檔案類型 & 檔案權限

根據​

​st_mode​

​判斷檔案類型和權限

[Linux高并發伺服器]模拟實作 ls -l 指令

檔案類型:​

​st_mode & S_IFMT​

​後與各個宏比較

檔案權限:​

​st_mode & S_IRUSR​

​(以user讀權限為例),直接看和宏按位與後的真假,若為真就有權限,假則無權限

//擷取檔案類型和檔案權限
    char perms[11]={0}; //用于儲存檔案類型和檔案權限的字元串

    switch (st.st_mode & S_IFMT){
        case S_IFLNK:
            perms[0]='l';
            break;
        case S_IFDIR:
            perms[0]='d';
            break;
        case S_IFREG:
            perms[0]='-';
            break;
        case S_IFBLK:
            perms[0]='b';
            break;
        case S_IFCHR:
            perms[0]='c';
            break;
        case S_IFSOCK:
            perms[0]='s';
            break;
        case S_IFIFO:
            perms[0]='p';
            break;
        default:
            perms[0]='?';
            break;
    }
    
    //判斷檔案的通路權限
    //檔案所有者權限
    perms[1]=(st.st_mode & S_IRUSR) ? 'r':'-';
    perms[2]=(st.st_mode & S_IWUSR) ? 'w':'-';
    perms[3]=(st.st_mode & S_IXUSR) ? 'x':'-';
    //檔案組
    perms[4]=(st.st_mode & S_IRGRP) ? 'r':'-';
    perms[5]=(st.st_mode & S_IWGRP) ? 'w':'-';
    perms[6]=(st.st_mode & S_IXGRP) ? 'x':'-';
    //其他組
    perms[7]=(st.st_mode & S_IROTH) ? 'r':'-';
    perms[8]=(st.st_mode & S_IWOTH) ? 'w':'-';
    perms[9]=(st.st_mode & S_IXOTH) ? 'x':'-';      

檔案擁有者 & 所屬使用者組

​st_uid​

​​擷取使用者ID

​​

​st_gid​

​​擷取組ID

但是實際上的​​

​ls -l​

​​指令顯示的使用者名群組名,是以我們要使用​

​getpwuid​

​​和​

​getgrgid​

​​兩個函數把ID轉換為名字

可以使用man手冊來查詢這兩個函數的用法和所需的頭檔案

//檔案所有者
    char * fileUser = getpwuid(st.st_uid)->pw_name;
    //檔案所在組
    char * fileGrp = getgrgid(st.st_gid)->gr_name;      

檔案上次修改時間

//擷取修改時間
    char * time = ctime(&st.st_mtime);

    char mtime[512]={0};
    strncpy(mtime,time,strlen(time)-1);//去除末尾換行      

成品代碼

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <string.h>

int main(int argc,char * argv[]){
    //判斷輸入參數是否正确
    if(argc<2){
        printf("%s filename\n",argv[0]);
        return -1;
    }
    //通過stat函數
    struct stat st;
    int ret=stat(argv[1],&st);
    if(ret==-1){
        perror("stat");
        return -1;
    }
    //擷取檔案類型和檔案權限
    char perms[11]={0}; //用于儲存檔案類型和檔案權限的字元串

    switch (st.st_mode & S_IFMT){
        case S_IFLNK:
            perms[0]='l';
            break;
        case S_IFDIR:
            perms[0]='d';
            break;
        case S_IFREG:
            perms[0]='-';
            break;
        case S_IFBLK:
            perms[0]='b';
            break;
        case S_IFCHR:
            perms[0]='c';
            break;
        case S_IFSOCK:
            perms[0]='s';
            break;
        case S_IFIFO:
            perms[0]='p';
            break;
        default:
            perms[0]='?';
            break;
    }
    
    //判斷檔案的通路權限
    //檔案所有者權限
    perms[1]=(st.st_mode & S_IRUSR) ? 'r':'-';
    perms[2]=(st.st_mode & S_IWUSR) ? 'w':'-';
    perms[3]=(st.st_mode & S_IXUSR) ? 'x':'-';
    //檔案組
    perms[4]=(st.st_mode & S_IRGRP) ? 'r':'-';
    perms[5]=(st.st_mode & S_IWGRP) ? 'w':'-';
    perms[6]=(st.st_mode & S_IXGRP) ? 'x':'-';
    //其他組
    perms[7]=(st.st_mode & S_IROTH) ? 'r':'-';
    perms[8]=(st.st_mode & S_IWOTH) ? 'w':'-';
    perms[9]=(st.st_mode & S_IXOTH) ? 'x':'-';

    //硬連結數
    int linkNum=st.st_nlink;

    //檔案所有者
    char * fileUser = getpwuid(st.st_uid)->pw_name;
    //檔案所在組
    char * fileGrp = getgrgid(st.st_gid)->gr_name;
    //檔案大小
    long int fileSize = st.st_size;
    //擷取修改時間
    char * time = ctime(&st.st_mtime);

    char mtime[512]={0};
    strncpy(mtime,time,strlen(time)-1);//去除末尾回車

    char buf[1024];
    sprintf(buf,"%s %d %s %s %ld %s %s",perms,linkNum,fileUser,fileGrp,fileSize,mtime,argv[1]);
    printf("%s\n",buf);
    return 0;
}      

運作效果