Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
оси_лабы_методички.doc
Скачиваний:
16
Добавлен:
10.11.2018
Размер:
418.3 Кб
Скачать

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

 

Системные вызовы представляют собой единственное средство, реализующее интерфейс между пользовательскими программами и ядром ОС 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.

 

STAT и FSTAT

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

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

int fstat(int fd, struct stat *statbuf);

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

 

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 _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);

 

 

READ

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

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

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

 

WRITE

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

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

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

 

LSEEK

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

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

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

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

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

 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 будет закрыт.