Программирование операций ввода-вывода

Системные вызовы представляют собой единственное средство, реализующее интерфейс между пользовательскими программами и ядром ОС UNIX. Всякая операция ввода/вывода для пользователя – это операция ввода/вывода в файл. Рассмотрим наиболее часто используемые из системных вызовов.

OPEN. Открывает файл для получения доступа к нему:

int open(char *pathname, int flags, mode_t mode)

Возвращает положительное целое число, так называемый пользовательский дескриптор файла fd, который в дальнейшем используется для обращения к этому файлу. pathname - указатель на строку символов, содержащую полное имя файла. mode - режим открытия файла (по чтению, записи и др.) Если нет возможности открыть файл, open возвращает -1. flags определяет режим открытия файла (O_CREAT, O_TRUNC, O_RDONLY, O_WRONLY и т.д.), mode задает права доступа к создаваемому файлу.

CLOSE. Закрывает файл, уничтожает связь между пользовательским дескриптором файла и самим файлом:

void close(int fd)

Параметр fd – дескриптор файла, возвращенный вызовом open. Функция close уничтожает связь между пользовательским дескриптором файла и самим файлом и уменьшает на 1 значения счетчиков в относящихся к нему записях файловых таблиц. Если значение счетчика становится равным 0, то данная запись считается свободной. Если равно 0 значение счетчика в записи системной таблицы описателей файлов, файл закрывается.

STAT и FSTAT. Эти системные вызовы позволяют получить информацию о файле, не осуществляя явного доступа к нему:

int stat(char *path, struct stat *statbuf)

int fstat(int fd, struct stat *statbuf)

Вызов stat предоставляет информацию по имени файла, а fstat – по номеру дескриптора открытого файла. Информация помещается в структуру stat, описанную ниже:

struct stat

{ dev_t st_dev;

ino_t st_ino;

ushort st_mode; /* режим доступа и тип файла */

short st_nlink; /*счетчик числа ссылок на файл*/

ushort st_uid; /*идентификатор его владельца */

ushort st_gid; /* идентификатор группы */

dev_t st_rdev; /* тип устройства */

off_t st_size; /* размер файла в байтах */

time_t st_atime; /* дата последнего доступа */

time_t st_mtime; /* дата последней модификации */

time_t st_ctime; /* дата создания */

}

Для детализации информации в поле st_mode используются следующие макросы:

#define S_IFMT 0170000 /* тип файла */

#define S_IFDIR 0040000 /* каталог */

#define S_IFCHR 0020000 /*байториентированный спец.файл */

#define S_IFBLK 0060000 /*блокориентированный спец.файл */

#define S_IFREG 0100000 /* обычный файл */

#define S_IFIFO 0010000 /* дисциплина FIFO */

#define S_ISUID 04000 /* идентификатор владельца */

#define S_ISGID 02000 /* идентификатор группы */

#define S_ISVTX 01000 /*сохранить свопируемый текст */

#define S_IREAD 00400 /* владельцу разрешено чтение */

#define S_WRITE 00200 /* владельцу разрешена запись */

#define S_IEXEC 00100 /*владельцу разрешено исполнение */

Пример использования вызова stat:

struct stat stbuf;

char *filename = ”myfile”;

............

stat(filename, &stbuf);

if ((stbuf.st_mode & S_IFMT) == S_IFDIR)

printf("%s является каталогом", filename);

LSEEK. Перемещает указатель файла с пользовательским дескриптором fd на offset байт:

long lseek(int fd, long offset, int fromwhere)

Параметр fromwhere определяет положение указателя файла перед началом перемещения:

SEEK_SET – от начала файла;

SEEK_CUR – от текущей позиции указателя;

SEEK_END – от конца файла.

READ. Осуществляет чтение из открытого файла указанного количества символов в буфер:

int read(int fd, void *buffer, unsigned count)

Возвращает количество реально прочитанных байт num или отрицательный код ошибки. При этом указатель чтения/записи перемещается на num байт.

WRITE. Осуществляет запись в открытый файл указанного количества символов из буфера:

int write(int fd, void *buffer, unsigned count)

Возвращает количество реально записанных num байт или отрицательный код ошибки. При этом указатель чтения/записи перемещается на num байт.

DUP и DUP2. Эти системные вызовы дублируют пользовательский дескриптор файла:

int dup(int handle);

int dup2(int oldhandle, int newhandle);

fd1 = dup(handle);

fd2 = dup2(oldhandle, newhandle);

Копия пользовательского дескриптора позволяет осуществлять к файлу доступ того же типа и с использованием того же указателя чтения/записи, что и с помощью оригинального дескриптора.

Вызов dup возвращает первый свободный номер дескриптора fd1 или -1, если указанный дескриптор handle не соответствует открытому файлу или нет свободных номеров.

Вызов dup2 возвращает дескриптор newhandle как копию дескриптора oldhandle или -1, если указанный дескриптор oldhandle не соответствует открытому файлу. Если newhandle до этого указывал на открытый файл, этот файл в результате вызова dup2 будет закрыт.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: