2010-02-11 30 views
41

Estoy tratando de leer un texto de un archivo y escribirlo en otro usando open(), read() y write().¿Por qué open() crea mi archivo con los permisos incorrectos?

Ésta es mi open() para el archivo-a-escritura-a (Quiero crear un nuevo archivo y escribir en él):

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

Esta es la creación de archivos en permisos a algo que yo no entender en absoluto. Esta es la salida de ls -l:

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

Incluso el permiso de lectura está bloqueado. Intenté buscar esto, pero no pude encontrar NADA. Extrañamente, write() aún escribe con éxito datos en el archivo.

Además, si hago un 'chmod 777 test-1', las cosas vuelven a funcionar correctamente.

¿Podría alguien decirme por favor dónde me estoy equivocando en mi llamada abierta?

Gracias!

Para su referencia, He pegado el programa completo a continuación:

#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

Probablemente no necesite el permiso 777; probablemente solo necesite 666 a lo sumo, y generalmente tampoco desea permiso de escritura pública. No quiere que las personas ejecuten sus archivos de datos. –

Respuesta

68

abierto() realiza un tercer argumento que es el conjunto de permisos, es decir

open(filename, O_RDWR|O_CREAT, 0666) 

0666 es un número octal , es decir, cada uno de los 6 corresponde a tres permiso los bits

6 = rw

7 = rwx

Es una trampa típica. El compilador le permite abandonar el argumento de permiso, porque cuando abre un archivo existente, los bits de permiso no tienen sentido. Pero cuando olvida el argumento cuando crea un archivo, obtiene un conjunto aleatorio de permisos, p. 0000 en tu caso (---).

+2

Para completar, octal 4 = r –

+0

¿Qué ocurre con el hexadecimal 4? –

+1

@ Adam Liss: hex 4 = octal 4. Octal es conveniente para los permisos porque cada grupo de 3 bits constituye una unidad de permisos y un dígito octal. 0644 = 0x1A4, pero es mucho más fácil ver los permisos en la notación octal que en hexadecimal. (Experiencia parcial, pero principalmente la agrupación de bits apropiada). –

9

lectura http://linux.die.net/man/2/open parece se ha perdido el parámetro de mode abierta:

modo

debe especificarse cuando se O_CREAT está en las banderas, y se ignora lo contrario. El modo argumento especifica los permisos para usar en caso de que se cree un nuevo archivo.

+0

oh. ¡muchas gracias! – Chaitanya

7

Esta pregunta me ayudó a cabo recientemente, por lo que quería hacer mi parte para añadir un poco más a fondo en cuanto a lo que está pasando. Como se dijo antes, le faltaba el tercer argumento al open(). Sin embargo, los permisos que ves no son aleatorios; vienen de la pila. Mira el siguiente fragmento de código:

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

Nota el siguiente resultado:

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

Vamos a cambiar el primer empujón a 1, es decir,permiso de ejecución:

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

y obtenemos:

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

Cambiar el empuje a 4, es decir, el permiso de lectura, y meterse con los otros dos valores:

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

y obtenemos:

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

Así que c un ver que el tercer valor salido de la pila (primero empujado) es lo que realmente importa. Finalmente para la diversión podemos tratar 5 y 50, que se traducen, respectivamente, en:

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

Hope esto añade un poco de claridad!

0

puede llamar al sistema umask(0); antes de usar la llamada al sistema open(); para configurar correctamente sus opciones de archivo.

1

En realidad umask() únicamente filtros de permisos y no se los puso. El valor típico es umask()0002 ("no dar permiso de escritura en el mundo") y si su valor de modo en el open("file", O_CREAT, 0777) dio todos los permisos, el archivo resultante tendría 775 como sus permssions.

1

No es estrictamente relevante a la pregunta, pero la respuesta aceptada podría utilizar este punto de clarificación:

Hay una relación entre rwx y su representación numérica que puede ser visto por el tratamiento de la presencia de una carta como un 1 binario , y su ausencia como un binario 0.

por ejemplo,

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

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

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

Como nueva adición, ahora puede considerar el comando chmod:

chmod 777 filename.extension -> rwxrwxrwx permisos

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

o: chmod 654 filename.extension - > rw-rxr--

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

Espero que te dé información!

0

esto es una especie de un viejo hilo, pero creo que la gente debe ser consciente de la "/ sys stat.h" biblioteca. Esto incluye un conjunto de constantes simbólicas para establecer bits de permiso.

Por ejemplo: Para abrir un archivo con permisos de lectura/escritura habilitada para el usuario

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

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

donde:

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

Esta biblioteca incluye un montón de otros, no voy a enumerarlas todo aquí, pero puede leer todo here.

Por supuesto, puede poner en los valores octales para establecer estos bits, sin embargo, algunos pueden argumentar que es una mala práctica de codificación.

Cuestiones relacionadas