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 файл будет усечен до нулевого размера (если он существует и если это позволяют права доступа). |