Главная » Программирование для UNIX » Файловая система UNIX: индексные дескрипторы

0

В этом разделе будут рассмотрены системные вызовы, имеющие дело с файловой системой и, в частности, с информацией о файлах, такой как размер, даты, права доступа и т. д. Эти системные вызовы дают доступ  ко всей той информации, которую мы обсуждали в главе 2.

Давайте  теперь  обратимся  собственно к  индексным  дескрипторам.

Часть их описывается структурой stat, определяемой в sys/stat.h:

struct stat /*  структура,  возвращаемая stat */

{

dev_t

st_dev;

/*  устройство  индексного  дескриптора */

ino_t

st_ino;

/*  номер  индексного  дескриптора */

short

st_mode

/*  биты  доступа */

short

st_nlink;

/*  количество  ссылок на файл  */

short

st_uid;

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

short

st_gid;

/*  идентификатор  группы  владельца */

dev_t

st_rdev;

/*  для  специальных  файлов */

off_t

st_size;

/*  размер  файла в  символах */

time_t

st_atime;

/*  время  последнего  чтения из  файла */


time_t

st_mtime;

/*  время  последней  записи или  создания файла  */

time_t

st_ctime;

/*  время  последнего  изменения  файла или  индексного

дескриптора  */

};

Большинство полей описано в комментариях. Такие типы, как dev_t и ino_t, определены в sys/types.h, это обсуждалось в предыдущих разделах. Элемент st_mode содержит набор флагов, описывающих файл; для  удобства флаги определены также в файле sys/stat.h:

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

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

#define      S_IFCHR  0020000 /*  специальный  символьный  */

#define      S_IFBLK  0060000 /*  специальный  блочный */

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

#define S_ISUID    0004000    /*  при запуске  установить  эффективный идентификатор  пользователя как у  владельца */

использования  */

#define S_IREAD    0000400    /*  права на чтение,  владелец */

#define S_IWRITE  0000200    /*  права на запись,  владелец */

#define S_IEXEC    0000100    /*  права на  выполнение/поиск, владелец */

Доступ к индексному дескриптору файла  выполняется при  помощи двух  системных вызовов: stat и fstat. Вызов  stat принимает имя фай ла и возвращает информацию индексного дескриптора для  этого фай ла (или  –1 в случае ошибки), fstat делает то же самое из файлового дескриптора для открытого файла (не из указателя FILE). Таким образом,

char  *name; int fd;

struct stat stbuf;

stat(name,  &stbuf); fstat(fd,  &stbuf);

Структура stbuf заполняется информацией из индексного дескриптора для файла с именем name или дескриптором fd.

Теперь, когда мы располагаем всеми  этими фактами, попробуем написать какой-нибудь полезный код. Начнем с того, что напишем на языке Си программу checkmail, которая будет наблюдать за почтовым ящиком пользователя. Если файл увеличивается в размере, программа пишет You have mail и подает звуковой сигнал. (Если  файл становится меньше, это,  видимо, потому, что вы только что прочитали и удалили какое-то пись мо, сообщения не требуются). Для первого шага этого вполне достаточно; когда эта программа заработает, можно будет ее усовершенствовать.

/*  checkmail:  следит за  почтовым  ящиком  пользователя  */

#include <stdio.h>

#include <sys/types.h>

#include  <sys/stat.h> char  *progname;

char  *maildir  = "/usr/spool/mail";   /*  зависит  от  системы */

main(argc,  argv) int  argc;

char  *argv[];

{

struct stat buf;

char  *name,  *getlogin(); int  lastsize  =  0;

progname = argv[0];

if ((name  = getlogin())  == NULL)

error("can’t  get  login name", (char *)  0); if  (chdir(maildir)  ==  –1)

error("can’t  cd  to  %s",  maildir); for  (;;)  {

if (stat(name, &buf)  == –1)  /*  нет почтового ящика  */ buf.st_size = 0;

if (buf.st_size > lastsize)

fprintf(stderr,  "\nYou  have  mail\007\n"); lastsize =  buf.st_size;

sleep(60);

}

}

Функция  getlogin(3)  возвращает  имя,  с  которым  зарегистрирован пользователь, или NULL, если  имя  не получено. Системный вызов chdir переводит checkmail в почтовый каталог, так  что последующим вызо вам  stat  не  приходится просматривать каждый  каталог,  начиная с корневого и заканчивая почтовым. В вашей системе, может быть, при дется изменить значение maildir. Программа checkmail  написана так, чтобы  попытки предпринимались даже в том случае, когда почтовый ящик не существует, поскольку большинство почтовых программ удаляют почтовый ящик, если он пуст.

Эта программа была  представлена в главе 5 для иллюстрации циклов оболочки. Та версия создавала несколько процессов при  каждом просмотре  почтового ящика,  что  могло  вызвать бoльшую, чем  хотелось бы, нагрузку на систему. Версия на языке Си – это единственный процесс,  запускающий stat для файла каждую минуту. Во что обойдется программа проверки почтового ящика, которая все время работает в фоновом режиме? По  оценкам авторов, будет  затрачено менее  одной секунды в час, что довольно мало, и это чрезвычайно важно.

Источник: Керниган Б., Пайк Р., UNIX. Программное окружение. – Пер. с англ. – СПб: Символ-Плюс, 2003. – 416 с., ил.

По теме:

  • Комментарии