Почему open () создает мой файл с неправильными разрешениями? - PullRequest
45 голосов
/ 11 февраля 2010

Я пытаюсь прочитать один текст из файла и записать его в другой файл, используя 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;
}

Ответы [ 7 ]

76 голосов
/ 11 февраля 2010

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

open(filename, O_RDWR|O_CREAT, 0666)

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

6 = RW

7 = RWX

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

9 голосов
/ 11 февраля 2010

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

Режим

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

8 голосов
/ 26 февраля 2014

Этот вопрос недавно помог мне, поэтому я хотел внести свой вклад, чтобы добавить немного больше глубины в то, что происходит. Как было сказано ранее, вы пропустили третий аргумент 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

Надеюсь, это добавит ясности!

3 голосов
/ 04 марта 2015

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

1 голос
/ 31 марта 2017

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

Существует связь между 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--

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

1 голос
/ 23 марта 2014

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

0 голосов
/ 05 июня 2017

Это старая ветка, но я думаю, что люди должны знать о библиотеке "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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...