簡體   English   中英

C sys / stat.h並非初始化stat結構的每個字段

[英]C sys/stat.h not every field of stat structure is initialised

我最近一直在嘗試實現自己的linux ls命令版本。 一切都很好,但是當我嘗試使用ls -l功能時,並未初始化struct stat的某些字段-我得到NULL指針或垃圾值,盡管似乎僅在某些文件和目錄中才會發生,就像/的內容一樣以及其他屬於根或根組的對象。 我發現奇怪的事實是文件的寫入權限總是成功的。 這是故障功能的代碼:

void printFullList(struct dirent* pDirEnt) {
    struct stat fileStat;
    stat(pDirEnt->d_name, &fileStat);
    if(pDirEnt->d_type & DT_DIR)
        putchar('d');
    else 
        putchar('-');

    putchar((fileStat.st_mode & S_IRUSR) ? 'r' : '-');
    putchar((fileStat.st_mode & S_IWUSR) ? 'w' : '-');
    putchar((fileStat.st_mode & S_IXUSR) ? 'x' : '-');
    putchar((fileStat.st_mode & S_IRGRP) ? 'r' : '-');
    putchar((fileStat.st_mode & S_IWGRP) ? 'w' : '-');
    putchar((fileStat.st_mode & S_IXGRP) ? 'x' : '-');
    putchar((fileStat.st_mode & S_IROTH) ? 'r' : '-');
    putchar((fileStat.st_mode & S_IWOTH) ? 'w' : '-');
    putchar((fileStat.st_mode & S_IXOTH) ? 'x' : '-');

    struct passwd *pwd;
    pwd = getpwuid(fileStat.st_uid);
    struct group *gid = NULL; 
    gid = getgrgid(fileStat.st_gid);
    char date[15];
    strftime(date, 15, "%d-%m %H:%M", localtime(&(fileStat.st_ctime)));
    printf(" %d %s %s %5d %s %s\n", (int)fileStat.st_nlink, (pwd != NULL ? pwd->pw_name : "NO_PERM"), (gid != NULL ? gid->gr_name : "NO_PERM"), (int)fileStat.st_size, date, pDirEnt->d_name);
}

感謝幫助!

編輯:

stat()返回-1。 我在每次函數調用之前將errno設置為0。 我還按照@chux的建議每次都打印pDirEnt-> d_name。 這是/的輸出:

mnt No such file or directory d---rw---- 16961624 root NO_PERM 1 27-03 08:13 mnt
usr No such file or directory d--x--x--- 16961648 root NO_PERM 1 27-03 08:13 usr 
root No such file or directory d--xr----- 16961672 root NO_PERM 1 27-03 08:13 root  
lost+found No such file or directory d-w------- 16961696 root NO_PERM 1 27-03 08:13 lost+found ...

stat()返回-1

當系統調用返回錯誤指示時,您期望的任何數據(例如fileStat )都可以產生一些有效數據或純垃圾。

將程序的輸出與ls -l ,您會發現權限和文件大小都是廢話。

我找到了答案。 僅將指針傳遞給struct dirent是問題:d_name字段存儲文件名,而stat()函數則需要文件路徑。 現在,我將文件的目錄和dirent結構及其數據傳遞給它,然后將它們合並到以下路徑中:

int pathLength;
char path[PATH_MAX];
pathLength = snprintf(path, PATH_MAX, "%s/%s", directory, pDirEnt->d_name);
if(pathLength >= PATH_MAX)
{
    fprintf(stderr, "Path was too long!");
    exit(EXIT_FAILURE);
}

然后我做:

stat(path, &fileStat);

解決了我的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM