Использование stat для проверки исполняемого файла в C

для домашней работы я должен написать программу на C, и одна из вещей, которую она должна сделать, - это проверить, существует ли файл и исполняется ли он владельцем.

используя (stat(path[j], &sb) >= 0 Я могу видеть, существует ли файл, указанный путем[j].

Я просмотрел man-страницы, много вопросов и ответов на stackoverflow и несколько веб-сайтов, но я не могу точно понять, как проверить, является ли файл исполняемым с помощью stat. Я думал, это будет так же просто, как ((stat(path[j], &sb) >= 0) && (sb.st_mode > 0) && (S_IEXEC) но, насколько я могу судить, тестируя его, он, похоже, игнорирует тот факт, что эти файлы не являются исполняемыми.

Я думаю, что, возможно, stat не работает так, как я думаю. Предполагая, что я использую stat, как я могу это исправить?

3 ответов


вы действительно можете использовать stat для этого. Вы просто должны использовать S_IXUSR (S_IEXEC Это старый синоним S_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;
}   

попробуй:

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


мы можем использовать libmagic.Итак, библиотека, которая поставляется вместе с утилитой file(1). Он может обнаруживать все исполняемые файлы, такие как скрипты 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;
}

тест$ ССЗ.c-I / путь / к / магии.h / usr/lib / libmagic.Итак.1

./а.вне /ОГРН/ЛС

./а.оттуда.из

.a.вне теста.c