【问题标题】:Using stat to check if a file is executable in C使用 stat 检查文件是否在 C 中可执行
【发布时间】:2012-10-17 09:49:30
【问题描述】:

对于家庭作业,我必须编写一个 C 程序,它必须做的一件事是检查文件是否存在以及它是否可由所有者执行。

使用(stat(path[j], &sb) >= 0可以查看path[j]指示的文件是否存在。

我已经浏览了手册页、stackoverflow 上的许多问题和答案以及几个网站,但我无法确切了解如何使用 stat 检查文件是否可执行。 我认为它会像((stat(path[j], &sb) >= 0) && (sb.st_mode > 0) && (S_IEXEC) 一样简单,但据我测试它可以看出,它似乎忽略了这些文件不可执行的事实。

我认为也许 stat 不像我认为的那样工作。假设我使用 stat,我该如何解决这个问题?

【问题讨论】:

  • && (S_IEXEC) 根本不依赖于sb,那在你的测试中应该做什么?
  • 查找按位与运算符。您需要针对 sb.st_mode 使用它和 S_IXUSR
  • 有趣的是,如果这是一个 Python 问题,如果您打算稍后依赖该结果,每个人都会立即shout out about how terribly dangerous this is,因为可能存在竞争条件。如果您这样做(并且喜欢保持安全),您可能希望在调用 stat 之前获得对文件的锁定。
  • @Mat Ahhhhh 这是我昨晚不太明白的。我最初尝试使用 sb.S_IEXEC,但它给了我一个错误。我没有意识到这是我应该比较的。

标签: c stat


【解决方案1】:

试试:

((stat(path[j], &sb) >= 0) && (sb.st_mode > 0) && (S_IEXEC & sb.st_mode)

【讨论】:

    【解决方案2】:

    您确实可以使用stat 来执行此操作。你只需要使用S_IXUSRS_IEXECS_IXUSR 的旧同义词)来检查你是否有执行权限。按位AND 运算符(&)检查S_IXUSR 的位是否设置。

    if (stat(file, &sb) == 0 && sb.st_mode & S_IXUSR) 
        /* executable */
    else  
        /* non-executable */
    

    例子:

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    
    int main(int argc, char **argv)
    {
        if (argc > 1) {
            struct stat sb;
            printf("%s is%s executable.\n", argv[1], stat(argv[1], &sb) == 0 &&
                                                     sb.st_mode & S_IXUSR ? 
                                                     "" : " not");
        }
        return 0;
    }   
    

    【讨论】:

    • (sb.st_mode & S_IXUSR) 只是确保我明白了。所以 S_IXUSR 存储 sb.st_mode 的任何数字表示它是由 0 和按位包围的可执行文件,并且如果该特定位设置为 1,则只会给出 1?
    • 你是对的。 :) 请注意,S_IXUSR几个 位可能设置为 1。
    • 这是否也检查文件是否不是目录?没关系,阅读文档我发现了 S_ISDIR 宏。
    • 如果我错了,请纠正我,但这只是检查文件是否可由文件所有者执行,对吗?如果运行“此程序”的用户不是文件的所有者,则检查可能会错误地指示它是可执行的。在这种情况下,程序还应检查 S_IXGRP(如果调用用户组与程序组相同)和 S_IXOTH(否则)。
    【解决方案3】:

    我们可以利用 file(1) 实用程序附带的 libmagic.so 库。 它可以检测所有可执行文件,如 ELF、bash/python/perl 脚本等

    这是我的代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "magic.h"
    
    int
    main(int argc, char **argv)
    {
       struct magic_set *ms;
       const char *result;
       char *desired;
       size_t desired_len;
       int i;
       FILE *fp;
    
       ms = magic_open(MAGIC_RAW);
       if (ms == NULL) {
          (void)fprintf(stderr, "ERROR opening MAGIC_NONE: out of memory\n");
          return -1;
       }
       if (magic_load(ms, NULL) == -1) {
          (void)fprintf(stderr, "ERROR loading with NULL file: %s\n", magic_error(ms));
          return 11;
       }
    
       if (argc > 1) {
          if (argc != 2) {
             (void)fprintf(stderr, "Usage:  ./a.out </path/to/file>\n");
          } else {
             if ((result = magic_file(ms, argv[1])) == NULL) {
                (void)fprintf(stderr, "ERROR loading file %s: %s\n", argv[1], magic_error(ms));
                return -1;
             } else {
                 if (strstr(result, (const char *)"executable")) {
                    printf("%s: is executable\n", argv[1], result);
                 }
             }
          }
       }
       magic_close(ms);
       return 0;
    }
    

    $ gcc test.c -I/path/to/magic.h /usr/lib/libmagic.so.1

    ./a.out /bin/ls

    ./a.out a.out

    ./a.out test.c

    【讨论】:

      猜你喜欢
      • 2016-07-11
      • 2013-04-08
      • 1970-01-01
      • 2015-07-21
      • 2023-03-25
      • 1970-01-01
      • 2013-04-21
      相关资源
      最近更新 更多