В настоящее время актуальный стандарт - это POSIX 2008 и его дополнение POSIX 1003.13 |
Организация файловой системы
Приведем еще несколько примеров употребления утилиты ls. После выполнения команд, показанных в листинге 4.4, наша Linux -система выдает информацию определенного вида (см. листинг 4.5):
cd /usr/share/zoneinfo/posix ls -il UTC Universal ZuluЛистинг 4.4. Еще один пример использования служебной программы ls.
2506763 -rw-r--r-- 6 root root 56 Apr 15 2002 UTC 2506763 -rw-r--r-- 6 root root 56 Apr 15 2002 Universal 2506763 -rw-r--r-- 6 root root 56 Apr 15 2002 ZuluЛистинг 4.5. Возможный результат использования служебной программы ls.
Как и предписывает опция -i, выданы порядковые номера ( уникальные идентификаторы ) файлов. Мы видим, что для всех трех имен они одинаковы (2506763), т. е. эти имена ссылаются на один и тот же файл. Поскольку выданное утилитой ls число ссылок равно шести, в файловой системе имеются еще три (жесткие) ссылки на данный файл.
Полезно сопоставить команды и результаты, показанные в листингах 4.4 и 4.5, с теми, что приведены в листингах 4.6 и 4.7.
cd /bin ls -il ex rvi rview vi viewЛистинг 4.6. Применение служебной программы ls для выдачи информации о символьных ссылках.
4849722 lrwxrwxrwx 1 root root 2 Jul 6 14:17 ex -> vi 4849723 lrwxrwxrwx 1 root root 2 Jul 6 14:17 rvi -> vi 4849724 lrwxrwxrwx 1 root root 2 Jul 6 14:17 rview -> vi 4849725 -rwxr-xr-x 1 root root 386120 Mar 8 2002 vi 4849726 lrwxrwxrwx 1 root root 2 Jul 6 14:17 view -> viЛистинг 4.7. Возможный результат использования служебной программы ls при выдаче информации о символьных ссылках.
Все пять файлов - аргументов командной строки (четыре символьные ссылки и один обычный файл ) имеют разные порядковые номера и, следовательно, являются разными файлами (на каждый имеется лишь по одной жесткой ссылке). Для символьных ссылок выдана информация о них, а не об указуемых файлах. Если же добавить опцию -L, мы получим сведения об указуемом файле ( vi ) в пяти экземплярах, но на месте имен будут фигурировать имена символьных ссылок (см. листинг 4.8).
4849725 -rwxr-xr-x 1 root root 386120 Mar 8 2002 ex 4849725 -rwxr-xr-x 1 root root 386120 Mar 8 2002 rvi 4849725 -rwxr-xr-x 1 root root 386120 Mar 8 2002 rview 4849725 -rwxr-xr-x 1 root root 386120 Mar 8 2002 vi 4849725 -rwxr-xr-x 1 root root 386120 Mar 8 2002 viewЛистинг 4.8. Возможный результат использования служебной программы ls при выдаче информации о символьных ссылках и наличии опции -L.
Данные о специальных файлах (см. листинг 4.9) могут выглядеть так, как показано в листинге 4.10.
ls -l /dev/ttyp[0-3] /dev/fd[2-5]Листинг 4.9. Пример использования служебной программы ls для выдачи информации о специальных файлах.
brw-rw---- 1 root floppy 2, 2 Apr 1 2002 /dev/fd2 brw-rw---- 1 root floppy 2, 3 Apr 1 2002 /dev/fd3 brw-rw---- 1 root floppy 2, 128 Apr 1 2002 /dev/fd4 brw-rw---- 1 root floppy 2, 129 Apr 1 2002 /dev/fd5 crw-rw-rw- 1 root root 3, 0 Sep 2 17:21 /dev/ttyp0 crw-rw-rw- 1 root tty 3, 1 Apr 1 2002 /dev/ttyp1 crw-rw-rw- 1 root tty 3, 2 Apr 1 2002 /dev/ttyp2 crw-rw-rw- 1 root tty 3, 3 Apr 1 2002 /dev/ttyp3Листинг 4.10. Возможный результат использования служебной программы ls при выдаче информации о специальных файлах.
Для специальных файлов вместо размера выдаются так называемые старший и младший номера, однозначно определяющие соответствующее устройство; наличие такой возможности, разумеется, зависит от реализации.
Сведения о файлах- каналах могут выглядеть так, как показано в листинге 4.11.
total 0 prw--w---- 1 root root 0 Sep 2 10:42 xdmctl prw--w---- 1 shmyrev root 0 Sep 2 10:42 xdmctl-:0Листинг 4.11. Возможный результат использования служебной программы ls при выдаче информации о каналах.
В листинге 4.12 приведен пример вывода информации о сокетах.
srwx------ 1 shmyrev root 0 Sep 2 10:42 /dev/gpmctl srw-rw-rw- 1 root root 0 Sep 2 10:42 /dev/logЛистинг 4.12. Возможный результат использования служебной программы ls при выдаче информации о сокетах.
Опция -t позволяет увидеть сначала те файлы, которые изменялись позже других. Например, командная строка служебной программы ls
ls -tl /
может выдать следующую информацию (см. листинг 4.13):
total 338 drwxrwxrwt 23 root root 8192 Sep 2 16:26 tmp dr-xr-xr-x 143 root root 0 Sep 2 14:42 proc drwxr-xr-x 60 root root 4096 Sep 2 10:42 etc drwxr-xr-x 18 root root 86016 Sep 2 10:42 dev drwxr-x--- 5 root root 4096 Sep 1 17:10 root drwxr-xr-x 8 root root 4096 Aug 8 13:16 lib drwxr-xr-x 7 root root 4096 Jul 23 13:09 opt drwxr-xr-x 20 root root 4096 Jul 15 18:00 home drwxr-xr-x 14 root root 4096 Jul 15 12:50 usr drwxr-xr-x 2 root root 4096 Jul 11 17:38 sbin drwxr-xr-x 16 root root 4096 Jul 9 16:22 var drwxr-xr-x 2 root root 4096 Jul 8 13:32 bin drwxr-xr-x 4 root root 1024 Jul 6 15:06 boot drwx------ 2 root root 16384 Jul 6 14:15 lost+found drwxrwxr-x 2 root root 4096 Jul 6 13:31 cdrom drwxrwxr-x 2 root root 4096 Jul 6 13:31 a drwxr-xr-x 5 root root 4096 Jul 6 11:24 mnt drwxr-xr-x 6 root root 4096 Feb 23 2003 dss drwxr-xr-x 2 root root 4096 Apr 1 2002 misc drwxr-xr-x 2 root root 4096 Jun 12 2001 initrdЛистинг 4.13. Возможный результат использования служебной программы ls с сортировкой файлов по времени последнего изменения.
Видеть в первую очередь самые свежие файлы полезно в тех случаях, когда программная система перестала работать и нужно найти причину поломки, а для этого требуется прежде всего точно узнать, что же, собственно, изменилось.
При программировании на языке C информацию о файлах получают с помощью функций семейства stat() (см. листинг 4.14).
#include <sys/stat.h> int stat (const char *restrict path, struct stat *restrict buf); #include <sys/stat.h> int fstat (int fildes, struct stat *buf); #include <sys/stat.h> int lstat (const char *restrict path, struct stat *restrict buf);Листинг 4.14. Описание функций семейства stat().
Обратим внимание на использование в описании функций stat() и lstat() ключевого слова restrict из репертуара C99. Оно означает, что по указателям-аргументам доступ осуществляется к непересекающимся областям памяти. Подобная спецификация расширяет оптимизационные возможности компилятора.
Функция stat() предоставляет информацию о поименованном файле: аргумент path указывает на маршрутное имя файла. Чтобы получить эти сведения, достаточно иметь право на поиск для всех компонентов маршрутного префикса. Функция fstat() сообщает данные об открытом файле, задаваемом дескриптором файла fildes. Функция lstat() эквивалентна stat() за одним исключением: если аргумент path задает символьную ссылку, lstat() возвращает информацию о ней, а stat() - о файле, на который эта ссылка указывает.
В случае нормального завершения результат функций семейства stat() равен 0.
Аргумент buf является указателем на структуру типа stat, в которую помещается информация о файле. Согласно стандарту POSIX-2001, в ней содержатся по крайней мере следующие поля:
dev_t st_dev; /* Идентификатор устройства, содержащего файл */ ino_t st_ino; /* Порядковый номер файла в файловой системе */ mode_t st_mode; /* Режим файла nlink_t st_nlink; /* Число жестких ссылок на файл */ uid_t st_uid; /* Идентификатор владельца файла */ gid_t st_gid; /* Идентификатор владеющей группы */ off_t st_size; /* Для обычных файлов и символьных ссылок - размер в байтах */ /* Для файлов других типов значение этого поля неспецифицировано */ time_t st_atime; /* Время последнего доступа */ time_t st_mtime; /* Время последнего изменения файла */ time_t st_ctime; /* Время последнего изменения статуса файла */
Некоторые пояснения. Комбинация значений ( st_dev, st_ino ) должна однозначно определять файл в пределах объединенной (в том числе сетевой) файловой системы. Статус файла меняется, когда модифицируются его атрибуты (например, режим ), а не содержимое.
В файле <sys/stat.h> определена не только структура stat, но и константы, полезные для работы с битами режима. Так, S_IFMT выделяет тип файла, S_IFREG обозначает обычные файлы, S_IRWXU - биты режима доступа владельца и т.д.
Приведем пример использования функций stat() и lstat() (см. листинг 4.15).
/* Программа выдает информацию о файлах - аргументах командной строки */ #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> /* Функция возвращает односимвольное обозначение типа файла */ /* Для неизвестного типа возвращается 'u' */ static char my_filetype (const mode_t mode) { switch (mode &S_IFMT) { case S_IFDIR: return ('d'); case S_IFBLK: return ('b'); case S_IFCHR: return ('c'); case S_IFLNK: return ('l'); case S_IFIFO: return ('p'); case S_IFREG: return ('-'); case S_IFSOCK: return ('s'); default: return ('u'); } } int main (int argc, char *argv[]) { struct stat buf; int i; for (i = 1; i < argc; i++) { if (stat (argv [i], &buf)) { fprintf (stderr, "\nstat: не удалось получить информацию о файле %s\n", argv [i]); return (-1); } printf ("\nstat-информация о файле %s:\n", argv [i]); printf ("Тип: %c\n", my_filetype (buf.st_mode)); printf ("Размер: %ld\n", buf.st_size); if (lstat (argv [i], &buf)) { fprintf (stderr, "\nlstat: не удалось получить информацию о файле %s\n", argv [i]); return (-1); } printf ("\nlstat-информация о файле %s:\n", argv [i]); printf ("Тип: %c\n", my_filetype (buf.st_mode)); printf ("Размер: %ld\n", buf.st_size); } return 0; }Листинг 4.15. Пример использования функций stat() и lstat().
Возможный результат работы этой программы с аргументами /bin/view и /bin/vi показан в листинге 4.16.
stat-информация о файле /bin/view: Тип: - Размер: 386120 lstat-информация о файле /bin/view: Тип: l Размер: 2 stat-информация о файле /bin/vi: Тип: - Размер: 386120 lstat-информация о файле /bin/vi: Тип: - Размер: 386120Листинг 4.16. Возможный результат работы программы, использующей функции stat() и lstat().