测试目录起诉S_ISDIR,但它不起作用

时间:2013-02-01 09:19:57

标签: linux macros posix dir

我正在学习linux中的c编程,我写这个来输出有关文件和目录的信息,比如标准工具“ls”和“-l”,一切正常,除了宏S_ISDIR,这是我的代码。 另外,我的操作系统是薄荷14 x86_64。

#include<sys/types.h>
#include<time.h>
#include<string.h>
#include<dirent.h>
#include<stdio.h>
#include<sys/stat.h>
#include<unistd.h>
void do_ls(char []);
void show_file_info(struct stat *t){
    printf("mode:    %o\n",t->st_mode);
    if(S_ISDIR(t->st_mode)==0)
        printf("Is a dir\n");
    else
        printf("Is not a dir\n");
    printf("links:   %d\n",t->st_nlink);
    printf("group:   %d\n",t->st_gid);
    printf("user:    %d\n",t->st_uid);
    printf("size:    %d\n",t->st_size);
    printf("modtime: %s\n",ctime(&t->st_mtime));
}
int main(int num,char *a[]){
    if(num==1){
        do_ls(".");
    }
    else{
        while(--num){
            printf("%s :\n",*++a);
            do_ls(*a);
        }
    }
}
void do_ls(char dirname[]){
    DIR *tem=opendir(dirname);
    struct dirent *direntp;
    struct stat *buf;
    char t[256];
    if(tem==NULL){
        fprintf(stderr,"ls: cannot open %s\n",dirname);
    }
    else{
        while((direntp=readdir(tem))!=NULL){
            strcpy(t,dirname);
            printf("%s\n",direntp->d_name);
            strcat(t,"/");
            if(stat(t,buf)==-1){
                perror("");
                break;
            }
            else{
                show_file_info(buf);
            }
        }
        closedir(tem);
    }
}

3 个答案:

答案 0 :(得分:0)

系统调用

int stat(const char *path, struct stat *buf);

不为*buf分配内存。

要么留下你的声明

struct stat *buf;

并用

手动分配内存
buf = (struct stat *) malloc(sizeof(struct stat));

并在不再需要free的地方使用buf释放记忆

或您将声明更改为

struct stat buf;

让c为你分配内存。

您应该根据手册中的建议测试stat if(stat(t,&buf) < 0)的失败情况。

另一个错误是,您没有将文件名传递给stat,而是传递目录名。

我附上了代码的更正版本。


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

void do_ls(char []);

void show_file_info(struct stat *t){
    printf("mode:    %o\n",t->st_mode);
    if((t->st_mode & S_IFMT) == S_IFDIR)
        printf("Is a dir\n");
    else
        printf("Is not a dir\n");
    printf("links:   %d\n",t->st_nlink);
    printf("group:   %d\n",t->st_gid);
    printf("user:    %d\n",t->st_uid);
    printf("size:    %d\n",t->st_size);
    printf("modtime: %s\n",ctime(&t->st_mtime));
}

int main(int num,char *a[]){
    if(num==1){
        do_ls(".");
    }
    else{
        while(--num){
            printf("%s :\n",*++a);
            do_ls(*a);
        }
    }
}

void do_ls(char dirname[]){
    DIR *tem=opendir(dirname);
    struct dirent *direntp;
    struct stat buf;
    char t[256];

    if(tem==NULL){
        fprintf(stderr,"ls: cannot open %s\n",dirname);
    }
    else{
        while((direntp=readdir(tem))!=NULL){
            strcpy(t,dirname);
            printf("%s\n",direntp->d_name);
            strcat(t,"/");
            strcat(t,direntp->d_name);
            if(stat(t,&buf) < 0){
                perror("");
                break;
            }
            else{
                show_file_info(&buf);
            }
        }
        closedir(tem);
    }

}

答案 1 :(得分:0)

user1198331关于stat的更正是正确的。通常检查所有系统调用返回值是一种好习惯,以防止出错。

尽管如此,在原始代码中,我认为这部分是错误的:

if(S_ISDIR(t->st_mode)==0)
    printf("Is a dir\n");
else
    printf("Is not a dir\n");

您认为如果S_ISDIR(t-> st_mode)返回0,则它是一个目录,但实际上,如果t指向的文件不是 st_mode)返回0 strong>一个目录。因此,您必须进行反向检查。

答案 2 :(得分:0)

尝试从https://discuss.pytorch.org/t/pytorch-no-longer-supports-this-gpu-because-it-is-too-old/13803开始关注。

#ifndef S_ISDIR
#define S_ISDIR(mode)  (((mode) & S_IFMT) == S_IFDIR)
#endif