2010-02-11 2 views
41

Sto cercando di leggere del testo da un file e scriverlo su un altro utilizzando open(), read() e write().Perché open() crea il mio file con le autorizzazioni sbagliate?

Questo è il mio open() per il file-to-write-a (voglio creare un nuovo file e scrivere in esso):

fOut = open ("test-1", O_RDWR | O_CREAT | O_SYNC); 

Questa è la creazione di file-autorizzazioni per qualcosa che non so capire a tutti. Questa è l'uscita di ls -l:

---------T 1 chaitanya chaitanya 0 2010-02-11 09:38 test-1 

Anche l'autorizzazione di lettura è bloccata. Ho provato a cercare questo, ma non ho trovato nulla. Stranamente, write() scrive ancora correttamente i dati nel file.

Inoltre, se eseguo un 'chmod 777 test-1', le cose riprendono a funzionare correttamente.

Qualcuno potrebbe farmi sapere dove sto andando male nella mia chiamata aperta?

Grazie!

Per il vostro riferimento, ho incollato il programma completo qui sotto:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <fcntl.h> 

int main() { 

    char buffer[512], ch; 

    int fIn, fOut, i; 
    ssize_t bytes; 
    FILE *fp = NULL; 

    //open a file 
    fIn = open ("test", O_RDONLY); 
    if (fIn == -1) { 
     printf("\nfailed to open file."); 
     return 1; 
    } 

    //read from file 
    bytes = read (fIn, buffer, sizeof(buffer)); 
    //and close it 
    close (fIn); 

    printf("\nSuccessfully read %d bytes.\n", bytes); 

    //Create a new file 
    fOut = open ("test-1", O_RDWR | O_CREAT | O_SYNC); 

    printf("\nThese are the permissions for test-1\n"); 
    fflush(stdout); 
    system("ls -l test-1"); 

    //write to it and close it. 
    write (fOut, buffer, bytes); 
    close (fOut); 


    //write is somehow locking even the read permission to the file. Change it. 
    system("chmod 777 test-1"); 

    fp = fopen ("test-1", "r"); 
    if (fp == NULL) { 
     printf("\nCan't open test-1"); 
     return 1; 
    } 

    while (1) 
    { 
     ch = fgetc(fp); 
     if (ch == EOF) 
      break; 
     printf("\n%c", ch); 
    } 

    fclose (fp); 

    return 0; 
} 
+0

Probabilmente non è necessario il permesso 777; probabilmente hai solo bisogno di 666 al massimo, e di solito non vuoi neanche un permesso di scrittura pubblico. Non vuoi che le persone eseguano i tuoi file di dati. –

risposta

68

open() prende un terzo argomento, che è l'insieme di permessi, cioè

open(filename, O_RDWR|O_CREAT, 0666) 

0666 è un numero ottale , cioè ognuno dei 6 del corrisponde a tre permessi i bit

6 = rw

7 = rwx

È una trappola tipica. Il compilatore ti permette di allontanare l'argomento dei permessi, perché quando apri un file esistente i bit di autorizzazione non hanno senso. Ma quando dimentichi l'argomento quando crei un file, ottieni un insieme casuale di permessi, ad es. 0000 nel tuo caso (---).

+2

Per completezza, ottale 4 = r –

+0

E per quanto riguarda il 4 esadecimale? –

+1

@Adam Liss: hex 4 = ottale 4. Ottale è conveniente per le autorizzazioni poiché ogni gruppo di 3 bit costituisce un'unità di permessi e una cifra ottale. 0644 = 0x1A4, ma è molto più facile vedere le autorizzazioni nella notazione ottale che in esadecimale. (Esperienza parziale, ma principalmente il raggruppamento appropriato di bit). –

9

lettura http://linux.die.net/man/2/open sembra vi siete persi il parametro mode per l'open:

modalità

deve essere specificato quando O_CREAT è nelle bandiere, e viene ignorato in caso contrario. La modalità argomento specifica le autorizzazioni da utilizzare in caso di creazione di un nuovo file.

+0

oh. molte grazie! – Chaitanya

7

Questa domanda mi ha recentemente aiutato, quindi ho voluto fare la mia parte per aggiungere un po 'più di profondità a ciò che sta succedendo. Come è stato affermato in precedenza, mancava il terzo argomento a open(). Tuttavia, le autorizzazioni che vedi non sono casuali; vengono dallo stack. Guardate il seguente frammento di codice:

asm("push $0"); 
    asm("push $0"); 
    asm("push $0"); 
    fd = open("base", O_RDWR|O_CREAT); 

Nota il seguente risultato:

----------. 1 user user 4 Feb 26 08:21 base 

Cambiamo la prima spinta a 1, vale a direpermesso di esecuzione:

asm("push $1;push $0;push $0"); 
    fd = open("base", O_RDWR|O_CREAT); 

e otteniamo:

---------x. 1 user user 4 Feb 26 08:25 base 

Cambiare la spinta a 4, ovvero permesso di lettura, e la mensa con gli altri due valori:

asm("push $4;push $5;push $6"); 
    fd = open("base", O_RDWR|O_CREAT); 

e otteniamo:

-------r--. 1 user user 4 Feb 26 08:27 base 

Così abbiamo c un vedere il terzo valore spuntato dallo stack (prima spinto) è ciò che conta davvero. Finalmente per divertimento possiamo provare 5 e poi 50, che risultano rispettivamente in:

-------r-x. 1 user user 4 Feb 26 08:27 base 
    ----rw----. 1 user user 4 Feb 26 08:28 base 

Spero che questo aggiunga un po 'di chiarezza!

0

è possibile chiamare la chiamata di sistema umask(0); prima di utilizzare la chiamata di sistema open(); per impostare le autorizzazioni delle scelte per file correttamente.

1

In realtà umask() filtra solo le autorizzazioni e non le imposta. Il valore tipico di umask() è 0002 ("non dare il permesso di scrittura al mondo") e se il valore della modalità in open("file", O_CREAT, 0777) ha dato tutte le autorizzazioni, il file risultante avrebbe 775 come le sue permsions.

1

Non strettamente rilevanti per la domanda, ma la risposta accettata potrebbe usare questo punto chiarificatrice:

Esiste una relazione tra rwx e della sua rappresentazione numerica che può essere visto trattando la presenza di una lettera come un binario 1 e la sua assenza come binario 0.

es.

rwx <--> 111 (binary) <--> 7 (octal) 

r-- <--> 100 (binary) <--> 4 (octal) 

-wx <--> 011 (binary) <--> 3 (octal) 

Come ulteriore addendum, si può ora considerare il comando chmod:

chmod 777 nomefile.estensione -> rwxrwxrwx permessi

777 <--> 111 111 111 <--> rwx rwx rwx 

o: chmod 654 nomefile.estensione - > rw-rxr--

654 <--> 110 101 100 <--> rw- r-x r-- 

Spero che questo è informativo!

0

Questa è una specie di thread vecchio, ma penso che le persone dovrebbero essere consapevoli della libreria "sys/stat.h". Ciò include un gruppo di costanti simboliche per l'impostazione di bit di autorizzazione.

Per esempio: Per aprire un file con permessi di lettura/scrittura abilitato per l'utente

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

open("Your/File/Path", O_RDWR | O_CREAT, S_IWUSR | S_IRUSR); 

dove:

S_IWUSR // Sets the Users Write bit 
S_IRUSR // Sets the Users Read bit 

Questa libreria include un mucchio di altri, non voglio elencarli tutto qui ma puoi leggere tutto su here.

Ovviamente è possibile inserire i valori ottali per impostare questi bit, tuttavia alcuni potrebbero obiettare che si tratta di una cattiva pratica di codifica.