2010-04-03 9 views
6

Dado el siguiente código (que se supone que escribir "Hola Mundo" en un archivo "HelloWorld", y luego leer el texto):sistema C llama abierta/lectura/escritura/cierre y O_CREAT | O_EXCL

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

#define FNAME "helloworld" 

int main(){ 
    int filedes, nbytes; 
    char buf[128]; 

    /* Creates a file */ 
    if((filedes=open(FNAME, O_CREAT | O_EXCL | O_WRONLY | O_APPEND, 
     S_IRUSR | S_IWUSR)) == -1){ 
      write(2, "Error1\n", 7); 
    } 

    /* Writes hello world to file */ 
    if(write(filedes, FNAME, 10) != 10) 
     write(2, "Error2\n", 7); 

    /* Close file */ 
    close(filedes); 

    if((filedes = open(FNAME, O_RDONLY))==-1) 
     write(2, "Error3\n", 7); 

    /* Prints file contents on screen */  
    if((nbytes=read(filedes, buf, 128)) == -1) 
     write(2, "Error4\n", 7); 

    if(write(1, buf, nbytes) != nbytes) 
     write(2, "Error5\n", 7); 

    /* Close file after read */ 
    close(filedes); 

    return (0); 
} 

la primera vez que ejecute el programa, la salida es:

helloworld 

Después de que cada vez que para ejecutar el programa, la salida es:

Error1 
Error2 
helloworld 

No entiendo por qué el texto no está adjunto, ya que he especificado el archivo O_APPEND. ¿Es porque he incluido O_CREAT? ¿El archivo ya está creado, no se debe ignorar O_CREAT?

Respuesta

11

O_EXCL obliga a crear el archivo. Si el archivo ya existe, la llamada falla.

Se utiliza para asegurar que el archivo se debe crear, con los permisos otorgados en el tercer parámetro. En resumen, tienes estas opciones:

  • O_CREAT: Crear el archivo con los permisos dados si el archivo no existe ya. Si el archivo existe, se abre y los permisos se ignoran.
  • O_CREAT | O_EXCL: Cree el archivo con los permisos especificados si el archivo aún no existe. Si el archivo existe, falla. Esto es útil para crear archivos de bloqueo y garantizar el acceso exclusivo al archivo (siempre que todos los programas que usan ese archivo sigan el mismo protocolo).
  • O_CREAT | O_TRUNC: Cree el archivo con los permisos dados si el archivo aún no existe. De lo contrario, trunque el archivo a cero bytes. Esto tiene más del efecto que esperamos cuando pensamos "crear un nuevo archivo en blanco". Aún así, mantiene los permisos ya presentes en el archivo existente.

Más información de the manual page:

O_EXCL

Cuando se utiliza con O_CREAT, si el archivo ya existe es un error y al aire libre() fallará. En este contexto, existe un enlace simbólico, independientemente de donde apunta. O_EXCL está roto en sistemas de archivos NFS; los programas que se basan en él para realizar tareas de bloqueo contendrán una condición de carrera. La solución para realizar atómica de bloqueo archivo utilizando un fichero de bloqueo está a crear un archivo único en el mismo sistema de archivos (por ejemplo, la incorporación de nombre de host y pid), enlace de uso (2) para hacer un enlace al fichero de bloqueo. Si link() devuelve 0, , el bloqueo se realiza correctamente. De lo contrario, use stat (2) en el archivo exclusivo para verificar si su número de enlaces ha aumentado a 2, en , en cuyo caso el bloqueo también es exitoso.

+0

Gracias, al eliminar O_EXCL, el código es funcional. ¿Puedes explicarme el uso de O_EXCL? –

Cuestiones relacionadas