Программа в листинге 15.1 использует системный вызов stat() для извлечения информации о файле, чье имя передано в командную строку. Если указан параметр командной строки — l, то программа задействует системный вызов lstat(), чтобы мы смогли извлечь информацию о символической ссылке, а не о файле, на который она указывает. Данная программа выводит все поля возвращаемой структуры stat. (Объяснение того, почему мы присваиваем полям st_size и st_blocks тип long long, см. в разделе 5.10.) Функция filePermStr(), примененная в этой программе, показана в листинге 15.4.

Приведу пример использования данной программы:

$ echo 'All operating systems provide services for programs they run' > apue

$ chmod g+s apue Установка бита set-group-ID; отражается

на времени последнего изменения статуса

$ cat apue Отражается на времени последнего доступа к файлу

All operating systems provide services for programs they run

$ ./t_stat apue

File type: regular file

Device containing i-node: major=3 minor=11

I-node number: 234363

Mode: 102644 (rw-r — r-)

special bits set: set-GID

Number of (hard) links: 1

Ownership: UID=1000 GID=100

File size: 61 bytes

Optimal I/O block size: 4096 bytes

512B blocks allocated: 8

Last file access: Mon Jun 8 09:40:07 2011

Last file modification: Mon Jun 8 09:39:25 2011

Last status change: Mon Jun 8 09:39:51 2011

Листинг 15.1. Извлечение информации о файле из структуры stat и ее интерпретация

files/t_stat.c

#define _BSD_SOURCE /* Берем major() и minor() из файла */

#include

#include

#include

#include "file_perms.h"

#include "tlpi_hdr.h"

static void

displayStatInfo(const struct stat *sb)

{

printf("File type: ");

switch (sb->st_mode & S_IFMT) {

case S_IFREG: printf("regular file\n"); break;

case S_IFDIR: printf("directory\n"); break;

case S_IFCHR: printf("character device\n"); break;

case S_IFBLK: printf("block device\n"); break;

case S_IFLNK: printf("symbolic (soft) link\n"); break;

case S_IFIFO: printf("FIFO or pipe\n"); break;

case S_IFSOCK: printf("socket\n"); break;

default: printf("unknown file type?\n"); break;

}

printf("Device containing i-node: major=%ld minor=%ld\n",

(long) major(sb->st_dev), (long) minor(sb->st_dev));

printf("I-node number: %ld\n", (long) sb->st_ino);

printf("Mode: %lo (%s)\n",

(unsigned long) sb->st_mode, filePermStr(sb->st_mode, 0));

if (sb->st_mode & (S_ISUID | S_ISGID | S_ISVTX))

printf(" special bits set: %s%s%s\n",

(sb->st_mode & S_ISUID)? "set-UID": "",

(sb->st_mode & S_ISGID)? "set-GID": "",

(sb->st_mode & S_ISVTX)? "sticky": "");

printf("Number of (hard) links: %ld\n", (long) sb->st_nlink);

printf("Ownership: UID=%ld GID=%ld\n",

(long) sb->st_uid, (long) sb->st_gid);

if (S_ISCHR(sb->st_mode) || S_ISBLK(sb->st_mode))

printf("Device number (st_rdev): major=%ld; minor=%ld\n",

(long) major(sb->st_rdev), (long) minor(sb->st_rdev));

printf("File size: %lld bytes\n", (long long) sb->st_size);

printf("Optimal I/O block size: %ld bytes\n", (long) sb->st_blksize);

printf("512B blocks allocated: %lld\n", (long long) sb->st_blocks);

printf("Last file access: %s", ctime(&sb->st_atime));

printf("Last file modification: %s", ctime(&sb->st_mtime));

printf("Last status change: %s", ctime(&sb->st_ctime));

}

int

main(int argc, char *argv[])

{

struct stat sb;

Boolean statLink; /* Истина, если указано "-l" (то есть использовать lstat) */

int fname; /* Место аргумента filename в массиве argv[] */

statLink = (argc > 1) && strcmp(argv[1], "-l") == 0;

/* Простой синтаксический анализ для "-l" */

fname = statLink? 2: 1;

if (fname >= argc || (argc > 1 && strcmp(argv[1], " — help") == 0))

usageErr("%s [-l] file\n"

" — l = use lstat() instead of stat()\n", argv[0]);

if (statLink) {

if (lstat(argv[fname], &sb) == -1)

errExit("lstat");

} else {

if (stat(argv[fname], &sb) == -1)

errExit("stat");

}

displayStatInfo(&sb);

exit(EXIT_SUCCESS);

}

files/t_stat.c

15.2. Файловые метки времени

Поля st_atime, st_mtime и st_ctime структуры stat содержат файловые метки времени. В эти поля записывается соответственно время последнего доступа к файлу, время последнего изменения файла и время последнего изменения статуса файла (то есть последнего изменения информации в файловом дескрипторе). Метки времени выражаются в секундах, прошедших с начала «эры UNIX» (1 января 1970 года; см. раздел 10.1).

Большинство нативных файловых систем Linux и UNIX поддерживают все поля меток времени, однако некоторые не-UNIX системы могут этого не делать.

Перейти на страницу:

Похожие книги