Skip to content

Home Программирование Открытие файла: open()
Открытие файла: open()

Мы уже знаем один способ открытия файла посредством системного вызова creat (). Но в этом случае файл всегда открывается в режиме "только запись" и, к тому же, если файл уже существует, то он попросту будет очищен. Кроме того, нет никаких адекватных механизмов проверки того, существовал ли файл вообще.

Открыть файл определенным образом можно через системный вызов open(). Приятная особенность open() — возможность установки флагов открытия файла, благодаря которым процесс открытия файла становится контрол ируемы м.

Флаги открытия файла (как и флаги режима) представляют собой набор символических констант, которые могут соединяться операцией побитовой дизъюнкции (ИЛИ). Чтобы использовать эти флаги и системный вызов open (), в программу необходимо включить заголовочный файл fcntl.h.

Обычно имена заголовочных файлов перекликаются с механизмами, которые в них объявлены. Например, stdio.h расшифровывается как "STanDard Input/ Output". Неблагозвучное имя fcntl.h образовано от словосочетания "File CoNTroL".

Результат объединения флагов открытия файла представляет собой обычное целое число.  В следующем списке указаны лишь самые "популярные" из них:

  • o_rdonly — открыть файл только для чтения;
  • o_wronly — открыть файл только для записи;
  • o_rdwr — открыть файл для чтения и записи;
  • o_creat — создать файл, если не существует;
  • o_trunc — очистить файл, если он существует;
  • o_append —дописать в существующий файл;
  • o_excl — не открывать файл, если он существует (используется с флагом o_creat).

Системный вызов open (), объявленный в заголовочном файле fcntl.h, имеет два прототипа:

int open (const char * FILENAME, int FLAGS, mode_t MODE); 
int Open (const char * FILENAME, int FLAGS);

Как уже сообщалось, подобная двойственность прототипа достигается благодаря механизму va_arg (он же stdarg), являющемуся частью стандарта языка С.

Аргументы filename и mode полностью аналогичны соответствующим аргументам системного вызова creat (). Второй прототип open () обычно используется для открытия файлов в режиме "только чтение", когда указание режима является избыточным. Аргумент flags представляет собой набор флагов открытия, объединенных операцией побитового или. Следует отметить, что некоторые флаги не могут объединяться между собой. Здесь нужно рассуждать логически. Нельзя, например, объединить флаги o_rdonly и o_wronly, поскольку они противоречат друг другу.

Очень часто в качестве аргумента mode системных вызовов creat () и open () указывают не объединенные операцией побитовой дизъюнкции (ИЛИ) именованные константы, а числа в восьмеричной системе счисления. Такое представление называют восьмеричным представлением прав доступа. Возможно, вы никогда не будете применять такой подход, однако умение видеть права доступа в восьмеричной форме может пригодиться при чтении чужих программ.

В ранних Unix-подобных системах не было именованных констант из sys/stat.h. Для записи прав доступа использовались только восьмеричные числа.

Для записи прав доступа, которые занимают 9 бит режима файла, достаточно трех восьмеричных цифр. При этом следует учитывать, что биты отсчитыва-ются справа налево (little endian). Восьмеричная запись битов прав доступа удобна тем, что каждой восьмеричной цифре соответствует последовательность из трех бит.

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

Программа mymask.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
int main (void)
{
mode_t test_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
printf ("%d\n", test_mode);
return 0;
}

Проверим, что получилось:

$ gcc -о mymask mymask.c
$ ./mymask
420

Итак, правам доступа "чтение и запись для владельца" плюс "чтение для группы и остальных пользователей" соответствует число 420. Теперь переведем это число в восьмеричную систему счисления:

$ be -q
obase=8
420
644
quit

Получилось 644. Переведем полученное число в двоичную систему счисления:

$ be -q
ibase=8
obase=2
644
110100100
quit

Теперь пронумеруйте полученную цепочку от 0 до 8 справа налево. Это и есть биты прав доступа. Кроме того, если наложить эти биты на привычный нам шаблон rwxrwxrwx, который выводит программа Is, заменив все нули дефисами, то получим права доступа в удобном для чтения виде:

rw-r—г—

Теперь можно систематизировать знания, полученные в результате эксперимента. Итак, восьмеричные права доступа состоят из трех цифр:

  • первая цифра — права доступа для владельца;
  • вторая цифра — права доступа для группы;
  • третья цифра — права доступа для остальных пользователей.

Если запомнить, что означает каждая цифра, то работа с восьмеричными правами не будет вызывать никаких затруднений (в скобках даны двоичные значения):

  • 0 — отсутствие прав доступа (000);
  • 1—только выполнение (001); О 2 — только запись (010);
  • 3 — запись и выполнение (011);
  • 4 — только чтение (100);
  • 5 — чтение и выполнение (101);
  • 6 — чтение и запись (110);
  • 7 — чтение, запись и выполнение (111).

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

$ touch myfile
$ Is -1 myfile
-rw-r—r— 1 nn users 0 2006-12-08 01:24 myfile
$ chmod 600 myfile
$ Is -1 myfile
-rw------1 nn users 0 2006-12-08 01:24 myfile

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

Рассмотрим теперь программу, которая создает файл при помощи системного вызова open ()

Программа creatopen.с

#include <stdio.h> 
#include <fcntl.h>
#include <unistd.h>
int main (int argc, char ** argv)
{
int fd;
if (argc < 2)
{
fprintf (stderr, "Too few arguments\n");
return 1;
}
fd = open ( argv[1], 0_WRONLY | 0_CREAT | 0_TRUNC, 0640);
if (fd == -1)
{
fprintf (stderr, "Cannot create file (%s)\n"^, argv[ 1 ] ) ;
return 1;
}
close (fd);
return 0;
}

В первую очередь следует отметить, что системный вызов creato полностью идентичен open (), вызванному с флагами открытия o_wronly, o_creat и o_truwc. Если не верите, посмотрите в исходниках ядра Linux файл fs/open.c.

В данную программу не включаются файлы sys/stat.h и sys/types.h, поскольку мы не пользуемся ни константами режима, ни типом mode_t. Заголовочный файл unistd.h нужен для системного вызова close о, о котором пойдет речь в следующем разделе.

Комментарии (0)

RSS feed Comments

Написать комментарий

smaller | bigger

busy
 

Регистрация




Top