Подтвердить что ты не робот

Почему open() создает мой файл с неправильными разрешениями?

Я пытаюсь прочитать текст из файла и записать его другому, используя open(), read() и write().

Это мой open() для файла для записи (я хочу создать новый файл и записать в него):

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

Это устанавливает разрешения файлов для чего-то, чего я вообще не понимаю. Это результат ls -l:

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

Даже разрешение чтения заблокировано. Я попытался найти это, но не смог найти НИКАКОГО. Как ни странно, write() все еще успешно записывает данные в файл.

Кроме того, если я делаю "chmod 777 test-1", все снова начинает работать правильно.

Может кто-нибудь, пожалуйста, сообщите мне, где я ошибаюсь в своем открытом вызове?

Спасибо!

Для вашей справки я вставил полную программу ниже:

#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;
}
4b9b3361

Ответ 1

open() принимает третий аргумент, который является набором разрешений, т.е.

open(filename, O_RDWR|O_CREAT, 0666)

0666 - восьмеричное число, то есть каждый из 6 соответствует трем битам разрешения

6 = rw

7 = rwx

Это типичная ловушка. Компилятор позволяет вам оставить аргумент разрешения прочь, потому что, когда вы открываете существующий файл, бит разрешения не имеет смысла. Но когда вы забудете аргумент при создании файла, вы получите случайный набор разрешений, например. 0000 в вашем случае (---).

Ответ 2

Чтение http://linux.die.net/man/2/open кажется, что вы пропустили параметр mode для открытия:

Режим

должен указываться, когда O_CREAT находится во флагах, и в противном случае игнорируется.  Режим аргумента указывает разрешения для использования в случае создания нового файла.

Ответ 3

Этот вопрос недавно помог мне, поэтому я хотел внести свой вклад, чтобы добавить немного больше информации о том, что происходит. Как было сказано ранее, у вас отсутствовал третий аргумент open(). Однако разрешения, которые вы видите, не являются случайными; они идут из стека. Посмотрите следующий фрагмент кода:

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

Обратите внимание на следующий результат:

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

Изменить первое нажатие на 1, то есть выполнить разрешение:

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

и получим:

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

Измените push на 4, т.е. разрешение на чтение, и беспорядок с двумя другими значениями:

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

и получим:

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

Таким образом, мы можем видеть, что третье значение, выскочившее из стека (первое нажатие), действительно имеет значение. Наконец, для удовольствия мы можем попробовать 5, а затем 50, что соответственно приведет к:

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

Надеемся, что это добавит некоторую ясность!

Ответ 4

Фактически umask() фильтрует только разрешения и не устанавливает их. Типичным значением umask() является 0002 ( "не выдавать разрешение на запись миру" ), и если ваше значение режима в open( "file", O_CREAT, 0777) дало все разрешения, результирующий файл имел бы 775 как его permssions.

Ответ 5

Не имеет никакого отношения к вопросу, но принятый ответ может использовать этот поясняющий момент:

Существует связь между rwx и его численным представлением, которое можно увидеть, рассматривая присутствие буквы как двоичной 1, а ее отсутствие как двоичное 0.

например.

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

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

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

В качестве дополнительного добавления вы можете теперь рассмотреть команду chmod:

chmod 777 filename.extension → rwxrwxrwx разрешений

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

или: chmod 654 filename.extension → rw-r-x-r -

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

Надеюсь, что это информативно!

Ответ 6

вы можете вызвать системный вызов umask(0); перед использованием системного вызова open();, чтобы правильно настроить права на выбор.

Ответ 7

Это своего рода старый поток, но я думаю, что люди должны знать о библиотеке "sys/stat.h". Это включает в себя кучу символических констант для установки битов разрешения.

Например: Чтобы открыть файл с разрешениями на чтение/запись, включенными для пользователя

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

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

где:

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

В эту библиотеку входит множество других, я не буду перечислять их здесь, но вы можете прочитать все это здесь.

Конечно, вы можете ввести восьмеричные значения, чтобы установить эти биты, однако некоторые могут утверждать, что это плохая практика кодирования.