2012-10-27 15 views
9

Per i compiti devo scrivere un programma in C e una delle cose che deve fare è controllare se esiste un file e se è eseguibile dal proprietario.Uso di stat per verificare se un file è eseguibile in C

Utilizzo di (stat(path[j], &sb) >= 0 Sono in grado di vedere se il file indicato dal percorso [j] esiste.

Ho esaminato le pagine man, molte domande e risposte su StackOverflow e diversi siti Web, ma non sono in grado di comprendere esattamente come verificare se un file è eseguibile tramite stat. Ho pensato che sarebbe stato semplice come ((stat(path[j], &sb) >= 0) && (sb.st_mode > 0) && (S_IEXEC) ma, per quanto posso dire testandolo, sembra ignorare il fatto che questi file non sono eseguibili.

Penso che forse stat non funziona come credo. Supponendo che io uso stat, come posso risolvere il problema?

+2

'&& (S_IEXEC)' non dipende affatto da 'sb', cosa dovrebbe fare nel test? – Mat

+2

Ricerca dell'operatore AND bit a bit. Devi usarlo e S_IXUSR contro sb.st_mode – goji

+1

Divertente che se questa fosse una domanda Python, tutti avrebbero istantaneamente [gridato su quanto sia terribilmente pericoloso] (http://stackoverflow.com/questions/82831/how-do -i-check-if-a-file-exists-using-python) a causa di una possibile condizione di gara se prevedi di fare affidamento su quel risultato in seguito. Se lo fai (e ti piace tenerlo al sicuro), potresti voler ottenere un blocco sul file prima di chiamare 'stat'. – Kos

risposta

9

È possibile infatti utilizzare stat per fare questo. Devi solo usare S_IXUSR (S_IEXEC è un vecchio sinonimo di S_IXUSR) per verificare se hai il permesso di esecuzione. L'operatore bitmap AND (&) verifica se i bit di S_IXUSR sono impostati o meno.

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

Esempio:

#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; 
} 
+0

(sb.st_mode e S_IXUSR) solo per assicurarmi di averlo capito. Quindi S_IXUSR memorizza qualsiasi cifra di sb.st_mode indica che è eseguibile circondata da 0 e bit per bit e darà solo un 1 se quel bit particolare è impostato su 1? –

+0

Cosa intendi? – md5

+0

Per sbaglio ho premuto Invio prima di terminarlo, sistemandolo. –

4

Prova:

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

0

Siamo in grado di sfruttare la libreria libmagic.so che arriva con la (1) utilità di file. Può rilevare tutte eseguibili come script ELF, bash/Python/Perl ecc

Ecco il mio codice:

#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

Problemi correlati