【问题标题】:Incorrect st_mode Values - Cst_mode 值不正确 - C
【发布时间】:2013-01-15 02:57:54
【问题描述】:
  • 编译器:Code::Blocks(GNU GCC)
  • 平台:Windows(x86)

更新:我已经通过在调用 opendir() 之前使用 chdir() 更改当前工作目录解决了这个问题。所以我假设 opendir() 只能打开当前工作目录中的目录。所以我的新问题是,我正确吗?

我目前正在编写一个窗口的 dir 命令的基本模仿。当“。”时,我的程序可以正常工作。通配符用作 opendir() 的参数。但是当我不使用通配符并指定一个目录时。我的程序不会打开指定给它的目录。例如,如果我键入 c:\windows 它将打开 c:\ 而每个文件的 st_mode 将是相同的。至少我假设它们都是相同的,因为所有文件类型(DIR、FILE、OTHER)都是相同的。

#include <stdio.h>
#include <string.h>

#include <sys/stat.h>
#include <dirent.h>

int main(int argc, char* argv[])
{
//'directory' points to the directory | 'directory_contents' is used with readdir() to read the directory's('directory') contents.
DIR *directory;
struct dirent *directory_contents;
struct stat file_info;

//IF no argument is present display the contents of the current directory | IF there is an arugment display the contents of that argument | ELSE Too many arguments
if (argc == 1)
{
    directory = opendir(".");
}
else if (argc == 2)
{
    //New Code
    chdir(argv[1]); directory = opendir(".");

    //Old Code
    directory = opendir(argv[1]);
}
else
{
    printf("ERROR: Extra arguments\n");
}

//Checks to see if the directory opened above was actually opened.
if (directory == NULL)
{
    printf("ERROR: Failed to open '%s'.\n", argv[1]);
    return 2;
}
else
{
    //WHILE there are file names to be read THEN read the file names
    while (directory_contents = readdir(directory))
    {
        stat(directory_contents->d_name, &file_info);

        //Test for directory
        if(S_ISDIR(file_info.st_mode))
        {
            //File type
            printf("<DIR>   ");

            //File name
            if(strlen(directory_contents->d_name) <= 15)
            {
                printf("%-15s", directory_contents->d_name);
            }
            else if(strlen(directory_contents->d_name) > 15)
            {
                printf("%.12s.. ", directory_contents->d_name);
            }

            //File premissions
            printf("<%c%c%c>\n", ((file_info.st_mode & S_IRUSR)==0) ? '-' : 'r', ((file_info.st_mode & S_IWUSR)==0) ? '-' : 'w', ((file_info.st_mode & S_IXUSR)==0) ? '-' : 'x');
        }
        //Test for a regular file.
        else if(S_ISREG(file_info.st_mode))
        {
            //File type
            printf("<FILE>  ");

            //File name
            if(strlen(directory_contents->d_name) <= 15)
            {
                printf("%-15s", directory_contents->d_name);
            }
            else if(strlen(directory_contents->d_name) > 15)
            {
                printf("%.12s.. ", directory_contents->d_name);
            }

            //File premissions
            printf("<%c%c%c> ", ((file_info.st_mode & S_IRUSR)==0) ? '-' : 'r', ((file_info.st_mode & S_IWUSR)==0) ? '-' : 'w', ((file_info.st_mode & S_IXUSR)==0) ? '-' : 'x');

            //File size
            if (file_info.st_size < 1000)
            {
                printf("<%-3i B>\n", file_info.st_size);
            }
            else if ( (file_info.st_size > 1000) && (file_info.st_size < 1000000) )
            {
                printf("<%-3i KB>\n", file_info.st_size/1000);
            }
            else if ( (file_info.st_size > 1000000) && (file_info.st_size < 1000000000) )
            {
                printf("<%-3i MB>\n", file_info.st_size/1000000);
            }
            else
            {
                printf("<%-3i GB>\n", file_info.st_size/1000000000);
            }
        }
        //Symbolic Link etc.
        else
        {
            //File type
            printf("<OTHER> ");

            //File name
            if(strlen(directory_contents->d_name) <= 15)
            {
                printf("%-15s", directory_contents->d_name);
            }
            else if(strlen(directory_contents->d_name) > 15)
            {
                printf("%.12s.. ", directory_contents->d_name);
            }

            //File premissions
            printf("<%c%c%c>\n", ((file_info.st_mode & S_IRUSR)==0) ? '-' : 'r', ((file_info.st_mode & S_IWUSR)==0) ? '-' : 'w', ((file_info.st_mode & S_IXUSR)==0) ? '-' : 'x');
        }
    }
}
}

是的,我知道我输出的权限完全不相关,因为 Window 使用了 ACL。我只在 Windows 上编写这个程序,因为我现在别无选择,但它是为 Linux 操作系统设计的。

【问题讨论】:

  • 我不确定它是否仍然相关,但我有一个头文件 'sysstat.h' 是为了处理 Windows 上的 'stat()' 而编写的。基本上,当我写它的时候(c 1995),情况很可悲,甚至一些 Unix 系统也不支持 POSIX。从那时起,情况总体上有所改善,尤其是在 Unix 系统上。我现在不太确定Windows。这可能取决于您与 Code::Blocks 一起使用的编译器。 (这些天我通常不使用它,但我的一些旧代码仍然可以使用,以防万一——更多的是“只是因为”,意思是“只是因为我还没有修复它”。)
  • 尝试使用转义字符,例如 c:\\windwos
  • 当您在 windows 上工作并面临 windows 上的问题时,您应该标记这个问题windows,而不是POSIX。如果在 POSIX 系统上,请标记它POSIX
  • @alk 上面使用的几乎所有函数都是在 POSIX 下声明的,它们是不支持的 Windows 函数。碰巧我暂时在 Windows 上编写这个程序。现在它本身可能是个问题,但我想知道这是否是我正在做的其他事情。

标签: c posix


【解决方案1】:

stat(directory_contents-&gt;d_name,

这一行是问题所在。 d_name 字段只是文件的名称,没有任何目录。所以除非目录恰好是当前目录,否则对stat() 的调用将找不到该文件。

【讨论】:

  • 感谢您的回复。这就解释了为什么我的程序在我 chdir() 到它正在读取的目录时工作。
猜你喜欢
  • 2020-07-15
  • 1970-01-01
  • 1970-01-01
  • 2013-01-12
  • 2020-04-17
  • 2018-03-19
  • 1970-01-01
  • 1970-01-01
  • 2016-05-24
相关资源
最近更新 更多