fanotify

title: fanotify(7)

summary: отслеживание событий в файловой системе

text:
# fanotify(7)

## ИМЯ
fanotify - отслеживание событий в файловой системе

## ОПИСАНИЕ
Программный интерфейс fanotify уведомляет о событиях в файловой системе и перехватывает их. Например, его можно использовать для сканирования файлов на вирусы и управления иерархическим хранилищем. В настоящее время, поддерживается только ограниченный набор событий. В частности, не поддерживаются события создания, удаления и перемещения (о программном интерфейсе для этих событий смотрите в inotify(7)).

Дополнительные возможности по сравнению с программным интерфейсом inotify(7): способность отслеживать все объекты в смонтированной файловой системе, давать права на доступ и читать или изменять файлы перед тем как доступ получат другие приложения.

В программный интерфейс входят следующие системные вызовы: fanotify_init(2), fanotify_mark(2), read(2), write(2) и close(2).

### Вызовы fanotify_init(), fanotify_mark() и группы уведомлений
Системный вызов fanotify_init(2) создаёт и инициализирует группу уведомления fanotify и возвращает указывающий на неё файловый дескриптор.

Группа уведомления fanotify — это внутренний объект ядра, в котором хранится список файлов, каталогов, файловых систем и точек монтирования, для которых должны создаваться события.

У каждой записи в группе уведомления fanotify есть две битовые маски: меток и игнорирования. В маске меток указывается для каких действий на файлами должны создаваться события. В маске игнорирования указывается для каких действий не должны создаваться события. Имея маски таких типов можно пометить файловую систему, точку монтирования или каталог для получения событий, и в тоже время игнорировать события для определённых объектов в этой точке монтирования или каталоге.

Системный вызов fanotify_mark(2) добавляет файл, каталог, файловую систему или точку монтирования в группу уведомления и задаёт какие события должны отслеживаться (или игнорироваться), или удаляет или изменяет нужную запись.

Возможное применение маски игнорирования — кэш файлов. Интересующие события для файлового кэша — изменение файла и закрытие. Для этого добавляем кэшируемый каталог или точку монтирования для приёма этих событий. После получения первого события об изменении файла, соответствующая запись кэша помечается как недействительная. Дальнейшие события об изменении файла нас не интересуют, пока файл не будет закрыт. Для этого событие об изменении можно добавить в маску игнорирования. При получении события о закрытии, событие об изменении можно удалить из маски игнорирования и запись файлового кэша можно обновить.

Записи в группе уведомления fanotify ссылаются на файл и каталог по номеру иноды (inode), а на точку монтирования — через ID монтирования. При переименовании или перемещении файла или каталога внутри той же точки монтирования соответствующая запись остаётся. Если файл или каталог удаляется или перемещается в другую точку монтирования, или если файловая система или точка монтирования размонтируется, то соответствующая запись удаляется.

### Очередь событий
Для возникающих событий с объектами файловой системы, которые отслеживаются группой уведомления, система fanotify генерирует события и помещает их в очередь. После этого события можно прочитать (с помощью read(2) и подобных) из файлового дескриптора fanotify, возвращённого fanotify_init(2).

Генерируется два типа событий: события уведомления и события доступа. Уведомляющие события просто информируют и не требуют действия от принявшего приложения, за исключением того, что файловый дескриптор, передаваемый в событии общего типа, должен быть закрыт. Закрытие файловых дескрипторов для каждого события применяется только приложениями, которые инициализировали fanotify без использования FAN_REPORT_FID (смотрите ниже). События доступа запрашивают получившее приложение о разрешении доступа к файлу. Для этих событий получатель должен написать ответ, давать ли доступ или нет.

Событие удаляется из очереди событий группы fanotify после прочтения. События доступа, которые были прочитаны, остаются во внутреннем списке группы fanotify до тех пор, пока решение о доступе не будет записано в файловый дескриптор fanotify, или файловый дескриптор fanotify не будет закрыт.

### Чтение событий fanotify
Вызов read(2) с файловым дескриптором, полученным от fanotify_init(2), блокирует выполнение (если не указан флаг FAN_NONBLOCK в вызове fanotify_init(2)) до тех пор, пока не произойдёт файловое событие или вызов не будет прерван сигналом (смотрите signal(7)).

При указании флага FAN_REPORT_FID в fanotify_init(2) структуры данных возвращаются слушателю событий в каждом событии. После успешного выполнения read(2) буфер чтения содержит одну или более следующих структур:

```
struct fanotify_event_metadata {

    __u32 event_len;

    __u8 vers;

    __u8 reserved;

    __u16 metadata_len;

    __aligned_u64 mask;

    __s32 fd;

    __s32 pid;
};
```

Если в fanotify_init(2) среди флагов указан и FAN_REPORT_FID, то вы также должны ожидать структуру после общей структуры fanotify_event_metadata в буфере чтения:

```
struct fanotify_event_info_fid {

    struct fanotify_event_info_header hdr;

    __kernel_fsid_t fsid;

    unsigned char file_handle[0];
};
```

Для увеличения производительности рекомендуется использовать буфер большого размера (например, 4096 байт) для того, чтобы получить несколько событий за один вызов read(2).

Возвращаемое read(2) значение — количество байт помещённых в буфер, или -1 в случае ошибки (но смотрите ДЕФЕКТЫ).

Поля структуры fanotify_event_metadata:

event_len

Длина данных текущего события и смещение на следующее событие в буфере. Без FAN_REPORT_FID значение event_len всегда равно FAN_EVENT_METADATA_LEN. С FAN_REPORT_FID значение event_len также включает идентификатор файла переменной длины.

vers

Номер версии структуры. Он должен сравниваться с FANOTIFY_METADATA_VERSION для проверки того, что структуры, возвращаемые во время выполнения, соответствуют структурам, определённым во время компиляция. В случае несоответствия приложение должно прекратить попытки использовать файловый дескриптор fanotify.

reserved

Не используется.

metadata_len

Длина структуры. Это поле было добавлено для облегчения реализации необязательных заголовков разных типов событий. В текущей реализации такие необязательные заголовки отсутствуют.

mask

Битовая маска, описывающая событие (смотрите далее).

fd

Открытый файловый дескриптор объекта доступа или FAN_NOFD, если возникло переполнение очереди. Если файловый дескриптор fanotify инициализирован с использованием FAN_REPORT_FID,то приложения должны ожидать, что это значение равно FAN_NOFD у каждого полученного события. Файловый дескриптор можно использовать для доступа к содержимому отслеживаемого файла или каталога. Читающее приложение ответственно за закрытие этого файлового дескриптора.

Когда вызывается fanotify_init(2) вызывающий может указать (в аргументе event_f_flags) различные флаги состояния файла, которые будут установлены на открытом файловом дескрипторе, соответствующем этому файловому дескриптору. Также, на отрываемом файловом дескрипторе устанавливается (внутри ядра) флаг состояния файла FMODE_NONOTIFY. Этот флаг подавляет генерацию событий fanotify. Таким образом, когда получатель события fanotify обратится к отслеживаемому файлу или каталогу через этот файловый дескриптор, дополнительных событий создано не будет.

pid

Если в fanotify_init(2) установлен флаг FAN_REPORT_TID, то это TID нити, из-за которой возникло событие. В противном случае это PID процесса, из-за которой возникло событие.

Программа, слушающая события fanotify, может сравнить этот PID с PID, возвращаемым getpid(2), для проверки, что событие не возникло из-за самого слушающего, а из-за доступа к файлу другого процесса.

В битовой маске mask указывают события, произошедшие с одиночным объектом файловой системы. В маске может быть установлено несколько бит, если было более одного события с отслеживаемым объектом файловой системы. В частности, возникшие друг за другом события с одним объектом файловой системы и произошедшие из-за одного процесса могут быть объединены в одно событие, за исключением того, что два события доступа никогда не объединяются в одном элементе очереди.

Биты маски mask:

FAN_ACCESS

Доступ (на чтение) к файлу или каталогу (но смотрите ДЕФЕКТЫ).

FAN_OPEN

Файл или каталог открыт.

FAN_OPEN_EXEC

Файл открыт для выполнения. Смотрите ЗАМЕЧАНИЯ в fanotify_mark(2).

FAN_ATTRIB

Метаданные файла или каталога изменены.

FAN_CREATE

Создан дочерний файл или каталог в отслеживаемом родителе.

FAN_DELETE

Удалён дочерний файл или каталог в отслеживаемом родителе.

FAN_DELETE_SELF

Отслеживаемый файл или каталог был удалён.

FAN_MOVED_FROM

Дочерний файл или каталог был перемещён из отслеживаемого родительского каталога.

FAN_MOVED_TO

Дочерний файл или каталог был помещён в отслеживаемый родительский каталог.

FAN_MOVE_SELF

Отслеживаемый файл или каталог был перемещён.

FAN_MODIFY

Файл изменён.

FAN_CLOSE_WRITE

Файл, открытый на запись (O_WRONLY или O_RDWR), закрыт.

FAN_CLOSE_NOWRITE

Файл или каталог, открытый только для чтения (O_RDONLY), закрыт.

FAN_Q_OVERFLOW

Очередь событий превысила ограничение в 16384 записи. Это ограничение можно изменить, указав флаг FAN_UNLIMITED_QUEUE при вызове fanotify_init(2).

FAN_ACCESS_PERM

Приложение хочет прочитать файл или каталог, например, с помощью read(2) или readdir(2). Читатель события должен написать ответ (описано далее) о разрешении доступа к объекту файловой системы.

FAN_OPEN_PERM

Приложение хочет открыть файл или каталог. Читатель события должен написать ответ о разрешении открытия объекта файловой системы.

FAN_OPEN_EXEC_PERM

Приложение хочет открыть файл для выполнения. Читатель должен написать ответ о разрешении открытия объекта файловой системы для выполнения. Смотрите ЗАМЕЧАНИЯ в fanotify_mark(2).

Для проверки любого события закрытия может использоваться следующая битовая маска:

FAN_CLOSE

Файл закрыт. Это синоним:

FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE

Для проверки любого события перемещения может использоваться следующая битовая маска:

FAN_MOVE

Файл или каталог был перемещён. Это синоним для:

FAN_MOVED_FROM | FAN_MOVED_TO

Поля структуры fanotify_event_info_fid:

hdr

Структура типа fanotify_event_info_header. Это общий заголовок, содержащий информацию для описания дополнительной информации, присоединяемой к событию. Например, когда файловый дескриптор fanotify создан с использованием FAN_REPORT_FID, поле info_type этого заголовка равно FAN_EVENT_INFO_TYPE_FID. Слушатели события могут использовать это поле для проверки того, что полученная дополнительная информация о событии имеет правильный тип. Также fanotify_event_info_header содержит поле len. В текущей реализации значение len всегда равно (event_len - FAN_EVENT_METADATA_LEN).

fsid

Уникальный идентификатор файловой системы, содержащей объект, связанный с событием. Это структура имеет тип __kernel_fsid_t и содержит те же значения что и f_fsid при вызове statfs(2).

file_handle

Структура переменной длины, имеет тип file_handle. Это закрытый описатель, который соответствует заданному объекту файловой системы, возвращается name_to_handle_at(2). Её можно использовать как уникально определяемую файл в файловой системе и передавать аргументом в open_by_handle_at(2). Заметим, что для событий элементов каталога, таких как FAN_CREATE, FAN_DELETE, и FAN_MOVE, значение file_handle описывает изменяемый каталог, а не созданный/удалённый/перемещённый дочерний объект. События FAN_ATTRIB, FAN_DELETE_SELF и FAN_MOVE_SELF будут содержать информацию file_handle о дочернем объекте, если дочерний объект отслеживается.

Следующие макросы позволяют обходить буфер с метаданными событий fanotify, возвращаемый read(2) из файлового дескриптора fanotify:

FAN_EVENT_OK(meta, len)

Этот макрос сверяет оставшуюся длину len буфера meta с длиной структуры метаданных и полем event_len из первой структуры метаданных в буфере.

FAN_EVENT_NEXT(meta, len)

Этот макрос использует длину из поля event_len структуры метаданных, на которую указывает meta, для вычисления адреса следующей структуры метаданных, которая находится после meta. В поле len указано количество байт метаданных, оставшихся в буфере. Макрос возвращает указатель на следующую структуру метаданных после meta и уменьшает len на количество байт в структуре метаданных, которая была пропущена (т. е., вычитает meta->event_len из len).

Дополнительно есть:

FAN_EVENT_METADATA_LEN

Этот макрос возвращает размер (в байтах) структуры fanotify_event_metadata. Это минимальный размер (и, в настоящее время, единственный) метаданных любого события.

### Отслеживание событий через файловый дескриптор fanotify
Когда возникает событие fanotify файловый дескриптор fanotify помечается как доступный для чтения при его передаче в epoll(7), poll(2) или select(2).

### Работа с событиями доступа
Для событий доступа приложение должно записать (write(2)) в файловый дескриптор fanotify следующую структуру:

```
struct fanotify_response {

    __s32 fd;

    __u32 response;
};
```

Поля этой структуры имеют следующее назначение:

fd

Файловый дескриптор из структуры fanotify_event_metadata.

response

В этом поле указывает о разрешении доступа или запрещении. Данное значение должно быть равно FAN_ALLOW, чтобы разрешить операцию с файлом, или FAN_DENY для запрета.

Если доступ запрещается, то запрашивающее приложение получит ошибку EPERM.

### Закрытие файлового дескриптора fanotify
Когда все файловые дескрипторы, указывающие на группу уведомления fanotify, закрыты, группа fanotify освобождается и её ресурсы становятся доступны ядру для повторного использования. После close(2) все оставшиеся непросмотренные события доступа будут разрешены.

### /proc/[pid]/fdinfo
Файл /proc/[pid]/fdinfo/[fd] содержит информацию о метках fanotify для файлового дескриптора fd процесса pid Подробности смотрите в proc(5).

## ОШИБКИ
Кроме обычных ошибок read(2) при чтении из файлового дескриптора fanotify могут возникать следующие ошибки:

EINVAL

Буфер слишком мал для хранения события.

EMFILE

Достигнуто максимальное попроцессное количество открытых файлов. Смотрите описание RLIMIT_NOFILE в getrlimit(2).

ENFILE

Достигнут предел на общее количество открытых файлов в системе. Смотрите /proc/sys/fs/file-max в proc(5).

ETXTBSY

Эта ошибка возвращается read(2), если при вызове fanotify_init(2) в аргументе event_f_flags был указан O_RDWR или O_WRONLY и произошло событие с отслеживаемым файлом, который в данный момент выполняется.

Кроме обычных ошибок write(2) при записи в файловый дескриптор fanotify могут возникать следующие ошибки:

EINVAL

Свойство для проверки прав доступа fanotify не включено в настройках ядра или некорректное значение response в структуре ответа.

ENOENT

Некорректный файловый дескриптор fd в структуре ответа. Это может происходить, когда ответ на право доступа уже был записан.

## ВЕРСИИ
Программный интерфейс fanotify представлен в версии 2.6.36 ядра Linux и включён в версии 2.6.37. Поддержка fdinfo была добавлена в версии 3.8.

## СООТВЕТСТВИЕ СТАНДАРТАМ
Программный интерфейс fanotify есть только в Linux.

## ЗАМЕЧАНИЯ
Программный интерфейс fanotify доступен только, если ядро собрано с включённым параметром настройки CONFIG_FANOTIFY. Также, работа с доступом в fanotify доступна только, если включён параметр настройки CONFIG_FANOTIFY_ACCESS_PERMISSIONS.

### Ограничения и подводные камни
Fanotify сообщает только о событиях, которые возникли при использовании пользовательскими программами программного интерфейса файловой системы. Поэтому события об обращении к файлам в сетевых файловых системах не отлавливаются.

Программный интерфейс fanotify не сообщает о доступе и изменениях, которые могут произойти из-за mmap(2), msync(2) и munmap(2).

События для каталогов создаются только, если сам каталог открывается, читается и закрывается. Добавление, удаление и изменение потомков отслеживаемого каталога не приводит к возникновению событий.

Fanotify не следит за каталогами рекурсивно: чтобы следить за подкаталогами каталога, нужно их явно пометить (и, заметим, что программный интерфейс fanotify не позволяет отслеживать создание подкаталога, что затрудняет рекурсивное слежение). Отслеживание точек монтирования позволяет следить за всем деревом каталогов. Отслеживание файловых систем позволяет следить за изменениями, сделанными в любом смонтированном экземпляре файловой системы.

Очередь событий может переполниться. В этом случае события теряются.

## ДЕФЕКТЫ
До Linux 3.19, fallocate(2) не генерировал событий fanotify. Начиная с Linux 3.19, вызовы fallocate(2) генерируют событие FAN_MODIFY.

В Linux 3.17 существуют следующие дефекты:

- В Linux объект файловой системы может быть доступен через несколько путей, например, часть файловой системы может быть перемонтирована mount(8) с использованием параметра --bind. Ожидающий слушатель получит уведомления об объекте файловой системы только из запрошенной точки монтирования. О событиях из других точек уведомлений не поступит.

- При генерации события не делается проверка, что пользовательскому ID получающего процесса разрешено читать или писать в файл перед передачей файлового дескриптора на этот файл. Это представляет некоторый риск безопасности, когда у программ, выполняющихся непривилегированными пользователями, есть мандат CAP_SYS_ADMIN.

- Если вызов read(2) получает несколько событий из очереди fanotify и возникает ошибка, будет возвращена полная длина событий, которые были успешно скопированы в буфер пользовательского пространства до ошибки. Возвращаемое значение не будет равно -1, и в errno не записывается код ошибки. То есть читающее приложение не может обнаружить ошибку.

## ПРИМЕР
Далее показано два примера программы, в которых продемонстрированоиспользование программного интерфейса fanotify.

### Программа-пример: fanotify_example.c
В первой программе показано как использовать fanotify с информацией об событийном объекте, передаваемом в виде файлового дескриптора. Программа помечает точку монтирования, переданную в аргументе командной строки, и ждёт событий с типом FAN_OPEN_PERM и FAN_CLOSE_WRITE. При возникновении событий доступа выдаёт ответ FAN_ALLOW.

В сеансе оболочки далее показан пример запуска программы. В сеансе выполняется редактирование файла /home/user/temp/notes. Перед открытием файла возникает событие FAN_OPEN_PERM. После закрытия файла возникает событие FAN_CLOSE_WRITE. Выполнение программы заканчивается после нажатия пользователем клавиши ENTER.

```
# ./fanotify_example /home
Нажмите enter для завершения работы.
Ожидание событий.
FAN_OPEN_PERM: Файл /home/user/temp/notes
FAN_CLOSE_WRITE: Файл /home/user/temp/notes
Ожидание событий прекращено.
```

### Исходный код программы: fanotify_example.c

```
#define _GNU_SOURCE     /* для получения определения O_LARGEFILE */
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/fanotify.h>
#include <unistd.h>
/* читаем все доступные события fanotify из файлового дескриптора «fd» */
static void
handle_events(int fd)
{

    const struct fanotify_event_metadata *metadata;

    struct fanotify_event_metadata buf[200];

    ssize_t len;

    char path[PATH_MAX];

    ssize_t path_len;

    char procfd_path[PATH_MAX];

    struct fanotify_response response;

    /* проходим по всем событиям, которые можем прочитать

       из файлового дескриптора fanotify */

    for (;;) {

        /* читаем несколько событий */

        len = read(fd, (void *) &buf, sizeof(buf));

        if (len == -1 && errno != EAGAIN) {

            perror("read");

            exit(EXIT_FAILURE);

        }

        /* проверяем, достигнут ли конец доступных данных */

        if (len <= 0)

            break;

        /* выбираем первое событие в буфере */

        metadata = buf;

        /* проходим по всем событиям в буфере */

        while (FAN_EVENT_OK(metadata, len)) {

            /* проверяем, что структуры, использовавшиеся при сборке,

               идентичны структурам при выполнении */

            if (metadata->vers != FANOTIFY_METADATA_VERSION) {

                fprintf(stderr,

                        "Версия метаданных fanotify не совпадает.\n");

                exit(EXIT_FAILURE);

            }

            /* metadata->fd содержит или FAN_NOFD, указывающее

               на переполнение очереди, или файловый дескриптор

               (неотрицательное целое). Здесь мы просто игнорируем

               переполнение очереди. */

            if (metadata->fd >= 0) {

                /* обрабатываем событие на право открытия */

                if (metadata->mask & FAN_OPEN_PERM) {

                    printf("FAN_OPEN_PERM: ");

                    /* разрешаем открыть файл */

                    response.fd = metadata->fd;

                    response.response = FAN_ALLOW;

                    write(fd, &response,

                          sizeof(struct fanotify_response));

                }

                /* обрабатываем событие закрытия записываемого файла */

                if (metadata->mask & FAN_CLOSE_WRITE)

                    printf("FAN_CLOSE_WRITE: ");

                /* получаем и выводим имя файла, к которому

                   отслеживается доступ */

                snprintf(procfd_path, sizeof(procfd_path),

                         "/proc/self/fd/%d", metadata->fd);

                path_len = readlink(procfd_path, path,

                                    sizeof(path) - 1);

                if (path_len == -1) {

                    perror("readlink");

                    exit(EXIT_FAILURE);

                }

                path[path_len] = '\0';

                printf("Файл %s\n", path);

                /* закрываем файловый дескриптор из события */

                close(metadata->fd);

            }

            /* переходим на следующее событие */

            metadata = FAN_EVENT_NEXT(metadata, len);

        }

    }
}
int
main(int argc, char *argv[])
{

    char buf;

    int fd, poll_num;

    nfds_t nfds;

    struct pollfd fds[2];

    /* проверяем заданную точку монтирования */

    if (argc != 2) {

        fprintf(stderr, "Использование: %s ТОЧКА_МОНТИРОВАНИЯ\n",

                                        argv[0]);

        exit(EXIT_FAILURE);

    }

    printf("Нажмите enter для завершения работы.\n");

    /* Создаём файловый дескриптор для доступа к fanotify API */

    fd = fanotify_init(FAN_CLOEXEC | FAN_CLASS_CONTENT | FAN_NONBLOCK,

                       O_RDONLY | O_LARGEFILE);

    if (fd == -1) {

        perror("fanotify_init");

        exit(EXIT_FAILURE);

    }

    /* Помечаем точку монтирования для:

       - событий доступа перед открытием файлов

       - событий уведомления после закрытия файлового дескриптора

         для файла открытого для записи */

    if (fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_MOUNT,

                      FAN_OPEN_PERM | FAN_CLOSE_WRITE, AT_FDCWD,

                      argv[1]) == -1) {

        perror("fanotify_mark");

        exit(EXIT_FAILURE);

    }

    /* подготовка к опросу */

    nfds = 2;

    /* ввод с консоли  */

    fds[0].fd = STDIN_FILENO;

    fds[0].events = POLLIN;

    /* ввод из fanotify */

    fds[1].fd = fd;

    fds[1].events = POLLIN;

    /* цикл ожидания входящих событий */

    printf("Ожидание событий.\n");

    while (1) {

        poll_num = poll(fds, nfds, -1);

        if (poll_num == -1) {

            if (errno == EINTR)     /* прервано сигналом */

                continue;           /* перезапуск poll() */

            perror("poll");         /* неожиданная ошибка */

            exit(EXIT_FAILURE);

        }

        if (poll_num > 0) {

            if (fds[0].revents & POLLIN) {

                /* доступен ввод с консоли: опустошаем stdin и выходим */

                while (read(STDIN_FILENO, &buf, 1) > 0 && buf != '\n')

                    continue;

                break;

            }

            if (fds[1].revents & POLLIN) {

                /* доступны события fanotify */

                handle_events(fd);

            }

        }

    }

    printf("Ожидание событий прекращено.\n");

    exit(EXIT_SUCCESS);
}
```

### Программа-пример: fanotify_fid.c
Во второй программе показано как использовать fanotify с включённым FAN_REPORT_FID. Программа помечает объект файловой системы, переданный в аргументе командной строки, и ждёт возникновения события с типом FAN_CREATE. В маске событий задаётся какой тип объекта файловой системы ждать — файл или каталог. После того как все события из буфера будут прочитаны и правильно обработаны программа просто завершает работу.

В следующих сеансах показано два разных запуска программы с разными выполняемыми действиями над наблюдаемым объектом.

В первом сеансе ставится отметка на /home/user. После этого создаётся обычный файл /home/user/testfile.txt. В результате возникает событие FAN_CREATE, в котором передаётсяобъект отслеживаемого родительского каталога файла. Программа завершает выполнение после обработки всех захваченных и помещённых в буфер событий.

```
# ./fanotify_fid /home/user
Ожидание событий.
FAN_CREATE (создан файл): Каталог /home/user изменён.
Все события успешно обработаны. Завершение программы.
$ touch /home/user/testing              # в другом терминале
```

Во втором сеансе ставится отметка на /home/user. После этого создаётся каталог /home/user/testdir. В результате такого специального действия в программу передаются события FAN_CREATE и FAN_ONDIR.

```
# ./fanotify_fid /home/user
Ожидание событий.
FAN_CREATE | FAN_ONDIR (создан подкаталог):

        Каталог /home/user изменён.
Все события успешно обработаны. Завершение программы.
$ mkdir -p /home/user/testing          # в другом терминале
```

### Исходный код программы: fanotify_fid.c

```
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fanotify.h>
#include <unistd.h>
#define BUF_SIZE 256
int
main(int argc, char **argv)
{

    int fd, ret, event_fd;

    ssize_t len, path_len;

    char path[PATH_MAX];

    char procfd_path[PATH_MAX];

    char events_buf[BUF_SIZE];

    struct file_handle *file_handle;

    struct fanotify_event_metadata *metadata;

    struct fanotify_event_info_fid *fid;

    if (argc != 2) {

        fprintf(stderr, "Некорректное количество аргументов в командной строке.\n");

        exit(EXIT_FAILURE);

    }

    /* создаём файловый дескриптор fanotify с флагом FAN_REPORT_FID для

       того, чтобы программа могла принимать события fid. */

    fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_FID, 0);

    if (fd == -1) {

        perror("fanotify_init");

        exit(EXIT_FAILURE);

    }

    /* ставим метку на объект файловой системы, заданный в argv[1]. */

    ret = fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_ONLYDIR,

                        FAN_CREATE | FAN_ONDIR,

                        AT_FDCWD, argv[1]);

    if (ret == -1) {

        perror("fanotify_mark");

        exit(EXIT_FAILURE);

    }

    printf("Ожидание событий.\n");

    /* читаем события из очереди событий в буфер */

    len = read(fd, (void *) &events_buf, sizeof(events_buf));

    if (len == -1 && errno != EAGAIN) {

        perror("read");

        exit(EXIT_FAILURE);

    }

    /* обрабатываем все события в буфере */

    for (metadata = (struct fanotify_event_metadata *) events_buf;

            FAN_EVENT_OK(metadata, len);

            metadata = FAN_EVENT_NEXT(metadata, len)) {

        fid = (struct fanotify_event_info_fid *) (metadata + 1);

        file_handle = (struct file_handle *) fid->handle;

        /* проверим, что информация о событии правильного типа */

        if (fid->hdr.info_type != FAN_EVENT_INFO_TYPE_FID) {

            fprintf(stderr, "Получена информация о событии неожидаемого типа.\n");

            exit(EXIT_FAILURE);

        }

        if (metadata->mask == FAN_CREATE)

            printf("FAN_CREATE (создан файл):");

        if (metadata->mask == FAN_CREATE | FAN_ONDIR)

            printf("FAN_CREATE | FAN_ONDIR (создан подкаталог):");

        /* metadata->fd присваивается FAN_NOFD, если включён

           FAN_REPORT_FID. Чтобы получить файловый дескриптор для

           файлового объекта, соответствующего событию, можно

           использовать struct file_handle, которая находится

           внутри fanotify_event_info_fid и системный вызов

           open_by_handle_at(2). Проверка на ESTALE нужна, чтобы

           учесть ситуацию, когда файловый описатель для объекта

           был удалён до этого системного вызова. */

        event_fd = open_by_handle_at(AT_FDCWD, file_handle, O_RDONLY);

        if (ret == -1) {

            if (errno == ESTALE) {

                printf("Обработчик файл более недействителен. "

                        "Файл был удалён\n");

                continue;

            } else {

                perror("open_by_handle_at");

                exit(EXIT_FAILURE);
	    }

        }

        snprintf(procfd_path, sizeof(procfd_path), "/proc/self/fd/%d",

                event_fd);

        /* получаем и выводим путь изменённой dentry */

        path_len = readlink(procfd_path, path, sizeof(path) - 1);

        if (path_len == -1) {

            perror("readlink");

            exit(EXIT_FAILURE);

        }

        path[path_len] = '\0';

        printf("\tКаталог '%s' изменён.\n", path);

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

        close(event_fd);

    }

    printf("Все события успешно обработаны. Завершение программы.\n");

    exit(EXIT_SUCCESS);
}
```

## СМОТРИТЕ ТАКЖЕ
fanotify_init(2), fanotify_mark(2), inotify(7)


package: man-pages-ru

title: feature_test_macros(7)

summary: макросы тестирования свойств

text:
# feature_test_macros(7)

## ИМЯ
feature_test_macros - макросы тестирования свойств

## ОПИСАНИЕ
Макросы тестирования свойств позволяют программисту контролировать какие определения будут доступны из системных заголовочных файлов при компиляции программы.

ЗАМЕЧАНИЕ: В целях эффективности, макрос тестирования свойств должен быть определён до включения всех заголовочных файлов. Это можно сделать или в команде компиляции (cc -DМАКРОС=значение) или определив макрос в исходном коде до включения заголовочных файлов. Требование включения макроса раньше остальных заголовочных файлов возникло из-за того, что заголовочные файлы могут включаться друг в друга в любой последовательности. Например, в следующих строках определение макроса _GNU_SOURCE может не сработать, так как заголовок <abc.h> сам включает <xyz.h> (в POSIX это разрешается явным образом):

```
#include <abc.h>
#define _GNU_SOURCE
#include <xys.h>
```

Некоторые макросы тестирования свойств полезны для создания переносимых приложений; они позволяют блокировать нестандартные определения. Другие макросы можно использовать для разблокировки нестандартных определений, которые по умолчанию недоступны.

Действие каждого макроса тестирования свойств, описанного далее, можно узнать из содержимого заголовочного файла <features.h>. Замечание: в приложениях не нужно явно включать <features.h> — это не приветствуется. Смотрите ЗАМЕЧАНИЯ.

### Обозначение макросов тестирования свойств в справочных страницах
Когда функции требуется определение макроса тестирования свойств в ОБЗОРЕ справочной страницы, обычно, содержится упоминание в следующем виде (этот пример взят из справочной страницы acct(2)):

\#include <unistd.h> int acct(const char *filename);

```
Требования макроса тестирования свойств для glibc
(см. feature_test_macros(7)):
```

acct(): _BSD_SOURCE || (_XOPEN_SOURCE && _XOPEN_SOURCE < 500)

Символ || означает, что для получения объявления acct(2) из <unistd.h> нужно определить любой из следующих макросов до включения любых заголовочных файлов:

```
#define _BSD_SOURCE
#define _XOPEN_SOURCE        /* или любое значение < 500 */
```

Или же эквивалентные определения могут быть включены следующей командой компиляции:

```
cc -D_BSD_SOURCE
cc -D_XOPEN_SOURCE           # или любое значение < 500
```

Как описывается далее, некоторые макросы тестирования свойств определяются по умолчанию, поэтому макрос не всегда нужно указывать явно даже, если он приведён в ОБЗОРЕ.

В некоторых случаях в справочных страницах используется сокращённая запись требований макросов тестирования свойств (пример из readahead(2)):

```
#define _GNU_SOURCE
#include <fcntl.h>
```

```
ssize_t readahead(int fd, off64_t *offset, size_t count);
```

Такой формат употребляется в случаях, когда достаточно одного макроса для получения объявления функции, и этот макрос не определён по умолчанию.

### Макросы тестирования свойств, распознаваемые glibc
В следующих параграфах описаны макросы тестирования свойств, управляющие Linux glibc 2.x, где x > 0.

Если кратко:

- Макросы, которые вам, вероятно, понадобится использовать в современном коде: _POSIX_C_SOURCE (определения из различных версий POSIX.1), _XOPEN_SOURCE (определения из различных версий SUS), _GNU_SOURCE (специальные возможности GNU и/или Linux) и _DEFAULT_SOURCE (определения, которые, обычно, включены по умолчанию).

- Некоторые макросы определяют значения по умолчанию. То есть, хотя один или более макросов могут быть указаны как необходимые в ОБЗОР справочной страницы, возможно необязательно определять их явно. Полное описание значений по умолчанию приведены далее в этой справочной странице.

- Определение _XOPEN_SOURCE со значением 600 и более даёт тот же эффект что и определение _POSIX_C_SOURCE со значением 200112L и больше. Если требуется

```
_POSIX_C_SOURCE >= 200112L

```

в макросах тестирования свойств ОБЗОРА справочной страницы, то это неявным образом тоже что и:

```
_XOPEN_SOURCE >= 600

```

*

Определение _XOPEN_SOURCE со значением 700 и более даёт тот же эффект что и определение _POSIX_C_SOURCE со значением 200809L и больше. Если требуется

```
_POSIX_C_SOURCE >= 200809L

```

в макросах тестирования свойств ОБЗОРА справочной страницы, то это неявным образом тоже что и:

```
_XOPEN_SOURCE >= 700

```

В Linux glibc распознаются следующие макросы тестирования свойств:

__STRICT_ANSI__

Стандарт ISO C. Этот макрос неявно определяется компилятором gcc(1), если он вызывается с флагом -std=c99 или -ansi.

_POSIX_C_SOURCE

При определении этого макроса из заголовочных файлов становится доступно следующее:

- При значении 1 доступны определения, удовлетворяющие POSIX.1-1990 и ISO C (1990).

- При значении 2 и более дополнительно доступны определения, удовлетворяющие POSIX.2-1992.

- При значении 199309L и более дополнительно доступны определения, удовлетворяющие POSIX.1b (расширения для реального времени).

- При значении 199506L и более дополнительно доступны определения, удовлетворяющие POSIX.1c (нити).

- (начиная с glibc 2.3.3) При значении 200112L и более доступны определения, удовлетворяющие базовой спецификации POSIX.1-2001 (за исключением расширения XSI) а также свойства C95 (начиная с glibc 2.12) и C99 (начиная с glibc 2.10). Другими словами это эквивалент определения _ISOC99_SOURCE.

- (начиная с glibc 2.10) При значении 200809L и более доступны определения, удовлетворяющие базовой спецификации POSIX.1-2008 (за исключением расширения XSI).

_POSIX_SOURCE

Определение этого устаревшего макроса с любым значением эквивалентно определению _POSIX_C_SOURCE со значением 1.

Так как этот макрос устарел, его использование, обычно, не описывается при обсуждении требований макросов тестирования свойств в справочной странице.

_XOPEN_SOURCE

При определении этого макроса из заголовочных файлов становится доступно следующее:

- Определение с любым значением делает доступным определения, удовлетворяющие POSIX.1, POSIX.2 и XPG4.

- При значении 500 и более дополнительно доступны определения, удовлетворяющие SUSv2 (UNIX 98).

- (начиная с glibc 2.2) При значении 600L и более дополнительно доступны определения, удовлетворяющие SUSv3 (UNIX 03; т. е., базовой спецификации POSIX.1-2001 плюс расширение XSI), и определения C99.

- (начиная с glibc 2.10) При значении 700 и более дополнительно доступны определения, удовлетворяющие SUSv4 (т. е., базовой спецификации POSIX.1-2008 плюс расширение XSI).

If __STRICT_ANSI__ не определено или определено _XOPEN_SOURCE со значением больше или равно 500 и явно не определено _POSIX_SOURCE или _POSIX_C_SOURCE, то неявно определяются следующие макросы:

- _POSIX_SOURCE определяется со значением 1.

- _POSIX_C_SOURCE определяется согласно значению _XOPEN_SOURCE:

_XOPEN_SOURCE < 500

_POSIX_C_SOURCE определяется со значением 2.

500 <= _XOPEN_SOURCE < 600

_POSIX_C_SOURCE определяется со значением 199506L.

600 <= _XOPEN_SOURCE < 700

_POSIX_C_SOURCE определяется со значением 200112L.

700 <= _XOPEN_SOURCE (начиная с glibc 2.10)

_POSIX_C_SOURCE определяется со значением 200809L.

Также, определение _XOPEN_SOURCE со значением 500 и более даёт тот же эффект что и определение _XOPEN_SOURCE_EXTENDED.

_XOPEN_SOURCE_EXTENDED

Если этот макрос определён вместе с _XOPEN_SOURCE, то доступны определения, соответствующие расширениям UNIX (UNIX 95) XPG4v2 (SUSv1). Определение _XOPEN_SOURCE со значением 500 и более также вызывает эффект, подобный _XOPEN_SOURCE_EXTENDED. Использование _XOPEN_SOURCE_EXTENDED в новом коде следует избегать.

Так как определение _XOPEN_SOURCE со значением 500 и более даёт тот же эффект, что и _XOPEN_SOURCE_EXTENDED, последний (устаревший) макрос тестирования свойств, обычно, не описывается в ОБЗОРЕ справочной страницы.

_ISOC99_SOURCE (начиная с glibc 2.1.3)

Делает доступными объявления, удовлетворяющие требованиям стандарта ISO C99.

Ранние версии glibc 2.1.x распознавали макрос-эквивалент _ISOC9X_SOURCE (так как стандарт C99 ещё не был утверждён). Хотя использование последнего макроса не рекомендуется, glibc пока поддерживает его для обратной совместимости.

Делает доступными определения стандарта ISO C (1990) Amendment 1 («C95»). Основным изменением в C95 была поддержка международных наборов символов.

Вызов компилятора C с параметром -std=c99 работает также как если был бы указан этот макрос.

_ISOC11_SOURCE (начиная с glibc 2.16)

Делает доступными объявления, удовлетворяющие требованиям стандарта ISO C11. Определение этого макроса также включает свойства C99 и C95 (подобно _ISOC99_SOURCE).

Вызов компилятора C с параметром -std=c11 работает также как если был бы указан этот макрос.

_LARGEFILE64_SOURCE

Делает доступными объявления альтернативного программного интерфейса, определяемого в LFS (Large File Summit) как «переходного расширение» на Single UNIX Specification (смотрите программный интерфейс состоит из набора новых объектов (т. е., функций и типов), чьи имена оканчиваются на «»64 (например, off64_t и off_t, lseek64() и lseek(), и т. д.). В новых программах не нужно указывать этот макрос; вместо него указывайте _FILE_OFFSET_BITS=64. _LARGEFILE_SOURCE

Данный макрос исторически используется для предоставления определённых функций (в частности, fseeko(3) и ftello(3)), которые обходят адресные ограничения раннего программного интерфейса (fseek(3) и ftell(3)), в котором для файловых смещений использовался long int. Данный макрос неявно определяется, если определён _XOPEN_SOURCE со значением больше или равным 500. В новых программах не нужно определять данный макрос; определение _XOPEN_SOURCE или _FILE_OFFSET_BITS со значением 64 является более предпочтительным механизмом для достижения того же результата.

_FILE_OFFSET_BITS

При определении данного макроса со значением 64 ссылки на 32-битные функции и типы данных, относящиеся к файловому вводу-выводу и операциям с файловой системой, автоматически преобразуются в их 64-битные прототипы. Это полезно для выполнения ввода-вывода в огромные файлы (> 2 гигабайт) на 32-битных системах (определение данного макроса позволяет корректно написанным программам использовать огромные файлы, для чего требуется только перекомпиляция).

64-битные системы сразу позволяют работать с файлами размером больше 2 гигабайт, и на этих системах данный макрос ничего не делает.

_BSD_SOURCE (устарел начиная с glibc 2.20)

Определение данного макроса с любым значением приводит к доступности из заголовочных файлов определений BSD.

В glibc до версии 2.18 включительно при определении данного макроса также отдаётся приоритет определениям BSD в ситуациях, когда имеется конфликт со стандартами. Если определён один из макросов _SVID_SOURCE, _POSIX_SOURCE, _POSIX_C_SOURCE, _XOPEN_SOURCE, _XOPEN_SOURCE_EXTENDED или _GNU_SOURCE, то определения BSD не используются. Начиная с glibc 2.19 при наличии макроса _BSD_SOURCE определения BSD в случае конфликта приоритета не имеют.

Начиная с glibc 2.20 этот макрос считается устаревшим. Теперь он действует также как определение _DEFAULT_SOURCE, но при компиляции генерируется предупреждение (если также не определён _DEFAULT_SOURCE). Используйте _DEFAULT_SOURCE вместо него. Чтобы для кода, которому требуется _BSD_SOURCE в glibc 2.19 и старее и _DEFAULT_SOURCE в glibc 2.20 и новее, не выдавалось предупреждение при компиляции определите _BSD_SOURCE и _DEFAULT_SOURCE одновременно.

_SVID_SOURCE (устарел начиная с glibc 2.20)

При определении этого макроса с любым значением из заголовочных файлов становятся доступны определения System V (SVID == System V Interface Definition; смотрите standards(7)).

Начиная с glibc 2.20 этот макрос устарел также как _BSD_SOURCE.

_DEFAULT_SOURCE (начиная с glibc 2.19)

Данный макрос можно определить, чтобы точно знать, что будут доступны определения «по умолчанию» даже, если умолчательные макросы отключены, что случается, когда отдельные макросы определяются явно, или компилятор вызывается в одном из своих «стандартных» режимов (например, cc -std=c99). Определение _DEFAULT_SOURCE без определения отдельных макросов или вызов компилятора в одном из его «стандартных» режимов не работают.

Определения «по умолчанию» охватывают все, которые требуются POSIX.1-2008 и ISO C99, а также различные определения появившиеся из BSD и System V. В glibc 2.19 и старее эти значения по умолчанию приблизительно эквивалентны явному определению следующего:

cc -D_BSD_SOURCE -D_SVID_SOURCE -D_POSIX_C_SOURCE=200809

_ATFILE_SOURCE (начиная с glibc 2.4)

При определении этого макроса с любым значением из заголовочных файлов становятся доступны объявления набора функций с суффиксом «at»; смотрите openat(2). Начиная с glibc 2.10 данный макрос также неявно определяется, если определён _POSIX_C_SOURCE со значением 200809L или больше.

_GNU_SOURCE

При определении этого макроса (с любым значением) неявно определяются _ATFILE_SOURCE, _LARGEFILE64_SOURCE, _ISOC99_SOURCE, _XOPEN_SOURCE_EXTENDED, _POSIX_SOURCE, _POSIX_C_SOURCE со значением 200809L (200112L в версиях glibc до 2.10; 199506L в версиях glibc до 2.5; 199309L в версиях glibc до 2.1) и _XOPEN_SOURCE со значением 700 (600 в версиях glibc до 2.10; 500 в версиях glibc до 2.2). Также становятся доступны различные расширения GNU.

Начиная с glibc 2.19 определение _GNU_SOURCE также неявно определяет _DEFAULT_SOURCE. В glibc до 2.20 версии определение _GNU_SOURCE также неявно определяет _BSD_SOURCE и _SVID_SOURCE.

_REENTRANT

В прошлом, этот макрос требовалось определять для различных библиотек C, чтобы работал многонитевой код (некоторым библиотекам C это всё ещё требуется). В glibc этот макрос также включает определения определённых реентерабельных функций.

Однако glibc уже давно по умолчанию безопасна для нитей; начиная glibc 2.3 единственным эффектом определения _REENTRANT является включение одного или двух определений, которые также включаются определением _POSIX_C_SOURCE со значением 199606L или больше.

В настоящий момент _REENTRANT устарел. В glibc 2.25 и новее определение _REENTRANT эквивалентно определению _POSIX_C_SOURCE со значением 199606L. Если выбирается более высокий уровень соответствия POSIX (например, самим _POSIX_C_SOURCE, _XOPEN_SOURCE, _DEFAULT_SOURCE или _GNU_SOURCE), то определение не действует _REENTRANT.

Данный макрос автоматически определяется, если выполняется компиляция cc -pthread.

_THREAD_SAFE

Синоним (устарел) _REENTRANT, предоставляется для совместимости с некоторыми другими реализациями.

_FORTIFY_SOURCE (начиная с glibc 2.3.4)

Определение этого макроса вызывает выполнение нескольких простых проверок для обнаружения ошибок переполнения буфера, которые возникают в различных функциях работы со строками и памятью (например, memcpy(3), memset(3), stpcpy(3), strcpy(3), strncpy(3), strcat(3), strncat(3), sprintf(3), snprintf(3), vsprintf(3), vsnprintf(3), gets(3) и их варианты для работы с широкими символами). Для некоторых функций проверяется целостность аргумента; например, проверяется, что open(2) передали в аргументе mode, если указан флаг O_CREAT. Обнаруживаются не все проблемы, только самые распространённые.

Если значение _FORTIFY_SOURCE равно 1 и уровень оптимизации компиляции равен 1 (gcc -O1) и больше, то выполняются проверки, которые не изменяют поведение выверяемых программ. Если значение _FORTIFY_SOURCE равно 2, то добавляются дополнительные проверки, но некоторые выверяемые программы могут завершаться с ошибкой.

Некоторые проверки выполняются во время компиляции (через макросы, реализованных в заголовочных файлах) и вызывают предупреждение компилятора; другие проверки выполняются во время выполнения и приводят к ошибкам времени выполнения.

Для работы этого макроса требуется поддержка в компиляторе, доступная в gcc(1) начиная с версии 4.0.

### Определения по умолчанию, неявные определения и объединяющие определения
Если макросы тестирования свойств не указаны явно, то по умолчанию действуют следующие макросы тестирования свойств: _BSD_SOURCE (в glibc 2.19 и старее), _SVID_SOURCE (в glibc 2.19 и старее), _DEFAULT_SOURCE (начиная с glibc 2.19), _POSIX_SOURCE и _POSIX_C_SOURCE=200809L (200112L в версиях glibc до 2.10; 199506L в версиях glibc до 2.4; 199309L в версиях glibc до 2.1).

Если любой из макросов __STRICT_ANSI__, _ISOC99_SOURCE, _POSIX_SOURCE, _POSIX_C_SOURCE, _XOPEN_SOURCE, _XOPEN_SOURCE_EXTENDED, _BSD_SOURCE (в glibc 2.19 и старее) или _SVID_SOURCE (в glibc 2.19 и старее) указан явно, то по умолчанию не определяются макросы _BSD_SOURCE, _SVID_SOURCE и _DEFAULT_SOURCE.

Если макросы _POSIX_SOURCE и _POSIX_C_SOURCE не указаны явно и не определён __STRICT_ANSI__ или _XOPEN_SOURCE определён со значением 500 или более, то

- _POSIX_SOURCE определяется со значением 1; и

- _POSIX_C_SOURCE определяется с одним из следующих значений:

- 2, если _XOPEN_SOURCE определён со значением меньше 500;

- 199506L, если _XOPEN_SOURCE определён со значением 500 или более, но меньше 600; или

- (начиная с glibc 2.4) 200112L, если _XOPEN_SOURCE определён со значением 600 или более, но меньше 700.

- (начиная с glibc 2.10) 200809L, если _XOPEN_SOURCE определён со значением 700 или более.

- Старые версии glibc не знают о значениях 200112L и 200809L у _POSIX_C_SOURCE, и значение этого макроса зависит от версии glibc.

- Если макрос _XOPEN_SOURCE не определён, то значение _POSIX_C_SOURCE зависит от версии glibc: 199506L в версиях glibc до 2.4; 200112L в glibc от 2.4 до 2.9 и 200809L в glibc 2.10 и новее.

Можно определять несколько макросов; результат складывается.

## СООТВЕТСТВИЕ СТАНДАРТАМ
В POSIX.1 определены _POSIX_C_SOURCE, _POSIX_SOURCE и _XOPEN_SOURCE.

Макрос _XOPEN_SOURCE_EXTENDED был определён в XPG4v2 (также называемом SUSv1), но отсутствует в SUSv2 и более новых версиях. Макрос _FILE_OFFSET_BITS отсутствует в стандартах, но используется в некоторых других реализациях.

Макросы _BSD_SOURCE, _SVID_SOURCE, _DEFAULT_SOURCE, _ATFILE_SOURCE, _GNU_SOURCE, _FORTIFY_SOURCE, _REENTRANT и _THREAD_SAFE есть только в Linux (glibc).

## ЗАМЕЧАНИЯ
Файл <features.h> есть только в Linux/glibc. В других системах есть аналогичный файл, но, обычно, с другим именем. Данный заголовочный файл, если нужен, автоматически включается из других заголовочных файлов: его необязательно явно указывать для использования макросов тестирования свойств.

Согласно указанным макросам тестирования свойств раньше файла <features.h>, внутри него определяются другие различные макросы, которые проверяются в других заголовочных файлах glibc. Эти макросы имеют имена, начинающиеся с двух подчёркиваний (например, __USE_MISC). Программы никогда не должны определять эти макросы самостоятельно: вместо этого нужно задействовать соответствующий макрос тестирования свойств из перечисленных ранее.

## ПРИМЕР
Представленную далее программу можно использовать для изучения какие значения присваиваются макросам тестирования свойств в зависимости от версии glibc и какие макросы тестирования свойств устанавливаются явно. В следующем сеансе оболочки на системе с glibc 2.10 показаны несколько примеров того, что мы увидели:

```
$ cc ftm.c
$ ./a.out
_POSIX_SOURCE defined
_POSIX_C_SOURCE defined: 200809L
_BSD_SOURCE defined
_SVID_SOURCE defined
_ATFILE_SOURCE defined
$ cc -D_XOPEN_SOURCE=500 ftm.c
$ ./a.out
_POSIX_SOURCE defined
_POSIX_C_SOURCE defined: 199506L
_XOPEN_SOURCE defined: 500
$ cc -D_GNU_SOURCE ftm.c
$ ./a.out
_POSIX_SOURCE defined
_POSIX_C_SOURCE defined: 200809L
_ISOC99_SOURCE defined
_XOPEN_SOURCE defined: 700
_XOPEN_SOURCE_EXTENDED defined
_LARGEFILE64_SOURCE defined
_BSD_SOURCE defined
_SVID_SOURCE defined
_ATFILE_SOURCE defined
_GNU_SOURCE defined
```

### Исходный код программы

```
/* ftm.c */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
#ifdef _POSIX_SOURCE

    printf("_POSIX_SOURCE defined\n");
#endif
#ifdef _POSIX_C_SOURCE

    printf("_POSIX_C_SOURCE defined: %ldL\n", (long) _POSIX_C_SOURCE);
#endif
#ifdef _ISOC99_SOURCE

    printf("_ISOC99_SOURCE defined\n");
#endif
#ifdef _ISOC11_SOURCE

    printf("_ISOC11_SOURCE defined\n");
#endif
#ifdef _XOPEN_SOURCE

    printf("_XOPEN_SOURCE defined: %d\n", _XOPEN_SOURCE);
#endif
#ifdef _XOPEN_SOURCE_EXTENDED

    printf("_XOPEN_SOURCE_EXTENDED defined\n");
#endif
#ifdef _LARGEFILE64_SOURCE

    printf("_LARGEFILE64_SOURCE defined\n");
#endif
#ifdef _FILE_OFFSET_BITS

    printf("_FILE_OFFSET_BITS defined: %d\n", _FILE_OFFSET_BITS);
#endif
#ifdef _BSD_SOURCE

    printf("_BSD_SOURCE defined\n");
#endif
#ifdef _SVID_SOURCE

    printf("_SVID_SOURCE defined\n");
#endif
#ifdef _DEFAULT_SOURCE

    printf("_DEFAULT_SOURCE defined\n");
#endif
#ifdef _ATFILE_SOURCE

    printf("_ATFILE_SOURCE defined\n");
#endif
#ifdef _GNU_SOURCE

    printf("_GNU_SOURCE defined\n");
#endif
#ifdef _REENTRANT

    printf("_REENTRANT defined\n");
#endif
#ifdef _THREAD_SAFE

    printf("_THREAD_SAFE defined\n");
#endif
#ifdef _FORTIFY_SOURCE

    printf("_FORTIFY_SOURCE defined\n");
#endif

    exit(EXIT_SUCCESS);
}
```

## СМОТРИТЕ ТАКЖЕ
libc(7), standards(7)

Раздел «Макросы тестирования свойств» в info libc.

/usr/include/features.h

branch: sisyphus


fifo

title: fifo(7)

summary: специальный файл, организующий очередь (first\-in first\-out),

text:
# fifo(7)

## ИМЯ
fifo - специальный файл, организующий очередь (first-in first-out), именованный канал

## ОПИСАНИЕ
Специальный файл FIFO (именованный канал) подобен каналу, за исключением того, что доступен как часть файловой системы. Его можно открывать из нескольких процессов на чтении или запись. Когда процессы обмениваются данными через FIFO, ядро передаёт все данные без их записи в файловую систему. То есть, специальный файл FIFO не хранит содержимое в файловой системе; запись в файловой системе служит просто местом, посредством которого процессы могут получить доступ к каналу, используя имя в файловой системе.

Ядро поддерживает один объект канала для каждого специального файла FIFO, который открыт хотя бы одним процессом. Для того, чтобы пропускать данные, FIFO должен быть открыт как для чтения, так и для записи. Обычно, при открытии FIFO он блокируется до тех пор, пока вышеописанные условия не будут выполнены.

Процесс может открыть FIFO в неблокирующем режиме. В этом случае открытие только для чтения выполняется без ошибки, даже если другая сторона ещё не открыла его для записи, и открытие только на запись завершается ошибкой ENXIO (нет такого устройства или адреса), если другая сторона к этому моменту не была открыта на чтение.

В Linux открытие FIFO для чтения и записи может быть осуществлено в блокирующем и неблокирующем режимах. Так как POSIX не описывает эти положения, это может быть использовано для открытия FIFO для чтения в отсутствие считывающих процессов. Процесс, использующий этот файл для чтения и записи (для связи с самим собой), не должен допустить возникновения блокировок (deadlocks).

## ЗАМЕЧАНИЯ
Подробную информацию о семантике ввода-вывода FIFO смотрите в pipe(7).

Если процесс попытается записать данные в FIFO, который не открыт для чтения, то ему посылается сигнал SIGPIPE.

Специальные файлы FIFO могут быть созданы с помощью mkfifo(3); при выводе ls -l они отображаются с типом файла «p».

## СМОТРИТЕ ТАКЖЕ
mkfifo(1), open(2), pipe(2), sigaction(2), signal(2), socketpair(2), mkfifo(3), pipe(7)


futex

title: futex(7)

text:
# futex(7)

## ИМЯ
futex - быстрая блокировка в пользовательском пространстве

## ОБЗОР

```
#include <linux/futex.h>
```

## ОПИСАНИЕ
Ядро Linux предоставляет фьютексы (futexes, «быстрые мьютексы (mutexes, взаимоисключающие блокировки) в пользовательском пространстве») в качестве строительного блока для быстрой блокировки в пользовательском пространстве и семафоров. Фьютексы очень просты и полезны для создания высокоуровневых абстракций блокировок, таких как мьютексы, условных переменных, блокировок чтения-записи, барьеров и семафоров.

Большинство программистов, фактически, не используют фьютексы напрямую, а полагаются на системные библиотеки, которые на них построены, такие как Native POSIX Thread Library (NPTL) (смотрите pthreads(7)).

Фьютекс отождествляется с участком памяти, который может быть общим для процессов или нитей. В этих процессах фьютекс может быть доступен по разным адресам. В своей основе фьютекс имеет семантику семафора; это счётчик, который можно увеличивать и уменьшать атомарно; процессы могут ждать пока значение не станет положительным.

Работа с фьютексом выполняется полностью в пользовательском пространстве при отсутствии конфликта (noncontended case). Ядро привлекается только для разрешения конфликтов. Так как все проектные решения стремятся к отсутствию конфликтов, фьютексы также оптимизированы под эту ситуацию.

В своей основе фьютекс — это целое число, которое изменяется только атомарными инструкциями ассемблера. Это целое число размером 4 байта на всех платформах. Процессы могут совместно использовать это число посредством mmap(2), сегментов общей памяти или общего пространства памяти (share memory space, в этом случае приложение, обычно, называют многонитевым).

### Поведение
Любое действие с фьютексом начинается в пользовательском пространстве, но может потребовать обращения к ядру через системный вызов futex(2).

Для «установки» фьютекса выполняются соответствующие ассемблерные инструкции, которые заставляют ЦП машины атомарно увеличить целое число. Далее проверяется, было ли действительно изменено значение с 0 на 1, то есть не было ожидающих и операция выполнена. Это бесконфликтный вариант, выполняется быстро и должен возникать чаще всего.

При возникновении конфликта, атомарное увеличение изменяет счётчик с -1 (или другого отрицательного числа). Это означает, что есть ожидающие. В пользовательском пространстве теперь нужно присвоить счётчику 1 и дать команду ядру пробудить всех ожидающих с помощью операции FUTEX_WAKE.

Ожидание фьютекса, его «сброс», является обратной операцией. Происходит атомарное уменьшение счётчика и проверка того, стал ли он равен 0, то есть операция выполнена и фьютекс был неконфликтным. Во всех других случаях, процесс должен присвоить счётчику -1 и запросить ядро об ожидании другого процесса, устанавливающего фьютекс. Это выполняется с помощью операции FUTEX_WAIT.

В системном вызове futex(2) можно указать время ожидания, то есть как долго ядро должно ждать установку фьютекса, В этом случае семантика более сложна и программисту нужно обратиться к futex(2). Это тоже самое что и ожидания асинхронного фьютекса.

## ВЕРСИИ
Впервые поддержка фьютексов появилась в Linux 2.5.7, но с другой семантикой. Текущая семантика используется в Linux с версии 2.5.40.

## ЗАМЕЧАНИЯ
Ещё раз повторим: в чистом виде фьютексы не являются лёгкой в использовании абстракцией для конечных пользователей. Использующие их программисты должны иметь хороший запас знаний об ассемблере и уметь читать исходный код библиотеки фьютексов для пользовательского пространства, указанной далее.

В этой справочной странице показано самое распространённое использование примитивов futex(2), которое ни в коем случае не единственное.

## СМОТРИТЕ ТАКЖЕ
clone(2), futex(2), get_robust_list(2), set_robust_list(2), set_tid_address(2), pthreads(7)

Fuss, Futexes and Furwocks: Fast Userlevel Locking in Linux (доклад с Ottawa Linux Symposium 2002), пример в библиотеке futex, futex-*.tar.bz2 ftp://ftp.kernel.org/pub/linux/kernel/people/rusty/.


glob

title: glob(7)

summary: шаблоны полных имён файлов

text:
# glob(7)

## ИМЯ
glob - шаблоны полных имён файлов

## ОПИСАНИЕ
Давным-давно, во времена UNIX V6, существовала программа /etc/glob, которая могла раскрывать шаблоны подстановки. Очень скоро она стала встроенной функцией командной оболочки.

В наши дни существует библиотечная функция glob(3), которая выполняет эту задачу для пользовательских программ.

Следующие правила приведены в соответствии со стандартом POSIX.2, 3.13.

### Тип шаблона
Строка считается шаблоном подстановки, если содержит в себе один из символов '?', '*' или '['. Globbing — это операция, которая раскрывает шаблон подстановки в список имён путей, соответствующих данному шаблону. Соответствие определяется следующими правилами:

'?' (без учета кавычек) соответствует любому одному символу.

'*' (без учета кавычек) соответствует любой строке, включая пустую строку.

Классы символов

Выражение «[...]», где первый символ после открывающей '[' - не равен '!', соответствует одному символу, который может быть любым символом из набора, находящегося внутри скобок. Строка внутри скобок не может быть пустой, таким образом, ']' также может находиться внутри скобок и выступать в качестве первого символа (то есть «[][!]» будет соответствовать трем символам '[', ']' и '!').

Диапазоны

Два символа, разделённые '-', образуют особое выражение — диапазон (то есть «[A-Fa-f0-9]» будет эквивалентен записи «[ABCDEFabcdef0123456789]»). Сюда также может входить и сам '-' в качестве начального или конечного символа (то есть «[]-]» будет соответствовать только двум символам - ']' и '-', а «[--0]» — трем символам: '-', '.', '0', так как '/' не может быть использован).

Разность множеств

Выражение «[!...]» соответствует одному любому символу, который не входит в множество, получаемое путем удаления первого '!' (то есть «[!]a-]» будет соответствовать любому одному символу за исключением ']', 'a' и '-').

Специальное значение '?', '*' и '[' может быть аннулировано путём экранирования их обратной косой чертой или, в случае, когда они являются частью оболочки командной строки, путём заключения их в кавычки. Внутри квадратных скобок эти символы не имеют специального значения. Таким образом, «[[?*\]» совпадает с четырьмя символами '[', '?', '*' и '\'.

### Полные составные пути
Раскрытие (globbing) применяется к каждой части полного составного имени файла отдельно. Символ '/' в полном имени файла не может совпадать с шаблоном '?' или '*', а только с диапазоном подобным «[.-0]». Диапазон не может включать в себя символ '/', поскольку это будет считаться синтаксической ошибкой (в POSIX требуется, чтобы синтаксически некорректные шаблоны не изменялись).

Если имя файла начинается с '.', то этот символ должен быть обязательно указан в шаблоне (таким образом, rm * не удалит .profile, а tar c * заархивирует не все файлы; лучше использовать tar c .).

### Пустые списки
Выше было приведено простое и замечательное правило из оригинального определения UNIX: «раскрытие шаблона — это операция, преобразующая шаблон в список соответствующих ему полных имён файлов». Оно допускает существование шаблона, соответствующего пустому списку, например:

```
    xv -wait 0 *.gif *.jpg
```

где, возможно, файлы *.gif на самом деле отсутствуют (и это не ошибка). Несмотря на это, в POSIX требуется, чтобы шаблон, синтаксически неправильный или раскрывающийся в пустой список путей к файлам, оставался без изменений. В bash можно принудительно включить классическое поведение с помощью команды:

shopt -s nullglob

Подобная проблема может проявиться вновь. Например, там, где в старых сценариях использовалось

```
    rm `find . -name "*~"`
```

в новых сценариях используется

```
    rm -f nosuchfile `find . -name "*~"`
```

для избежания сообщений об ошибках rm, вызванного с пустым списком аргументов.

## ЗАМЕЧАНИЯ

### Регулярные выражения
Заметим, что шаблоны не являются регулярными выражениями, хотя и похожи. Во-первых, они используются для выявления совпадений в именах файлов, а не в тексте. Во-вторых, используются разные соглашения: например, регулярное выражение '*' означает ноль или более копий предшествующему символу.

Теперь, когда в квадратных скобках у регулярных выражений для отрицания используется '^', в POSIX оговаривается, что эффект шаблона «[^...]» не определён.

### Классы символов и интернационализация
Изначально диапазоны были определены для символов ASCII, так что «[ -%]» соответствует «[ !"#$%]», а «[a-z]» соответствует «любому символу нижнего регистра». В некоторых реализациях UNIX это обобщено так, что диапазон X-Y соответствует всем символам, коды которых находятся между X и Y. Однако, это требует знания способа кодирования символов в локальной системе и, более того, не удобно, если последовательность сортировки для локального алфавита отличается от последовательности кодов символов. Поэтому в POSIX значительно расширено обозначение квадратных скобок как для шаблонов файлов, так и для регулярных выражений. Выше встретилось три типа выражений в скобках: отрицание (i), указанный явно символ (ii) и диапазон (iii). В POSIX диапазоны определены в более удобном с точки зрения интернационализации виде, а также добавлены три новых типа:

(iii) Диапазоны X-Y включают в себя все символы, находящиеся между X и Y (включительно) в соответствии с текущей последовательностью сортировки, определённой в категории LC_COLLATE текущей локали.

(iv) Именованные классы символов, такие, как:

```
[:alnum:]  [:alpha:]  [:blank:]  [:cntrl:]
[:digit:]  [:graph:]  [:lower:]  [:print:]
[:punct:]  [:space:]  [:upper:]  [:xdigit:]
```

Благодаря им можно указать значение «[[:lower:]]» вместо «[a-z]», и это будет работать для Дании, где в алфавите есть три буквы, стоящие после «z». Эти классы символов определяются категорией LC_CTYPE текущей локали.

(v) Сортировочные символы, такие, как «[.ch.]» или «[.a-acute.]», строка которых, лежащая между «[.» и «.]», является элементом сортировки, определённым для текущей локали. Заметим, что это может быть многосимвольный элемент.

(vi) Классы эквивалентности, такие, как «[=a=]», где строка между «[=» и «=]» является любым элементом сортировки из своего класса эквивалентности, определённого в текущей локали. Например, «[[=a=]]» может быть эквивалентно «[aáàäâ]», то есть «[a[.a-acute.][.a-grave.][.a-umlaut.][.a-circumflex.]]».

## СМОТРИТЕ ТАКЖЕ
sh(1), fnmatch(3), glob(3), locale(7), regex(7)


hier

title: hier(7)

summary: описание иерархии файловой системы

text:
# hier(7)

## ИМЯ
hier - описание иерархии файловой системы

## ОПИСАНИЕ
Типичная система Linux имеет, кроме прочих, следующие каталоги:

/

Корневой каталог. С него начинается всё дерево каталогов.

/bin

Каталог, содержащий исполняемые программы, необходимые для работы в однопользовательском режиме и для запуска или ремонта системы.

/boot

Содержит статические файлы загрузчика системы. В этом каталоге содержатся файлы, необходимые только во время загрузки системы. Установщик карты и файлы настройки должны находиться в /sbin и /etc. Ядро операционной системы (например, initrd) должно располагаться в / или /boot.

/dev

Специальные файлы и файлы устройств, ссылающиеся на физические устройства. См. mknod(1).

/etc

Содержит файлы настройки машины. Некоторые большие пакеты программ, например X11, могут иметь свои собственные подкаталоги в /etc. Общесистемные файлы настройки могут быть размещены либо в этом каталоге, либо в /usr/etc. Тем не менее, программы всегда должны искать эти файлы в /etc, и у вас могут быть ссылки на эти файлы в /usr/etc.

/etc/opt

Файлы настройки дополнительных приложений узла, установленных в /opt.

/etc/sgml

Этот каталог содержит файлы настроек SGML (необязательный).

/etc/skel

При создании новой учётной записи пользователя файлы из этого каталога, как правило, копируются в домашний каталог пользователя.

/etc/X11

Файлы настроек оконной системы X11 (необязательный).

/etc/xml

Этот каталог содержит файлы настроек XML (необязательный).

/home

Содержит домашние каталоги пользователей, если они расположены на этой машине. Его структура зависит от администратора системы (необязательный).

/lib

Этот каталог должен содержать разделяемые библиотеки, необходимые для загрузки системы и запуска команд, содержащихся в корневой файловой системе.

/lib<уточнение>

Эти каталоги являются вариантами /lib в системе, которая поддерживает более одного формата двоичных файлов, требующих отдельных библиотек (необязательные).

/lib/modules

Загружаемые модули ядра (необязательный).

/lost+found

В этом каталоге содержатся потерянные элементы файловой системы. Обычно, данные элементы представляют собой куски испорченных файлов в следствии ошибок диска или падений системы.

/media

В этом каталоге содержатся точки монтирования съёмных носителей, таких как диски CD и DVD или устройства памяти USB. В системах, в которых существует более устройства для монтирования определённого типа носителя, каталоги монтирования могут создаваться добавлением к имени цифры, начиная с «0», но неполное имя также должно существовать.

/media/floppy[1-9]

Устройство чтения дискет (необязательный).

/media/cdrom[1-9]

Устройство CD-ROM (необязательный).

/media/cdrecorder[1-9]

Устройство записи CD (необязательный).

/media/zip[1-9]

Устройство Zip (необязательный).

/media/usb[1-9]

Устройство USB (необязательный).

/mnt

Этот каталог является точкой для временного монтирования файловой системы. В некоторых дистрибутивах /mnt содержит подкаталоги, предназначенные для использования в качестве точек временного монтирования нескольких файловых систем.

/opt

Этот каталог содержит дополнительные пакеты со статическими файлами.

/proc

Точка подключения файловой системы proc, предоставляющей пользователю доступ к информации о запущенных процессах и ядре. Это псевдофайловая система, более подробно описанная в proc(5).

/root

Этот каталог является домашним для пользователя root (необязательный).

/sbin

Как и /bin, содержит команды, необходимые для запуска системы, но, как правило, не запускаемые обычными пользователями.

/srv

В каталоге содержится информация, которую обрабатывает данная система.

/sys

Это точка монтирования файловой системы sysfs, предоставляющей информацию о ядре; подобна /proc, но лучше структурирована, следует правилам инфраструктуры kobject.

/tmp

Этот каталог содержит временные файлы, которые можно удалить без всяких проблем в любое время, например, по расписанию или при загрузке системы.

/usr

К этому каталогу обычно монтируется отдельный раздел. В нём должны содержаться общие, предназначенные только для чтения данные, так что он может быть смонтирован несколькими машинами, работающими в Linux.

/usr/X11R6

Система X-Window, версия 11, выпуск 6 (необязательный).

/usr/X11R6/bin

Исполняемые файлы, принадлежащие системе X-Window. Часто на него имеется символьная ссылка из более привычного каталога — /usr/bin/X11.

/usr/X11R6/lib

Файлы данных, относящиеся к системе X-Window.

/usr/X11R6/lib/X11

Содержит различные файлы, необходимые для запуска X. В каталоге /usr/lib/X11 часто имеется символьная ссылка на вышеуказанный каталог.

/usr/X11R6/include/X11

Содержит заголовочные файлы для компиляции программ, использующих систему X11. Часто имеется символьная ссылка на этот каталог в каталоге /usr/include/X11.

/usr/bin

Это основной каталог для исполняемых программ. Большая часть программ, не требующихся при загрузке или для ремонта системы, не устанавливаемых локально и запускаемых обычными пользователями, должна быть помещена в этот каталог.

/usr/bin/mh

Команды для работы с почтовой системой MH (необязательный).

/usr/bin/X11

обычное место для исполняемых файлов X11; в Linux это обычно символьная ссылка на /usr/X11R6/bin.

/usr/dict

Заменён на /usr/share/dict.

/usr/doc

Заменён на /usr/share/doc.

/usr/etc

В этом каталоге можно хранить системные файлы настройки, которые могут использоваться несколькими машинами одновременно. Однако, команды должны искать эти файлы в каталоге /etc. Ссылки из каталога /etc должны указывать на соответствующие файлы в /usr/etc.

/usr/games

Исполняемые файлы игр и обучающих программ (необязательный).

/usr/include

Заголовочные файлы для компилятора C.

/usr/include/bsd

Включаемые файлы для совместимости с BSD (необязательный).

/usr/include/X11

Заголовочные файлы для компилятора C и системы X-Window. Как правило, это символьная ссылка на /usr/X11R6/include/X11.

/usr/include/asm

Заголовочные файлы, определяющие некоторые ассемблерные функции. Это символьная ссылка на /usr/src/linux/include/asm.

/usr/include/linux

Содержит информацию, которая может меняться от выпуска к выпуску. Это символьная ссылка на /usr/src/linux/include/linux для получения информации, предназначенной только для данной системы.

(Заметим, что необходимо иметь заголовочные файлы, корректно работающие с текущей libc и в пространстве пользователя. Однако, исходный код ядра Linux не рассчитан на включение в пользовательскую программу и ничего не знает о работающей libc. Весьма вероятно, что появятся ошибки, если /usr/include/asm и /usr/include/linux будут указывать на произвольное дерево ядра. Системы Debian не делают этого, а используют заголовочные файлы тех версий ядра, которые себя хорошо зарекомендовали. Они поставляются в пакете libc*-dev.)

/usr/include/g++

Заголовочные файлы, используемые с компилятором GNU C++.

/usr/lib

Объектные библиотеки, в том числе и динамические, а также некоторые программы, обычно не запускаемые вручную. Более сложные программы могут иметь в этом каталоге свои подкаталоги.

/usr/lib<уточнение>

Эти каталоги являются вариантами /usr/lib в системе, которая поддерживает более одного формата двоичных файлов, требующих отдельных библиотек, за исключением того, что символьная ссылка /usr/lib<уточнение>/X11 не требуется (необязательные).

/usr/lib/X11

Стандартная область для файлов данных, связанных с программами X, а также для файлов настройки самой X. В Linux это обычно символьная ссылка на /usr/X11R6/lib/X11.

/usr/lib/gcc-lib

Содержит исполняемые и заголовочные файлы для компилятора GNU C, gcc(1).

/usr/lib/groff

Файлы для системы форматирования документов GNU groff.

/usr/lib/uucp

Файлы для uucp(1).

/usr/local

В этот каталог обычно помещаются программы, устанавливаемые локально.

/usr/local/bin

Исполняемые файлы программ, установленных локально.

/usr/local/doc

Локальная документация.

/usr/local/etc

Файлы настройки локально установленных программ.

/usr/local/games

Программы локально установленных игр.

/usr/local/lib

Файлы, связанные с локально установленными программами.

/usr/local/lib<уточнение>

Эти каталоги являются вариантами /usr/local/lib в системе, которая поддерживает более одного формата двоичных файлов, требующих отдельных библиотек (необязательные).

/usr/local/include

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

/usr/local/info

Страницы info, относящиеся к локально установленным программам.

/usr/local/man

Справочные страницы, относящиеся к локально установленным программам.

/usr/local/sbin

Локально установленные программы для системного администрирования.

/usr/local/share

Данные локально установленных приложений, которые могут быть общими между различными архитектурами одной ОС.

/usr/local/src

Исходный код локально установленного ПО.

/usr/man

Заменён на /usr/share/man.

/usr/sbin

В этом каталоге содержатся исполняемые программы для системного администрирования, не относящиеся к процессу загрузки, монтированию /usr или восстановлению системы.

/usr/share

Этот каталог содержит подкаталоги с данными приложений, которые могут быть использованы на различных аппаратных архитектурах в одной и той же ОС. Часто, в нём содержатся данные из /usr/doc, /usr/lib или /usr/man.

/usr/share/dict

Содержит словари для проверки орфографии (необязательный).

/usr/share/dict/words

Список английских слов (необязательный).

/usr/share/doc

Документация на установленные программы (необязательный).

/usr/share/games

Статические данные игр из /usr/games (необязательный).

/usr/share/info

Справочные страницы в формате info (необязательный).

/usr/share/locale

Информация о локали (необязательный).

/usr/share/man

Справочные страницы по разделам в соответствующих подкаталогах.

/usr/share/man/<локаль>/man[1-9]

Эти каталоги содержат исходный код справочных страниц для определённой локали. Системы, в которых используется один язык и кодировочная таблица, не содержат часть <локаль>.

/usr/share/misc

Различные данные, которые могут совместно использоваться для различных архитектур одной ОС.

/usr/share/nls

Каталог сообщений на родном языке (необязательный).

/usr/share/sgml

Файлы для SGML (необязательный).

/usr/share/sgml/docbook

DocBook DTD (необязательный).

/usr/share/sgml/tei

TEI DTD (необязательный).

/usr/share/sgml/html

HTML DTD (необязательный).

/usr/share/sgml/mathtml

MathML DTD (необязательный).

/usr/share/terminfo

Каталог базы данных для terminfo (необязательный).

/usr/share/tmac

Макросы troff, не распространяемые вместе с groff (необязательный).

/usr/share/xml

Файлы для XML (необязательный).

/usr/share/xml/docbook

DocBook DTD (необязательный).

/usr/share/xml/xhtml

XHTML DTD (необязательный).

/usr/share/xml/mathml

MathML DTD (необязательный).

/usr/share/zoneinfo

Файлы с информацией о часовых поясах (необязательный).

/usr/src

Файлы с исходным кодом различных частей системы, которые входят в состав различных пакетов. Не используйте этот каталог для работы над своими проектами, так как файлы в подкаталогах /usr предназначены только для чтения, кроме случаев установки программного обеспечения (необязательный).

/usr/src/linux

Этот каталог всегда был традиционным местоположением файлов с исходным кодом ядра. Многие дистрибутивы размещают тут исходный код используемого в системе ядра. Для сборки ядра рекомендуется использовать другой каталог.

/usr/tmp

Устарел. Должен быть ссылкой на /var/tmp. Эта ссылка оставлена только для совместимости, её не следует использовать.

/var

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

/var/account

Журналы учёта процессов (необязательный).

/var/adm

Вместо этого каталога используется /var/log и он должен быть символьной ссылкой на /var/log.

/var/backups

Этот каталог зарезервирован по историческим причинам.

/var/cache

Кэшированные данные программ.

/var/cache/fonts

Шрифты, сгенерированные локально (необязательный).

/var/cache/man

Справочные страницы (man), сгенерированные локально (необязательный).

/var/cache/www

Данные кэша или прокси WWW (необязательный).

/var/cache/<пакет>

Кэш данных определённого пакета (необязательный).

/var/catman/cat[1-9] или /var/cache/man/cat[1-9]

Эти каталоги содержат предварительно отформатированные справочные страницы в соответствии с их разделами (категорически запрещается использовать их в работе).

/var/crash

Дампы падений системы (необязательный).

/var/cron

Этот каталог зарезервирован по историческим причинам.

/var/games

Изменяемые данные игр (необязательный).

/var/lib

Изменяемая информация о состоянии программ.

/var/lib/hwclock

Каталог состояния hwclock (необязательный).

/var/lib/misc

Данные о различных состояниях.

/var/lib/xdm

Изменяемые данные менеджера экрана X (необязательный).

/var/lib/<editor>

Состояние и резервные копии файлов редактора (необязательный).

/var/lib/<имя>

Эти каталоги должны использоваться для поддержки распространения в пакетном виде.

/var/lib/<пакет>

Данные состояния пакетов и подсистем (необязательный).

/var/lib/<pkgtool>

Файлы поддержки пакетирования (необязательный).

/var/local

Изменяемые данные программами из /usr/local.

/var/lock

В этом каталоге содержатся файлы блокировки. Соглашения об именах файлов, блокирующих устройства, следующие: LCK..<устройство>, где устройство — имя устройства в файловой системе. Используется формат файлов блокировки HDU UUCP, то есть файлы блокировки содержат PID в виде 10-байтного десятичного числа ASCII; после этого числа стоит символ новой строки.

/var/log

Различные файлы журналов.

/var/opt

Изменяемые данные программами из /opt.

/var/mail

Почтовые ящики пользователей. Заменяет /var/spool/mail.

/var/msgs

Этот каталог зарезервирован по историческим причинам.

/var/preserve

Этот каталог зарезервирован по историческим причинам.

/var/run

Временные файлы, создаваемые во время работы. В них содержатся идентификаторы процессов (PID) и журнал регистрации пользователей utmp. Файлы из этого каталога обычно удаляются в процессе загрузки системы.

/var/spool

Файлы, поставленные в очередь различными программами.

/var/spool/at

Очередь заданий at(1).

/var/spool/cron

Очередь заданий cron(8).

/var/spool/lpd

Файлы, отправленные в очередь для печати (необязательный).

/var/spool/lpd/printer

Очередь печати определённого принтера (необязательный).

/var/spool/mail

Заменён на /var/mail.

/var/spool/mqueue

Очередь исходящей почты (необязательный).

/var/spool/news

Каталог хранения новостей (необязательный).

/var/spool/rwho

Хранящиеся файлы для rwhod(8) (необязательный).

/var/spool/smail

Хранящиеся файлы для программы доставки почты smail(1).

/var/spool/uucp

Хранящиеся файлы для uucp(1) (необязательный).

/var/tmp

Как и /tmp, этот каталог содержит временные файлы, но которые могут храниться неопределённое время.

/var/yp

Файлы баз данных NIS, ранее называвшийся Sun Yellow Pages (YP).

## СООТВЕТСТВИЕ СТАНДАРТАМ
Стандарт иерархии файловой системы, версия 2.3 http://www.pathname.com/fhs/.

## ДЕФЕКТЫ
Этот список далеко не полон; разные системы могут быть настроены различным образом.

## СМОТРИТЕ ТАКЖЕ
find(1), ln(1), proc(5), file-hierarchy(7), mount(8)

Стандарт иерархической файловой системы


hostname

title: hostname(7)

summary: определение имени узла

text:
# hostname(7)

## ИМЯ
hostname - определение имени узла

## ОПИСАНИЕ
Имена узлов (hostnames) представляют собой домены; домен — это иерархический список поддоменов, перечисленных через точку; например, имя машины «monet» в поддомене «example» домена «com» записывалось бы в виде «monet.example.com».

Каждый элемент имени узла должен быть от 1 до 63 символов, а полное имя узла, включая точки, может быть не более 253 символов. Допустимые символы в именах: буквы ASCII(7) от a до z, цифры от 0 до 9 и символ переноса (-). Имя узла не может начинаться с переноса.

Имена узлов часто используются клиентскими и серверными программами, которые перед использованием, обычно, должны преобразовать имя в адрес (эта задача, обычно, выполняется getaddrinfo(3) или устаревшей gethostbyname(3)).

Имена узлов в glibc преобразуются инфраструктурой NSS согласно настройке hosts в файле nsswitch.conf. Определитель имён на основе DNS (в NSS — служебный модуль dns) работает по следующему алгоритму:

Если имя состоит из одного компонента, то есть не содержит точки, и если в значении переменной окружения HOSTALIASES указано имя файла, то в этом файле выполняется поиск строки, совпадающей с именем узла. Файл должен содержать строки, которые состоят из двух частей, разделённых пробелом; в первой части задаётся псевдоним узла, а во второй — полное имя узла, которое используется вместо псевдонима. Если при поиске без учёта регистра найден искомый узел в первой части, то обработка останавливается и для поиска используется имя из второй части.

Если искомое имя оканчивается точкой, то эта точка удаляется и оставшееся имя ищется без дальнейшей обработки.

Если искомое имя не оканчивается точкой, то оно ищется со всеми доменами из списка до первого совпадения. По умолчанию, список поиска сначала содержит локальный домен, затем его родительские домены, имеющие не менее 2 компонентов в имени (от длинных к коротким). Например, в домене cs.example.com имя lithium.cchem сначала будет искаться как lithium.cchem.cs.example, а затем как lithium.cchem.example.com. lithium.cchem.com не будет искаться, так как в локальном домене остался только один компонент. Путь поиска по умолчанию можно изменить через системный файл настройки (смотрите resolver(5)).

## СМОТРИТЕ ТАКЖЕ
getaddrinfo(3), gethostbyname(3), nsswitch.conf(5), resolver(5), mailaddr(7), named(8)

IETF RFC 1123

IETF RFC 1178


icmp

title: icmp(7)

text:
# icmp(7)

## ИМЯ
icmp - модуль ядра Linux, реализующий протокол IPv4 ICMP

## ОПИСАНИЕ
Этот модуль ядра реализует Internet Control Message Protocol, описанный в RFC 792. Он используется для извещения об ошибках и для диагностики. Пользователь не взаимодействует напрямую с этим модулем; вместо этого он работает с другими протоколами в ядре, а они при помощи протокола ICMP передают ошибки на уровень приложения. Кроме того, этот модуль отвечает на ICMP-запросы.

Пользовательский протокол может получать ICMP-пакеты для всех локальных сокетов, если откроет неструктурированный (raw) сокет, используя протокол IPPROTO_ICMP. Более подробную информацию смотрите в raw(7). Типы ICMP-пакетов, передаваемые в сокет, могут быть отфильтрованы с помощью параметра сокета ICMP_FILTER. Пакеты ICMP всегда обрабатываются ядром, даже когда передаются в пользовательский сокет.

Linux ограничивает для каждого получателя поток ICMP-пакетов с сообщениями об ошибках. Количество ICMP_REDIRECT и ICMP_DEST_UNREACH также ограничивается для каждого отправителя приходящих пакетов.

### Интерфейсы в /proc
Для настройки некоторых глобальных параметров IP ICMP поддерживает набор интерфейсов в /proc. Эти параметры доступны на чтение и запись через файлы в каталоге /proc/sys/net/ipv4/. Большинство параметров служит для управления ограничением потока пакетов ICMP определённых типов. В Linux 2.2 для ограничения ICMP используется фильтр «протекающего ведра» (token bucket). Значение — задержка в jiffy, отведённая на очистку фильтра после всплеска. Величина jiffy зависит от архитектуры машины, обычно, это 10мс на i386 и около 1мс на alpha и ia64.

icmp_destunreach_rate (в Linux с 2.2 по 2.4.9)

Максимальная частота посылки ICMP-пакетов с типом Destination Unreachable по каждому конкретному маршруту или получателю. Ограничение не влияет на посылку пакетов ICMP_FRAG_NEEDED, необходимых для определения MTU для маршрута.

icmp_echo_ignore_all (начиная с Linux 2.2)

Если значение больше нуля, то Linux будет игнорировать все запросы ICMP_ECHO.

icmp_echo_ignore_broadcasts (начиная с Linux 2.2)

Если значение больше нуля, то Linux будет игнорировать все пакеты ICMP_ECHO, посланные по широковещательным адресам.

icmp_echoreply_rate (в Linux с 2.2 по 2.4.9)

Максимальная частота посылки пакетов ICMP_ECHOREPLY в ответ на запросы ICMP_ECHOREQUEST.

icmp_errors_use_inbound_ifaddr (логический; по умолчанию: выключено; начиная с Linux 2.6.12)

Если выключено, то сообщения ICMP об ошибках посылаются с первичным адресом существующего интерфейса.

Если включено, то сообщения будут посылаться с первичным адресом интерфейса, на который поступил пакет, вызвавший ошибку ICMP. Такое поведение соответствует работе маршрутизаторов, как этого ожидают сетевые администраторы. Также, это позволяет облегчить диагностику проблем в сложных сетях.

Заметим, что если на нужном интерфейсе первичный адрес не задан, то используется адрес первого интерфейса, не являющегося обратной петлёй, и значение данного параметра не учитывается.

icmp_ignore_bogus_error_responses (логический; по умолчанию: выключено; начиная с Linux 2.2)

Некоторые маршрутизаторы нарушают RFC1122, отправляя фиктивные ответы на широковещательные пакеты. Эти нарушения, обычно, протоколируются предупреждением ядра. Если этот параметр включён, то ядро не будет выдавать такие предупреждения, что позволяет не засорять файл журнала.

icmp_paramprob_rate (в Linux с 2.2 по 2.4.9)

Максимальная частота посылки пакетов ICMP_PARAMETERPROB. Эти пакеты посылаются, когда приходит пакет с ошибочным заголовком IP.

icmp_ratelimit (целое; по умолчанию: 1000; начиная с Linux 2.4.10)

Ограничивает скорость отправки пакетов ICMP для определённого получателя, чьи типы совпадают с icmp_ratemask (смотрите далее). Значение 0 отключает ограничение, иначе указывается минимальная задержка между ответами в миллисекундах.

icmp_ratemask (целое; по умолчанию: смотрите далее; начиная с Linux 2.4.10)

Маска типов ICMP, для которых накладывается ограничение.

Расстановка битов: IHGFEDCBA9876543210

Маска по умолчанию: 0000001100000011000 (0x1818)

Описание битов (смотрите файл include/linux/icmp.h из исходного кода ядра Linux):

0 Ответное эхо

3 Назначение недостижимо *

4 Погасить источник *

5 Перенаправление

8 Запрос эхо

B Время вышло *

C Проблема с параметром *

D Запрос метки времени

E Ответ меткой времени

F Запрос информации

G Ответ информацией

H Запрос маски адреса

I Ответ маской адреса

Для битов, помеченных звёздочкой, ограничение включено по умолчанию (смотрите маску по умолчанию, приведённую ранее).

icmp_timeexceed_rate (в Linux с 2.2 по 2.4.9)

Максимальная частота посылки пакетов ICMP_TIME_EXCEEDED. Эти пакеты посылаются для предотвращения зацикливания, когда пакет прошёл слишком большое количество транзитных участков (hops).

ping_group_range (два целых числа; значение по умолчанию смотрите далее; начиная с Linux 2.6.39)

Диапазон ID групп (минимальный и максимальный ID группы, включительно), которым разрешено создавать сокеты ICMP Echo. По умолчанию «1 0», что означает, что всем группам запрещено создавать сокеты ICMP Echo.

## ВЕРСИИ
Поддержка запроса ICMP_ADDRESS была удалена из 2.2.

Поддержка ICMP_SOURCE_QUENCH была удалена из Linux 2.2.

## ЗАМЕЧАНИЯ
Так как многие реализации не поддерживают неструктурированные сокеты IPPROTO_ICMP, то использование этой возможности нежелательно при написании переносимых программ.

Пакеты ICMP_REDIRECT не посылаются, если Linux не работает как маршрутизатор. Также, они принимаются только от старых шлюзов, определённых в таблице маршрутизации, причем информация о перенаправлении маршрутов устаревает через некоторое время.

Значения 64-битных временных меток, возвращаемых по ICMP_TIMESTAMP, отсчитываются в миллисекундах с начала Эпохи, 1970-01-01 00:00:00 +0000 (UTC).

В Linux-реализации ICMP для посылки ICMP-пакетов используются неструктурированные сокеты. Такие сокеты могут показываться программой netstat(8), при этом их inode будет равен 0.

## СМОТРИТЕ ТАКЖЕ
ip(7), rdisc(8)

В RFC 792 приведено описание протокола ICMP.


inode

title: inode(7)

summary: описание файловой иноды

text:
# inode(7)

## ИМЯ
inode - описание файловой иноды

## ОПИСАНИЕ
Для каждого файла существует инода (inode), содержащая метаданные файла. Приложение может получить эти метаданные с помощью stat(2) (и подобных вызовов), который возвращает структуру stat, и statx(2), который возвращает структуру statx.

В следующем списке показана информация, которую, обычно, можно найти или которая относится к файловой иноде в полях соответствующей структуры, возвращаемой stat(2) и statx(2):

Устройство, на котором находится инода

stat.st_dev; statx.stx_dev_minor и statx.stx_dev_major

Каждая инода (а также связанный с ней файл) располагается в файловой системе, которая находится на устройстве. Это устройство опознаётся по комбинации своих основного (определяет общий класс устройства) и вспомогательного (определяет конкретный экземпляр в общем классе) идентификаторов.

Номер иноды

stat.st_ino; statx.stx_ino

Каждый файл в файловой системе имеет уникальный номер иноды. Для номеров инод гарантируется уникальность только внутри файловой системы (т. е., одинаковые номера инод могут использоваться в разных файловых системах, из-за чего жёсткие ссылки не могут пересекать границы файловой системы). В этом поле содержится номер иноды файла.

Тип файла и режим

stat.st_mode; statx.stx_mode

Описание типа файла и режим приведены ниже.

Счётчик ссылок

stat.st_nlink; statx.stx_nlink

Это поле содержит количество жёстких ссылок на файл. Дополнительные ссылки на существующий файл созданы с помощью link(2).

Пользовательский идентификатор

st_uid stat.st_uid; statx.stx_uid

В этом поле содержится идентификатор пользователя, которому принадлежит файл. При создании файла идентификатору пользователя файла присваивается идентификатор эффективного пользователя создающего процесса. Идентификатор пользователя файла можно изменить с помощью chown(2).

Идентификатор группы

stat.st_gid; statx.stx_gid

В этом поле содержится идентификатор группы, которой принадлежит файл. При создании файла идентификатору группы файла присваивается идентификатор группы родительского каталога или идентификатор эффективной группы создающего процесса, в зависимости от наличия бита set-group-ID на родительском каталоге (смотрите ниже). Идентификатор группы файла можно изменить с помощью chown(2).

Устройство, представляемое этой инодой

stat.st_rdev; statx.stx_rdev_minor и statx.stx_rdev_major

Если этот файл (инода) представляет устройство, то инода хранит основной и вспомогательный идентификатор этого устройства.

Размер файла

stat.st_size; statx.stx_size

Размер файла (если он обычный или является символьной ссылкой) в байтах. Размер символьной ссылки равен длине пути файла, на который она ссылается, без конечного нулевого байта.

Предпочтительный размер блока для ввода/вывода

stat.st_blksize; statx.stx_blksize

«Предпочтительный» размер блока для эффективного ввода/вывода в файловой системе (запись в файл более мелкими порциями может привести к неэффективному чтению/изменению/повторной записи).

Количество блоков, выделенных файлу

stat.st_blocks; statx.stx_size

Количество блоков (по 512 байт), выделенных для файла (может быть меньше, чем st_size/512, когда в файле есть пропуски (holes)).

В стандарте POSIX.1 отмечено, что размер единиц значения st_blocks структуры stat стандартом не определяется. Во многих реализациях он равен 512 байт; в некоторых системах используются другой — 1024. Кроме этого, размер единиц может отличаться для разных файловых систем.

Метка времени последнего доступа (atime)

stat.st_atime; statx.stx_atime

Метка времени последнего доступ к файлу. Изменяется при доступе к файлу, например, при выполнении execve(2), mknod(2), pipe(2), utime(2) и read(2) (при чтении ненулевого количества байт). Другие интерфейсы, например mmap(2), могут изменять метку, но могут и не делать этого.

Некоторые типы файловых систем позволяют выполнить монтирование таким образом, что факт доступа к файлу или каталогу не вызовет изменение метки atime (смотрите описание noatime, nodiratime и relatime в mount(8) и связанную с ними информацию в mount(2)). Также, поле метка atime не обновляется, если файл открыт с флагом O_NOATIME; смотрите open(2).

Метка времени создания файла (btime)

(не возвращается в структуре stat); statx.stx_btime

Метка времени создания файла. Устанавливается при создании файла и после этого не изменяется.

Метка btime отсутствовала в системах UNIX и в настоящее время не поддерживается в большинстве файловых систем Linux.

Метка времени последнего изменения (mtime)

stat.st_mtime; statx.stx_mtime

Метка времени последнего изменения файла. Изменяется при изменении файла, например, при выполнении mknod(2), truncate(2), utime(2) и write(2) (если записано не менее одного байта). Кроме того, у каталога метка mtime изменяется при создании и удалении файлов в этом каталоге. Метка mtime не изменяется при изменении владельца, группы, количества жёстких ссылок или режима доступа.

Метка времени последнего изменения состояния (ctime)

stat.st_ctime; statx.stx_ctime

Метка времени последнего изменения состояния файла. Изменяется при записи или установке информации иноды (т. е., владельце, группе, количестве ссылок, режиме и т. д.).

За начальное значение полей меток времени принимается Эпоха, 1970-01-02 00:00:00 +0000, UTC (смотрите time(7)).

Метки времени наносекундной точности поддерживаются в XFS, JFS, Btrfs и ext4 (начиная с Linux 2.6.23). Метки времени наносекундной точности не поддерживаются в ext2, ext3 и Reiserfs. Для возвращать метки времени наносекундной точности поля меток времени в структурах stat и statx определены как структуры, включающие наносекундную составляющую. Подробности приведены в stat(2) и statx(2). Для файловых систем, не поддерживающих субсекундные метки времени, наносекундные поля в возвращаемых структурах stat и statx имеют значение 0.

### Тип файла и режим
Поле stat.st_mode (в statx(2) — поле statx.stx_mode ) содержит тип файл и режим.

В POSIX относятся к битам stat.st_mode равным маске S_IFMT (смотрите ниже) как к типу файла (file type), 12 битам, соответствующим маске 07777, как к битам режима файла (file mode bits) и наименее значащим 9 битам (0777) как к битам доступа к файлу (file permission bits).

Следующие значения масок определены для типа файла:

S_IFMT

0170000

битовая маска битового поля для типа файла

S_IFSOCK

0140000

сокет

S_IFLNK

0120000

символьная ссылка

S_IFREG

0100000

обычный файл

S_IFBLK

0060000

блочное устройство

S_IFDIR

0040000

каталог

S_IFCHR

0020000

символьное устройство

S_IFIFO

0010000

FIFO

Таким образом, чтобы проверить обычный файл (например) на возможность записи:

```
stat(pathname, &sb);
if ((sb.st_mode & S_IFMT) == S_IFREG) {

    /* обработка обычного файла */
}
```

Так как приведённое выше тестирование имеет общий вид, в POSIX определены дополнительные макросы, которые позволяют тестировать тип файла в st_mode более краткой записью:

S_ISREG(m)

обычный файл?

S_ISDIR(m)

каталог?

S_ISCHR(m)

символьное устройство?

S_ISBLK(m)

блочное устройство?

S_ISFIFO(m)

FIFO (именованный канал)?

S_ISLNK(m)

символьная ссылка? (нет в POSIX.1-1996.)

S_ISSOCK(m)

сокет? (нет в POSIX.1-1996.)

The preceding code snippet could thus be rewritten as:

```
stat(pathname, &sb);
if (S_ISREG(sb.st_mode)) {

    /* обработка обычного файла */
}
```

Определений большинства показанных ранее макросов тестирования типа файла доступно, если определён любой из следующих макросов тестирования свойств: _BSD_SOURCE (в glibc 2.19 и старее), _SVID_SOURCE (в glibc 2.19 и старее) или _DEFAULT_SOURCE (в glibc 2.20 и новее). Также, определение всех макросов, за исключением S_IFSOCK и S_ISSOCK(), доступны при наличии _XOPEN_SOURCE.

Определение S_IFSOCK также можно получить определив _XOPEN_SOURCE со значением 500 или более или (начиная с glibc 2.24) определением _XOPEN_SOURCE и _XOPEN_SOURCE_EXTENDED одновременно.

Определение S_ISSOCK() доступно, если определён любой из следующих макросов тестирования свойств: _BSD_SOURCE (в glibc 2.19 и старее), _DEFAULT_SOURCE (в glibc 2.20 и новее), _XOPEN_SOURCE со значением 500 или более или _POSIX_C_SOURCE со значением 200112L или более или (начиная с glibc 2.24) _XOPEN_SOURCE и _XOPEN_SOURCE_EXTENDED одновременно.

Следующие значения масок определены для компонента режима доступа к файлу в поле st_mode:

S_ISUID

04000

бит set-user-ID (смотрите execve(2))

S_ISGID

02000

бит set-group-ID (смотрите далее)

S_ISVTX

01000

закрепляющий бит (смотрите далее)

S_IRWXU

00700

владелец имеет права на чтение, запись и выполнение

S_IRUSR

00400

владелец имеет право на чтение

S_IWUSR

00200

владелец имеет право на запись

S_IXUSR

00100

владелец имеет право на выполнение

S_IRWXG

00070

группа имеет права на чтение, запись и выполнение

S_IRGRP

00040

имеет право на чтение

S_IWGRP

00020

группа имеет право на запись

S_IXGRP

00010

группа имеет право на выполнение

S_IRWXO

00007

все остальные (вне группы) имеют права на чтение, запись и выполнение

S_IROTH

00004

все остальные имеют право на чтение

S_IWOTH

00002

все остальные имеют право на запись

S_IXOTH

00001

все остальные имеют право на выполнение

Бит set-group-ID (S_ISGID) имеет несколько специальных применений. Для каталога он указывает, что используется семантика BSD: файлы, создаваемые в каталоге, наследуют ID группы этого каталога, а не фактический ID группы создающего процесса, а для подкаталогов данного каталога также будет установлен бит S_ISGID. Для исполняемого файла бит set-group-ID заставляет изменить фактический ID группы процесса, который выполняет файл, согласно правилам, описанным в execve(2). Если файл не имеет бита выполнения группой (S_IXGRP), то бит set-group-ID означает обязательную (mandatory) блокировку файла/записей.

Закрепляющий (sticky) бит (S_ISVTX) на каталоге означает, что файлы в этом каталоге могут быть удалены или переименованы только владельцем файла, владельцем каталога и привилегированным процессом.

## СООТВЕТСТВИЕ СТАНДАРТАМ
Если вам нужно получить определение типа blkcnt_t или blksize_t из <sys/stat.h>, то определите _XOPEN_SOURCE со значением 500 или больше (до включения каких-либо заголовочных файлов).

В POSIX.1-1990 не описаны константы S_IFMT, S_IFSOCK, S_IFLNK, S_IFREG, S_IFBLK, S_IFDIR, S_IFCHR, S_IFIFO, S_ISVTX, вместо них указано использовать макросы S_ISDIR() и т.п. Константы S_IF* определены в POSIX.1-2001 и новее.

Макросы S_ISLNK() и S_ISSOCK() не описаны в POSIX.1-1996, но есть в POSIX.1-2001; первый взят из SVID 4, последний из SUSv2.

В UNIX V7 (и более поздних системах) есть S_IREAD, S_IWRITE, S_IEXEC, для которых в POSIX есть синонимы S_IRUSR, S_IWUSR, S_IXUSR.

## ЗАМЕЧАНИЯ
Для псевдо-файлов, автоматически генерируемых ядром, размер файла (statst_size; statx.stx_size) возвращается не точным. Например, для многих файлов каталога /proc возвращается значение 0, а для различных файлов из каталога /sys возвращается размер 4096 байт, даже когда содержимое файла меньше этого значения. Из таких файлов нужно просто считать все возможные байты (и добавлять '\0' в возвращаемый буфер, если он считается строкой).

## СМОТРИТЕ ТАКЖЕ
stat(1), stat(2), statx(2), symlink(7)