web-dev-qa-db-fra.com

Pourquoi open () crée-t-il mon fichier avec les mauvaises autorisations?

J'essaie de lire du texte dans un fichier et de l'écrire dans un autre à l'aide de open(), read() et write().

Ceci est ma open() pour le fichier dans lequel écrire (je veux créer un nouveau fichier et y écrire):

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

Cela définit les autorisations de fichiers sur quelque chose que je ne comprends pas du tout. Voici le résultat de ls -l:

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

Même la permission de lecture est verrouillée. J'ai essayé de chercher cela, mais je n'ai rien trouvé . Étrangement, write() écrit toujours avec succès les données dans le fichier.

Aussi, si je fais un 'chmod 777 test-1', les choses recommencent à fonctionner correctement.

Quelqu'un pourrait-il s'il vous plaît me faire savoir où je me trompe dans mon appel ouvert?

Merci!

Pour votre référence, j'ai collé le programme complet ci-dessous:

#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;
}
44
Chaitanya

open () prend un troisième argument qui est l'ensemble des permissions, c'est-à-dire.

open(filename, O_RDWR|O_CREAT, 0666)

0666 est un nombre octal, c’est-à-dire que chacun des 6 correspond à trois bits de permission

6 = rw

7 = rwx

C'est un piège typique. Le compilateur vous permet de laisser l’argument d’autorisation, car lorsque vous ouvrez un fichier existant, les bits d’autorisation n’ont pas de sens. Mais lorsque vous oubliez l'argument lorsque vous créez un fichier, vous obtenez un ensemble aléatoire d'autorisations, par exemple. 0000 dans votre cas (---).

74
Antti Huima

Reading http://linux.die.net/man/2/open il semble que vous ayez manqué le paramètre mode pour open:

le mode doit être spécifié quand O_CREAT est dans les drapeaux et est ignoré sinon . Le mode argument spécifie les autorisations à utiliser dans le cas où un nouveau fichier est créé.

9
ZeissS

Cette question m'a récemment aidé, alors je voulais faire ma part pour ajouter un peu plus de profondeur à ce qui se passe. Comme il a été dit auparavant, vous manquiez le troisième argument de open(). Cependant, les autorisations que vous voyez ne sont pas aléatoires. ils viennent de la pile. Regardez l'extrait de code suivant:

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

Notez le résultat suivant:

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

Modifions le premier Push en 1, c'est-à-dire l'autorisation d'exécution:

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

et nous obtenons:

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

Changez le Push en 4, c’est-à-dire l’autorisation de lecture, et décoiffez les deux autres valeurs:

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

et nous obtenons:

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

Ainsi, nous pouvons voir que la troisième valeur qui sort de la pile (la première poussée) est ce qui compte vraiment. Enfin, pour le plaisir, nous pouvons essayer 5, puis 50, ce qui donne respectivement:

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

J'espère que cela ajoute un peu de clarté!

8
Billy

En fait, umask() ne filtre que les autorisations et ne les définit pas. La valeur typique de umask() est 0002 ("Ne donnez pas l'autorisation d'écriture au monde") et si votre valeur de mode dans open( "file", O_CREAT, 0777) donnait toutes les autorisations, le fichier résultant aurait 775 comme autorisation. 

3
rgt

Pas strictement pertinent pour la question, mais la réponse acceptée pourrait utiliser ce point de clarification:

Il existe une relation entre rwx et sa représentation numérique qui peut être vue en traitant la présence d'une lettre comme un 1 binaire et son absence comme un 0 binaire. 

par exemple.

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

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

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

En complément, vous pouvez maintenant considérer la commande chmod:

chmod 777 filename.extension -> autorisations rwxrwxrwx

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

ou: chmod 654 filename.extension -> rw-r-x-r--

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

J'espère que c'est informatif!

1
Evan

vous pouvez appeler l'appel système umask(0); avant d'utiliser l'appel système open(); pour définir les autorisations de votre choix afin de classer correctement.

0
Abdo