Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #51, ФЕВРАЛЬ 2005 г.

C в *nix – залог здоровья

Косякин Антон

Спецвыпуск: Хакер, номер #051, стр. 051-078-3


Если твои программы соответствуют стандарту ANSI C или C99, то они будут легко компилироваться под любой ОС с использованием "правильного" компилятора. Однако стремление к соответствию упомянутым стандартам, к сожалению, не разбудит полностью все таланты системы.

Для любой *nix-программы, помимо стандартных заголовков stdlib.h & stdio.h, необходимо использование заголовка unistd.h. При использовании некоторых специфичных типов данных необходимо подключать заголовок sys/types.h.

Для примера рассмотрим основные функции (примитивы) для работы с файлами, предоставляемые любой UNIX-системой. Эти функции состоят из небольшого набора системных вызовов, обеспечивающих непосредственный доступ к средствам ввода\вывода ОС. Одновременно с этим они являются основой для всей системы ввода\вывода *nix, и многие другие механизмы доступа к файлам (например) основаны именно на них.

Вот они: Open - открытие файла, Close - закрытие, Read - чтение данных, Write - запись данных, Lseek - перемещение в заданную позицию в файле, Fcntl - управление связанными с файлом атрибутами.

За что я люблю эту ОС, так это за то, что эти функции можно использовать почти для всего: и для работы с файлами, и для вывода на экран, и для организации обмена данными по сети. Один интерфейс для множества сходных задач. Сразу наплывают воспоминания о тех временах, когда я активно программировал под самой лучшей в мире операционной системой - Windows :).

Ближе к делу - рассмотрим элементарный рабочий пример:

#include <unistd.h>

#include <fcntl.h>

#include <sys/types.h>

int main () {

int fd;

ssize_t nread;

char buf[1024];

fd = open("data", O_RDONLY);

nread = read(fd, buf, 1024);

close(fd);

};

Вызов Open открывает в текущем каталоге файл Data только для чтения, возвращая целочисленный (и неотрицательный) дескриптор файла, по которому система уже будет опознавать этот файл и давать возможность выполнять с ним нужные действия. Далее идет системный вызов Read, читающий из файла с идентификатором fd первый килобайт данных. Все не так сложно.

Стоит заметить, что в случае возникновения ошибки любой из используемых выше системных вызовов вернет - 1. Чтобы узнать точное значение ошибки - подключить заголовочный файл errno.h и посмотреть значение переменной Errno. Или вызвать функцию Perror(), которая выведет текстовую интерпретацию ошибки на экран.

Внимание! Вызов Open имеет три параметра (последний - необязательный): строка, содержащая название файла, после которой идет целочисленный метод доступа. В этом случае использован O_RDONLY - только чтение. Также возможно использование O_WRONLY (только запись), O_RDWR (открытие для чтения и записи) или значение O_CREAT, используемое для создания файла. Как всегда, комбинировать значения можно при помощи "|" (например, O_CREAT | O_WRONLY). При использовании значения O_CREAT нужно передать системному вызову и третий параметр типа mode_t (на самом деле он тоже целочисленный), который будет характеризовать права доступа. Кстати, есть еще одно полезное значение второго параметра - O_TRUNC. При его использовании вместе с флагом O_CREAT файл будет усечен до нулевого размера (если он существует и если это позволяют права доступа).

Назад на стр. 051-078-2  Содержание  Вперед на стр. 051-078-4