title: pthread_sigmask(3)

text:
# pthread_sigmask(3)

## ИМЯ
pthread_sigmask - проверяет и изменяет маску заблокированных сигналов

## ОБЗОР

```
#include <signal.h>
```

```
int pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset);
```

Компилируется и компонуется вместе с -pthread.

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

pthread_sigmask():

_POSIX_C_SOURCE >= 199506L || _XOPEN_SOURCE >= 500

## ОПИСАНИЕ
Функция pthread_sigmask() подобна sigprocmask(2), но используется в многонитевых программах, что явно указано в POSIX.1. Другие отличия приведены в этой странице.

Описание аргументов и работы функции смотрите в sigprocmask(2).

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении pthread_sigmask() возвращается 0; при ошибке возвращается номер ошибки.

## ОШИБКИ
Смотрите sigprocmask(2).

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

pthread_sigmask()

Безвредность в нитях

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008.

## ЗАМЕЧАНИЯ
Новая нить наследует копию маски сигналов своего создателя.

Функция glibc pthread_sigmask() просто игнорирует попытки блокирования двух сигналов реального времени, которые используются внутри реализации NPTL. Подробности смотрите в nptl(7).

## ПРИМЕР
Показанная далее программа блокирует некоторые сигналы в главной нити, а затем создаёт отдельную нить для получения этих сигналов с помощью sigwait(3). Пример работы программы:

```
$ ./a.out &
[1] 5423
$ kill -QUIT %1
Нить обработки сигналов получила сигнал 3
$ kill -USR1 %1
Нить обработки сигналов получила сигнал 10
$ kill -TERM %1
[1]+  Terminated              ./a.out
```

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

```
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
/* Простая функция обработки сигналов */
#define handle_error_en(en, msg) \

        do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
static void *
sig_thread(void *arg)
{

    sigset_t *set = arg;

    int s, sig;

    for (;;) {

        s = sigwait(set, &sig);

        if (s != 0)

            handle_error_en(s, "sigwait");

        printf("Нить обработки сигналов получила сигнал %d\n", sig);

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

    pthread_t thread;

    sigset_t set;

    int s;

    /* Блокируем SIGQUIT и SIGUSR1; нити, созданные main(),

       унаследуют копию маски сигналов. */

    sigemptyset(&set);

    sigaddset(&set, SIGQUIT);

    sigaddset(&set, SIGUSR1);

    s = pthread_sigmask(SIG_BLOCK, &set, NULL);

    if (s != 0)

        handle_error_en(s, "pthread_sigmask");

    s = pthread_create(&thread, NULL, &sig_thread, (void *) &set);

    if (s != 0)

        handle_error_en(s, "pthread_create");

    /* Главная нить служит для создания других нитей и/или

       выполняет другую работу */

    pause();            /* Просто пауза, чтобы мы могли протестировать

                           программу */
}
```

## СМОТРИТЕ ТАКЖЕ
sigaction(2), sigpending(2), sigprocmask(2), pthread_create(3), pthread_kill(3), sigsetops(3), pthreads(7), signal(7)


package: man-pages-ru

title: pthread_sigqueue(3)

text:
# pthread_sigqueue(3)

## ИМЯ
pthread_sigqueue - вставляет сигнал и данные в очередь нити

## ОБЗОР

```
#include <signal.h>
#include <pthread.h>
```

```
int pthread_sigqueue(pthread_t thread, int sig,
                     const union sigval value);
```

Компилируется и компонуется вместе с -pthread.

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

pthread_sigqueue(): _GNU_SOURCE

## ОПИСАНИЕ
Функция pthread_sigqueue() выполняет схожу с sigqueue(3) задачу, но посылает сигнал не процессу, а нити из того же процесса, что и вызвавшая функцию нить.

В аргументе thread указывается ID нити в том же процессе, что и вызывающий. В аргументе sig задаётся отправляемый сигнал. В аргументе value указываются данные, прилагаемые к сигналу; подробности смотрите в sigqueue(3).

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении pthread_sigqueue() возвращается 0; при ошибке возвращается номер ошибки.

## ОШИБКИ
EAGAIN

Достигнуто ограничение на количество сигналов в очереди (подробней об этом смотрите в signal(7)).

EINVAL

Значение sig некорректно.

ENOSYS

Функция pthread_sigqueue() не поддерживается в этой системе.

ESRCH

Некорректное значение thread.

## ВЕРСИИ
Функция pthread_sigqueue() впервые появилась в glibc 2.11.

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

pthread_sigqueue()

Безвредность в нитях

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
Эта функция является расширением GNU.

## ЗАМЕЧАНИЯ
Реализация pthread_sigqueue() в glibc выдаёт ошибку (EINVAL) при попытке послать сигналы реального времени, которые используются внутри реализации NPTL. Подробности смотрите в nptl(7).

## СМОТРИТЕ ТАКЖЕ
rt_tgsigqueueinfo(2), sigaction(2), pthread_sigmask(3), sigqueue(3), sigwait(3), pthreads(7), signal(7)

branch: sisyphus


title: pthread_spin_init(3)

summary: инициализирует или уничтожает

text:
# pthread_spin_init(3)

## ИМЯ
pthread_spin_init, pthread_spin_destroy - инициализирует или уничтожает циклическую блокировку

## ОБЗОР

```
#include <pthread.h>
```

```
int pthread_spin_init(pthread_spinlock_t *lock, int pshared);
int pthread_spin_destroy(pthread_spinlock_t *lock);
```

Компилируется и компонуется вместе с -pthread.

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

pthread_spin_init(), pthread_spin_destroy():

_POSIX_C_SOURCE >= 200112L

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

Функция pthread_spin_init() выделяет ресурсы, требуемые для работы циклической блокировки, на которую указывает lock, и инициализирует блокировку в неблокированном состоянии. В аргументе pshared должно быть одно из следующих значений:

PTHREAD_PROCESS_PRIVATE

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

PTHREAD_PROCESS_SHARED

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

Вызов pthread_spin_init() с уже инициализированной циклической блокировкой приводит к непредсказуемому поведению.

Функция pthread_spin_destroy() уничтожает ранее инициализированную циклическую блокировку, освобождая все выделенные ей ресурсы. Уничтожение ещё не инициализированной циклической блокировки или уничтожение циклической блокировки, которая захвачена другой нитью,приводит к непредсказуемым результатам.

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

Результат выполнения операций pthread_spin_lock(3), pthread_spin_unlock(3) и pthread_spin_destroy(3) с копией объекта, на который указывает lock, не определён.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении эти функции возвращают ноль. При ошибке возвращается номер ошибки. Если ошибкой завершается pthread_spin_init(), то инициализация блокировки не происходит.

## ОШИБКИ
Функция pthread_spin_init() может завершаться со следующими ошибками:

EAGAIN

В системе не хватает ресурсов для инициализации новой циклической блокировки.

ENOMEM

Недостаточно памяти для инициализации циклической блокировки.

## ВЕРСИИ
Эти функции впервые появились в glibc 2.2.

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001.

Поддержка общих для процессов циклических блокировок указана в POSIX. Она поддерживается реализацией glibc.

## ЗАМЕЧАНИЯ
Циклические блокировки должны использоваться вместе с алгоритмами выполнения реального времени (SCHED_FIFO или, возможно, SCHED_RR). Использование циклических блокировок с недерминированными алгоритмами планирования, такими как SCHED_OTHER, вероятно, указывают на ошибки при проектировании. Проблема в том, что если нить, выполняющаяся по такому алгоритму, вытеснится с ЦП в момент когда она удерживает циклическую блокировку, остальные нити будут впустую тратить время на ожидание блокировки, пока держатель не будет запланирован к выполнению и не освободит блокировку.

Если нити создают ситуацию взаимной блокировки при работе с циклическими блокировками, то эти нити будут ждать блокировку бесконечно потребляя время ЦП.

Циклические блокировки пользовательского пространства не применяются в качестве обычного решения по блокировкам. Они, по определению, подвержены смене приоритетов и неограниченны по времени ожидания. Программист, использующий циклические блокировки, должен быть исключительно осмотрителен не только с кодом, но и с настройкой системы, размещением нити и назначением приоритета.

## СМОТРИТЕ ТАКЖЕ
pthread_mutex_init(3), pthread_mutex_lock(3), pthread_spin_lock(3), pthread_spin_unlock(3), pthreads(7)


title: pthread_spin_lock(3)

summary: блокирует и

text:
# pthread_spin_lock(3)

## ИМЯ
pthread_spin_lock, pthread_spin_trylock, pthread_spin_unlock - блокирует и разблокирует блокировку циклически (spin lock)

## ОБЗОР

```
#include <pthread.h>
```

```
int pthread_spin_lock(pthread_spinlock_t *lock);
int pthread_spin_trylock(pthread_spinlock_t *lock);
int pthread_spin_unlock(pthread_spinlock_t *lock);
```

Компилируется и компонуется вместе с -pthread.

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

pthread_spin_lock(), pthread_spin_trylock():

_POSIX_C_SOURCE >= 200112L

## ОПИСАНИЕ
Функция pthread_spin_lock() блокирует циклическую блокировку (spin lock), на которую указывает lock. Если циклическая блокировка разблокирована, то вызывающая нить сразу же захватывает блокировку. Если циклическая блокировка заблокирована, то проверка блокировки продолжается до тех пор, пока она не освободится, и в этот момент вызывающая нить захватит блокировку.

Вызов pthread_spin_lock() для блокировки, которая уже захвачена вызывающим или не была инициализирована с помощью pthread_spin_init(3), приводит к непредсказуемому поведению.

Функция pthread_spin_trylock() подобна pthread_spin_lock(), за исключением того, что если циклическая блокировка, на которую указывает lock заблокирована, то вместо зацикливания вызов завершается с ошибкой EBUSY.

Функция pthread_spin_unlock() разблокирует циклическую блокировку, на которую указывает lock. Если какая-то нить зациклена в ожидании блокировки, то она захватит блокировку.

Вызов pthread_spin_unlock() для блокировки, которая не была захвачена вызывающим, приводит к непредсказуемому поведению.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении эти функции возвращают ноль. При ошибке возвращается номер ошибки.

## ОШИБКИ
Функция pthread_spin_lock() может завершаться со следующими ошибками:

EDEADLOCK

Система обнаружила условие взаимной блокировки.

Функция pthread_spin_trylock() может завершаться со следующими ошибками:

EBUSY

Циклическая блокировка уже заблокирована другой нитью.

## ВЕРСИИ
Эти функции впервые появились в glibc 2.2.

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001.

## ЗАМЕЧАНИЯ
Применение любой из описанных в этой странице функций к не инициализированной циклической блокировке приведёт к непредсказуемому поведению.

Внимательно прочитайте ЗАМЕЧАНИЯ в pthread_spin_init(3).

## СМОТРИТЕ ТАКЖЕ
pthread_spin_destroy(3), pthread_spin_init(3), pthreads(7)


title: pthread_testcancel(3)

summary: доставляет ожидающий запрос отмены

text:
# pthread_testcancel(3)

## ИМЯ
pthread_testcancel - доставляет ожидающий запрос отмены

## ОБЗОР

```
#include <pthread.h>
```

```
void pthread_testcancel(void);
```

```
Компилируется и компонуется вместе с -pthread.
```

## ОПИСАНИЕ
Вызов pthread_testcancel() создаёт точку отмены в вызвавшей нити, из-за чего нить, в выполняемом коде которой нет точек отмены, ответит на запрос отмены.

Если отменяемость выключена (с помощью pthread_setcancelstate(3)) или нет ожидающего запроса отмены, то функция pthread_testcancel() ничего не делает.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Эта функция не возвращает значения. Если вызвавшая нить отменяется из-за вызова этой функции, то функция не возвращает управление.

## ОШИБКИ
Данная функция всегда завершается успешно.

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

pthread_testcancel()

Безвредность в нитях

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008.

## ПРИМЕР
See pthread_cleanup_push(3).

## СМОТРИТЕ ТАКЖЕ
pthread_cancel(3), pthread_cleanup_push(3), pthread_setcancelstate(3), pthreads(7)


title: pthread_tryjoin_np(3)

summary: пытается присоединиться к

text:
# pthread_tryjoin_np(3)

## ИМЯ
pthread_tryjoin_np, pthread_timedjoin_np - пытается присоединиться к завершённой нити

## ОБЗОР

```
#define _GNU_SOURCE             /* Смотрите feature_test_macros(7) */
#include <pthread.h>
```

```
int pthread_tryjoin_np(pthread_t thread, void **retval);
```

```
int pthread_timedjoin_np(pthread_t thread, void **retval,
                         const struct timespec *abstime);
```

Компилируется и компонуется вместе с -pthread.

## ОПИСАНИЕ
Эти функции работают также как pthread_join(3) за исключением различий, описанных в данной справочной странице.

Функция pthread_tryjoin_np() выполняет неблокирующую присоединение к нити thread, возвращая в *retval код выхода нити. Если thread ещё не завершилась, то вместо блокировки, как это делает pthread_join(3), вызов возвращает ошибку.

Функция pthread_timedjoin_np() выполняет присоединение-с-ожиданием. Если thread ещё не завершилась, то вызов блокируется на максимальное время, заданное в abstime. Если время истекло до завершения thread, то вызов возвращает ошибку. Аргумент abstime представляет собой структуру представления абсолютного времени, измеряемого с начала Эпохи (смотрите time(2)):

```
struct timespec {

    time_t tv_sec;     /* секунды */

    long   tv_nsec;    /* наносекунды */
};
```

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении эти функции возвращают 0; при ошибке возвращается номер ошибки.

## ОШИБКИ
Эти функции могут завершиться с теми же ошибками что и pthread_join(3). Дополнительно, функция pthread_tryjoin_np() может завершиться со следующей ошибкой:

EBUSY

Нить thread не завершилась на момент вызова.

Дополнительно, функция pthread_timedjoin_np() может завершиться со следующими ошибками:

ETIMEDOUT

Истёк период ожидания раньше завершения thread.

EINVAL

Некорректное значение abstime (tv_sec меньше 0 или tv_nsec больше 1e9).

Функция pthread_timedjoin_np() никогда не возвращает ошибку EINTR.

## ВЕРСИИ
Эти функции впервые появились в glibc 2.3.3.

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

pthread_tryjoin_np(), pthread_timedjoin_np()

Безвредность в нитях

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
Данные функции являются не стандартизированными расширениями GNU, о чём свидетельствует наличие суффикса «_np» (nonportable).

## ПРИМЕР
Следующий код ждёт присоединения к нити не более 5 секунд:

```
struct timespec ts;
int s;
...
if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {

    /* обработка ошибки */
}
ts.tv_sec += 5;
s = pthread_timedjoin_np(thread, NULL, &ts);
if (s != 0) {

    /* обработка ошибки */
}
```

## СМОТРИТЕ ТАКЖЕ
clock_gettime(2), pthread_exit(3), pthread_join(3), pthreads(7)


title: pthread_yield(3)

summary: освобождает процессор

text:
# pthread_yield(3)

## ИМЯ
pthread_yield - освобождает процессор

## ОБЗОР

```
#define _GNU_SOURCE             /* Смотрите feature_test_macros(7) */
#include <pthread.h>
```

```
int pthread_yield(void);
```

Компилируется и компонуется вместе с -pthread.

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

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении pthread_yield() возвращается 0; при ошибке возвращается номер ошибки.

## ОШИБКИ
В Linux эта функция всегда выполняется успешно (но в переносимых приложениях нужно учитывать возможность возврата ошибки).

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

pthread_yield()

Безвредность в нитях

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
Эта функция является нестандартной, но присутствует в некоторых других системах. Вместо неё используйте стандартный вызов sched_yield(2).

## ЗАМЕЧАНИЯ
В Linux эта функция реализована как вызов sched_yield(2).

Функция pthread_yield() предназначена для использования с алгоритмами планирования реального времени (т. е., SCHED_FIFO или SCHED_RR). Использование pthread_yield() с недерминированными алгоритмами планирования, такими как SCHED_OTHER, не определено и указывает на, вероятно, неправильно разработанное приложение.

## СМОТРИТЕ ТАКЖЕ
sched_yield(2), pthreads(7), sched(7)


ptsname

title: ptsname(3)

summary: возвращает имя подчинённого псевдо\-терминала

text:
# ptsname(3)

## ИМЯ
ptsname, ptsname_r - возвращает имя подчинённого псевдо-терминала

## ОБЗОР
\#include <stdlib.h>

char *ptsname(int fd);

int ptsname_r(int fd, char *buf, size_t buflen);

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

ptsname():

начиная с glibc 2.24:

_XOPEN_SOURCE >= 500 ||

(_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED)

glibc 2.23 и старее:

_XOPEN_SOURCE

ptsname_r():

_GNU_SOURCE

## ОПИСАНИЕ
Функция ptsname() возвращает имя устройства подчинённого псевдо-терминала, соответствующего главному, который указан в fd.

Функция ptsname_r() является реентерабельным эквивалентном ptsname(). Она сохраняет имя устройства подчинённого псевдо-терминала в виде строки (завершающейся null) в буфер, указанный в buf. В аргументе buflen задаётся количество байт, доступных в buf.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении ptsname() возвращает указатель на строку в статическом хранилище, которая будет перезаписана последующими вызовами. Данный указатель не нужно освобождать. При ошибке возвращается NULL.

При успешном выполнении ptsname_r() возвращает 0. При ошибке возвращается ненулевое значение и в errno записывается номер ошибки.

## ОШИБКИ
EINVAL

(только ptsname_r()) Значение buf равно NULL (эта ошибка возвращается только в glibc 2.25 и старее).

ENOTTY

Значение fd не ссылается на устройство главного псевдо-терминала.

ERANGE

(только ptsname_r()) Значение buf слишком мало.

## ВЕРСИИ
Функция ptsname() появилась в glibc версии 2.1.

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

ptsname()

Безвредность в нитях

MT-Unsafe race:ptsname

ptsname_r()

Безвредность в нитях

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
ptsname():

POSIX.1-2001, POSIX.1-2008.

Функция ptsname() является частью поддержки псевдо-терминалов UNIX 98 (смотрите pts(4)).

Функция ptsname_r() является расширением Linux, которую предполагается включить в следующую большую версию POSIX.1 (Issue 8). Версия этой функции описана в Tru64 и HP-UX, но в их реализациях при ошибке возвращается -1, а в errno записывается номер ошибки. Не используйте эту функцию в переносимых программах.

## СМОТРИТЕ ТАКЖЕ
grantpt(3), posix_openpt(3), ttyname(3), unlockpt(3), pts(4), pty(7)


putenv

title: putenv(3)

text:
# putenv(3)

## ИМЯ
putenv - изменяет или добавляет переменную окружения

## ОБЗОР

```
#include <stdlib.h>
```

```
int putenv(char *string);
```

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

putenv(): _XOPEN_SOURCE

|| /* начиная с glibc 2.19: */ _DEFAULT_SOURCE

|| /* версии glibc <= 2.19: */ _SVID_SOURCE

## ОПИСАНИЕ
Функция putenv() добавляет или изменяет значение переменных окружения. Аргумент string должен быть представлен в форме name=value. Если переменной с именем name нет в окружении, то string добавляется к окружению. Если переменная name уже существует, то значение name в окружении изменяется на value. Строка, на которую указывает string, становится частью окружения, так что её изменение приведёт к изменению окружения.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Функция putenv() возвращает ноль при успешном выполнении и не ноль в противном случае. При ошибке errno отражает причину ошибки.

## ОШИБКИ
ENOMEM

Недостаточно памяти под новое окружение.

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

putenv()

Безвредность в нитях

MT-Unsafe const:env

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008, SVr4, 4.3BSD.

## ЗАМЕЧАНИЯ
От функции putenv() не требуется быть реентерабельной, и она такова в glibc 2.0, но в glibc 2.1 она реентерабельна.

Начиная с версии 2.1.2 glibc соответствует SUSv2: используется указатель string, передаваемый putenv(). В частности, эта строка становится частью окружения; последующее её изменение приводит к изменению окружения. Таким образом, ошибочным будет вызывать putenv() с автоматической переменной в качестве аргумента, так как после возврата из вызвавшей функции строка string является частью окружения. Однако, версии glibc 2.0 по 2.1.1 работают по-другому: используется копия строки. С одной стороны, это вызывает утечку памяти, с другой стороны, это не соответствует SUSv2.

В версии 4.4BSD как и в glibc 2.0 используется копия.

В SUSv2 удалено const из прототипа и это сделано в glibc 2.1.3.

Реализация библиотеки GNU C предоставляет нестандартное расширение. Если string не включает знака равно:

```
putenv("NAME");
```

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

## СМОТРИТЕ ТАКЖЕ
clearenv(3), getenv(3), setenv(3), unsetenv(3), environ(7)


putgrent

title: putgrent(3)

summary: записывает базу данных групп в файл

text:
# putgrent(3)

## ИМЯ
putgrent - записывает базу данных групп в файл

## ОБЗОР
\#define _GNU_SOURCE /* смотрите feature_test_macros(7) */

\#include <grp.h>

int putgrent(const struct group *grp, FILE *stream);

## ОПИСАНИЕ
Функция putgrent() ответная часть fgetgrent(3). Она записывает содержимое переданной struct group в stream. Список членов группы должен завершаться NULL или быть инициализированным NULL.

Структура struct group определена следующим образом:

```
struct group {

    char   *gr_name;      /* имя группы */

    char   *gr_passwd;    /* пароль группы */

    gid_t   gr_gid;       /* идентификатор группы */

    char  **gr_mem;       /* члены группы */
};
```

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Функция возвращает ноль при успешном выполнении и ненулевое значение при ошибке.

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

putgrent()

Безвредность в нитях

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
Эта функция является расширением GNU.

## СМОТРИТЕ ТАКЖЕ
fgetgrent(3), getgrent(3), group(5)


putpwent

title: putpwent(3)

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

text:
# putpwent(3)

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

## ОБЗОР

```
#include <stdio.h>
#include <sys/types.h>
#include <pwd.h>
```

```
int putpwent(const struct passwd *p, FILE *stream);
```

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

putpwent():

начиная с glibc 2.19:

_DEFAULT_SOURCE

в glibc 2.19 и старее:

_SVID_SOURCE

## ОПИСАНИЕ
Функция putpwent() выполняет запись элемента пароля из структуры p в файл, связанный с stream.

Структура passwd определена в <pwd.h> таким образом:

```
struct passwd {

    char    *pw_name;        /* имя пользователя */

    char    *pw_passwd;      /* пароль пользователя */

    uid_t    pw_uid;         /* идентификатор пользователя */

    gid_t    pw_gid;         /* идентификатор группы */

    char    *pw_gecos;       /* настоящее имя */

    char    *pw_dir;         /* домашний каталог */

    char    *pw_shell;       /* программная оболочка */
};
```

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Функция putpwent() возвращает ноль при успешном выполнении и -1 в противном случае. При ошибке errno отражает причину ошибки.

## ОШИБКИ
EINVAL

Неверное значение (NULL) аргумента.

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

putpwent()

Безвредность в нитях

MT-Safe locale

## СООТВЕТСТВИЕ СТАНДАРТАМ
SVr4.

## СМОТРИТЕ ТАКЖЕ
endpwent(3), fgetpwent(3), getpw(3), getpwent(3), getpwnam(3), getpwuid(3), setpwent(3)


puts

title: puts(3)

summary: вывод символов и строк

text:
# puts(3)

## ИМЯ
fputc, fputs, putc, putchar, puts - вывод символов и строк

## ОБЗОР

```
#include <stdio.h>
```

```
int fputc(int c, FILE *stream);
```

```
int fputs(const char *s, FILE *stream);
```

```
int putc(int c, FILE *stream);
```

```
int putchar(int c);
```

```
int puts(const char *s);
```

## ОПИСАНИЕ
Функция fputc() записывает символ c, преобразуя его в unsigned char, в stream.

Функция fputs() записывает строку s в stream без добавления нулевого байта ('\0').

Функция putc() является эквивалентом fputc() за исключением того, что она может быть реализована в качестве макрокоманды, которая проверяет stream более одного раза.

Вызов putchar(c) является эквивалентом putc(c, stdout).

Функция puts() записывает строку s и завершающую новую строку в stdout.

Вызовы описанных здесь функций могут быть смешаны между собой и вызовами других функций вывода из библиотеки stdio в пределах одного и того же потока вывода.

Для неблокирующих аналогов, см. unlocked_stdio(3).

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Функции fputc(), putc() and putchar() возвращают записанный символ, преобразованный из unsigned char в int или EOF в случае ошибки.

Функции puts() и fputs() возвращают неотрицательное число в случае успеха или EOF в случае ошибки.

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

fputc(), fputs(), putc(), putchar(), puts()

Безвредность в нитях

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008, C89, C99.

## ДЕФЕКТЫ
Не рекомендуется смешивать вызовы функций вывода из библиотеки stdio с вызовами write(2) для файлового дескриптора, связанного с одним и тем же потоком вывода. Результаты могут быть непредсказуемыми и, очень вероятно, совсем не теми, что вы ожидали увидеть.

## СМОТРИТЕ ТАКЖЕ
write(2), ferror(3), fgets(3), fopen(3), fputwc(3), fputws(3), fseek(3), fwrite(3), putwchar(3), scanf(3), unlocked_stdio(3)


putwchar

title: putwchar(3)

text:
# putwchar(3)

## ИМЯ
putwchar - записывает широкий символ в стандартный выходной поток

## ОБЗОР

```
#include <wchar.h>
```

```
wint_t putwchar(wchar_t wc);
```

## ОПИСАНИЕ
Функция putwchar — это эквивалент функции putchar(3), но для широких символов. Она записывает широкий символ wc в поток stdout. Если значение ferror(stdout) истинно, то возвращается WEOF. Если при преобразовании в широкий символ возникает ошибка, то значение переменной errno устанавливается равным EILSEQ и возвращается WEOF. В любом другом случае возвращается wc.

Неблокирующий аналог смотрите в unlocked_stdio(3).

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении putwchar() возвращается wc; при ошибке возвращается WEOF.

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

putwchar()

Безвредность в нитях

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008, C99.

## ЗАМЕЧАНИЯ
Поведение putwchar() зависит от категории LC_CTYPE текущей локали.

Закономерно ожидать, что putwchar() на самом деле пишет многобайтовую последовательность, соответствующую широкому символу wc.

## СМОТРИТЕ ТАКЖЕ
fputwc(3), unlocked_stdio(3)


qecvt

title: qecvt(3)

text:
# qecvt(3)

## ИМЯ
qecvt, qfcvt, qgcvt - преобразуют число с плавающей точкой в строку

## ОБЗОР
\#include <stdlib.h>

char *qecvt(long double number, int ndigits, int *decpt, int *sign);

char *qfcvt(long double number, int ndigits, int *decpt, int *sign);

char *qgcvt(long double number, int ndigit, char *buf);

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

qecvt(), qfcvt(), qgcvt(): _SVID_SOURCE

## ОПИСАНИЕ
Функции qecvt(), qfcvt() и qgcvt() идентичны ecvt(3), fcvt(3) и gcvt(3), соответственно, за исключением того, что аргумент number имеет тип long double. Смотрите ecvt(3) и gcvt(3).

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

qecvt()

Безвредность в нитях

MT-Unsafe race:qecvt

qfcvt()

Безвредность в нитях

MT-Unsafe race:qfcvt

qgcvt()

Безвредность в нитях

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
SVr4. Отсутствуют в наиболее распространённых реализациях UNIX, но есть в SunOS. Поддерживаются в glibc.

## ЗАМЕЧАНИЯ
Данные функции устарели. Вместо них рекомендуется использовать snprintf(3).

## СМОТРИТЕ ТАКЖЕ
ecvt(3), ecvt_r(3), gcvt(3), sprintf(3)


qsort

title: qsort(3)

summary: сортировка массива

text:
# qsort(3)

## ИМЯ
qsort, qsort_r - сортировка массива

## ОБЗОР

```
#include <stdlib.h>
```

```
void qsort(void *base, size_t nmemb, size_t size,
           int (*compar)(const void *, const void *));
```

```
void qsort_r(void *base, size_t nmemb, size_t size,
           int (*compar)(const void *, const void *, void *),
           void *arg);
```

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

qsort_r(): _GNU_SOURCE

## ОПИСАНИЕ
Функция qsort() сортирует массив из nmemb размером size. Аргумент base указывает на начало массива.

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

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

Функция qsort_r() идентична qsort(), за исключением того, что в функцию сравнения compar добавлен третий аргумент. Указатель передаётся в функцию сравнения через аргумент arg. Таким образом, функции сравнения не требуется глобальные переменные для передачи произвольных аргументов, и поэтому она реентерабельна и её можно безопасно использовать в нитях.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Функции qsort() и qsort_r() ничего не возвращают.

## ВЕРСИИ
Функция qsort_r() впервые появилась в glibc 2.8.

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

qsort(), qsort_r()

Безвредность в нитях

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
qsort(): POSIX.1-2001, POSIX.1-2008, C89, C99, SVr4, 4.3BSD.

## ЗАМЕЧАНИЯ
Для сравнения C-строк в качестве функции сравнения можно использовать strcmp(3), как это указано ниже.

## ПРИМЕР
Для примера использования смотрите пример, указанный в bsearch(3).

Еще один пример программы, сортирующей строки, переданные в качестве аргументов через командную строку:

```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int
cmpstringp(const void *p1, const void *p2)
{

    /* Аргументами данной функции являются "pointers to

       pointers to char", однако аргументами strcmp(3)

       являются "pointers to char", так что здесь происходит

       преобразование и разыменовывание ссылок */

    return strcmp(* (char * const *) p1, * (char * const *) p2);
}
int
main(int argc, char *argv[])
{

    int j;

    if (argc < 2) {

        fprintf(stderr, "Использование: %s <string>...\n", argv[0]);

        exit(EXIT_FAILURE);

    }

    qsort(&argv[1], argc - 1, sizeof(char *), cmpstringp);

    for (j = 1; j < argc; j++)

        puts(argv[j]);

    exit(EXIT_SUCCESS);
}
```

## СМОТРИТЕ ТАКЖЕ
sort(1), alphasort(3), strcmp(3), versionsort(3)


queue

title: queue(3)

text:
# queue(3)

## ИМЯ
SLIST_EMPTY, SLIST_ENTRY, SLIST_FIRST, SLIST_FOREACH, SLIST_HEAD, SLIST_HEAD_INITIALIZER, SLIST_INIT, SLIST_INSERT_AFTER, SLIST_INSERT_HEAD, SLIST_NEXT, SLIST_REMOVE_HEAD, SLIST_REMOVE, STAILQ_CONCAT, STAILQ_EMPTY, STAILQ_ENTRY, STAILQ_FIRST, STAILQ_FOREACH, STAILQ_HEAD, STAILQ_HEAD_INITIALIZER, STAILQ_INIT, STAILQ_INSERT_AFTER, STAILQ_INSERT_HEAD, STAILQ_INSERT_TAIL, STAILQ_NEXT, STAILQ_REMOVE_HEAD, STAILQ_REMOVE, LIST_EMPTY, LIST_ENTRY, LIST_FIRST, LIST_FOREACH, LIST_HEAD, LIST_HEAD_INITIALIZER, LIST_INIT, LIST_INSERT_AFTER, LIST_INSERT_BEFORE, LIST_INSERT_HEAD, LIST_NEXT, LIST_REMOVE, TAILQ_CONCAT, TAILQ_EMPTY, TAILQ_ENTRY, TAILQ_FIRST, TAILQ_FOREACH, TAILQ_FOREACH_REVERSE, TAILQ_HEAD, TAILQ_HEAD_INITIALIZER, TAILQ_INIT, TAILQ_INSERT_AFTER, TAILQ_INSERT_BEFORE, TAILQ_INSERT_HEAD, TAILQ_INSERT_TAIL, TAILQ_LAST, TAILQ_NEXT, TAILQ_PREV, TAILQ_REMOVE, TAILQ_SWAP — реализации односвязных списков, односвязных хвостовых очередей, списков и хвостовых очередей

## ОБЗОР
<sys/queue.h> SLIST_EMPTY(SLIST_HEAD *head) SLIST_ENTRY(TYPE) SLIST_FIRST(SLIST_HEAD *head) SLIST_FOREACH(TYPE *var, SLIST_HEAD *head, SLIST_ENTRY NAME) SLIST_HEAD(HEADNAME, TYPE) SLIST_HEAD_INITIALIZER(SLIST_HEAD head) SLIST_INIT(SLIST_HEAD *head) SLIST_INSERT_AFTER(TYPE *listelm, TYPE *elm, SLIST_ENTRY NAME) SLIST_INSERT_HEAD(SLIST_HEAD *head, TYPE *elm, SLIST_ENTRY NAME) SLIST_NEXT(TYPE *elm, SLIST_ENTRY NAME) SLIST_REMOVE_HEAD(SLIST_HEAD *head, SLIST_ENTRY NAME) SLIST_REMOVE(SLIST_HEAD *head, TYPE *elm, TYPE, SLIST_ENTRY NAME) STAILQ_CONCAT(STAILQ_HEAD *head1, STAILQ_HEAD *head2) STAILQ_EMPTY(STAILQ_HEAD *head) STAILQ_ENTRY(TYPE) STAILQ_FIRST(STAILQ_HEAD *head) STAILQ_FOREACH(TYPE *var, STAILQ_HEAD *head, STAILQ_ENTRY NAME) STAILQ_HEAD(HEADNAME, TYPE) STAILQ_HEAD_INITIALIZER(STAILQ_HEAD head) STAILQ_INIT(STAILQ_HEAD *head) STAILQ_INSERT_AFTER(STAILQ_HEAD *head, TYPE *listelm, TYPE *elm, STAILQ_ENTRY NAME) STAILQ_INSERT_HEAD(STAILQ_HEAD *head, TYPE *elm, STAILQ_ENTRY NAME) STAILQ_INSERT_TAIL(STAILQ_HEAD *head, TYPE *elm, STAILQ_ENTRY NAME) STAILQ_NEXT(TYPE *elm, STAILQ_ENTRY NAME) STAILQ_REMOVE_HEAD(STAILQ_HEAD *head, STAILQ_ENTRY NAME) STAILQ_REMOVE(STAILQ_HEAD *head, TYPE *elm, TYPE, STAILQ_ENTRY NAME) LIST_EMPTY(LIST_HEAD *head) LIST_ENTRY(TYPE) LIST_FIRST(LIST_HEAD *head) LIST_FOREACH(TYPE *var, LIST_HEAD *head, LIST_ENTRY NAME) LIST_HEAD(HEADNAME, TYPE) LIST_HEAD_INITIALIZER(LIST_HEAD head) LIST_INIT(LIST_HEAD *head) LIST_INSERT_AFTER(TYPE *listelm, TYPE *elm, LIST_ENTRY NAME) LIST_INSERT_BEFORE(TYPE *listelm, TYPE *elm, LIST_ENTRY NAME) LIST_INSERT_HEAD(LIST_HEAD *head, TYPE *elm, LIST_ENTRY NAME) LIST_NEXT(TYPE *elm, LIST_ENTRY NAME) LIST_REMOVE(TYPE *elm, LIST_ENTRY NAME) LIST_SWAP(LIST_HEAD *head1, LIST_HEAD *head2, TYPE, LIST_ENTRY NAME) TAILQ_CONCAT(TAILQ_HEAD *head1, TAILQ_HEAD *head2, TAILQ_ENTRY NAME) TAILQ_EMPTY(TAILQ_HEAD *head) TAILQ_ENTRY(TYPE) TAILQ_FIRST(TAILQ_HEAD *head) TAILQ_FOREACH(TYPE *var, TAILQ_HEAD *head, TAILQ_ENTRY NAME) TAILQ_FOREACH_REVERSE(TYPE *var, TAILQ_HEAD *head, HEADNAME, TAILQ_ENTRY NAME) TAILQ_HEAD(HEADNAME, TYPE) TAILQ_HEAD_INITIALIZER(TAILQ_HEAD head) TAILQ_INIT(TAILQ_HEAD *head) TAILQ_INSERT_AFTER(TAILQ_HEAD *head, TYPE *listelm, TYPE *elm, TAILQ_ENTRY NAME) TAILQ_INSERT_BEFORE(TYPE *listelm, TYPE *elm, TAILQ_ENTRY NAME) TAILQ_INSERT_HEAD(TAILQ_HEAD *head, TYPE *elm, TAILQ_ENTRY NAME) TAILQ_INSERT_TAIL(TAILQ_HEAD *head, TYPE *elm, TAILQ_ENTRY NAME) TAILQ_LAST(TAILQ_HEAD *head, HEADNAME) TAILQ_NEXT(TYPE *elm, TAILQ_ENTRY NAME) TAILQ_PREV(TYPE *elm, HEADNAME, TAILQ_ENTRY NAME) TAILQ_REMOVE(TAILQ_HEAD *head, TYPE *elm, TAILQ_ENTRY NAME) TAILQ_SWAP(TAILQ_HEAD *head1, TAILQ_HEAD *head2, TYPE, TAILQ_ENTRY NAME)

## ОПИСАНИЕ
Данные макросы определяют и управляют четырьмя типами структур данных: односвязными списками, односвязными хвостовыми очередями, списками и хвостовыми очередями. Все четыре структуры поддерживают следующие возможности:

- Вставка нового элемента в начало списка.

- Вставка нового элемента после любого элемента списка.

- Удаление элемента из начала списка за время O(1).

- Обход списка из начала в конец.

- Перестановка содержимого двух списков.

Односвязные списки — самая простая из этих четырёх структур данных и поддерживает только указанные выше возможности. Односвязные списки идеальны для приложений с большими наборами данных, из которых производится очень мало удалений, или для реализации очереди LIFO (последним пришёл — первым ушёл). У односвязных списков есть дополнительное свойство:

- Удаление любого элемента списка за время O(n).

У односвязных хвостовых очередей есть дополнительные свойства:

- Добавление элементов в конец списка.

- Удаление любого элемента списка за время O(n).

- Возможность объединения.

Однако:

- При вставке элементов нужно указывать начало списка.

- Каждый начальный элемент требует двух указателей вместо одного.

- Код примерно на 15% больше и на 20% медленнее, чем для односвязных списков.

Односвязные хвостовые очереди идеальны для приложений с большими наборами данных из которых производится очень мало удалений, или для реализации очереди FIFO (первым пришёл — первым ушёл).

Все двусвязные типы структур данных (списки и хвостовые очереди) дополнительно позволяют:

- Вставку нового элемента перед любым элементом списка.

- Удаление любого элемента списка за время O(1).

Однако:

- Для каждого элемента требуется два указателя вместо одного.

- Размер кода и время выполнения операций (кроме удаления) удваивается, по сравнению с односвязными структурами данных.

Связные списки — самая простая из двусвязных структур данных. К указанным выше возможностям для них возможно:

- Обход в обратном направлении.

Однако:

- Для обхода в обратном направлении требуется указывать начало обхода и сам список.

У хвостовых очередей есть дополнительные свойства:

- Добавление элементов в конец списка.

- Обход может идти в обратном направлении, от конца к началу.

- Возможность объединения.

Однако:

- При вставке и удалении элементов нужно указывать начало списка.

- Каждый начальный элемент требует двух указателей вместо одного.

- Код примерно на 15% больше и на 20% медленнее, чем для односвязных списков.

В определениях макросов TYPE — это имя определяемое пользователем структуры, которая должна содержать поле типа SLIST_ENTRY, STAILQ_ENTRY, LIST_ENTRY или TAILQ_ENTRY, названное NAME. Аргумент HEADNAME — это имя определяемое пользователем структуры, которая должна быть объявлена с помощью макроса SLIST_HEAD, STAILQ_HEAD, LIST_HEAD или TAILQ_HEAD. Ниже показаны примеры использования этих макросов.

### Односвязные списки
Односвязный список начинается со структуры, определённой макросом SLIST_HEAD. В этой структуре содержится одиночный указатель на первый элемент списка. Элементы имеют по одной связи для минимизации занимаемого пространства, а дополнительный расход на операции с указателями равен O(n) при удалении произвольного элемента. Новые элементы можно добавлять в список после существующего элемента или в начало списка. Структура SLIST_HEAD объявляется следующим образом:

```
SLIST_HEAD(HEADNAME, TYPE) head;
```

где HEADNAME — имя определяемой структуры, а TYPE — тип элементов, объединяемых в список. Указатель на начало списка может в дальнейшем объявляться так:

```
struct HEADNAME *headp;
```

(Имена head и headp могут выбираться пользователем.)

Макрос SLIST_HEAD_INITIALIZER запускает инициализатор для head списка.

Макрос SLIST_EMPTY возвращает true, если в списке нет элементов.

Макрос SLIST_ENTRY объявляет структуру, которая добавляет элементы в список.

Макрос SLIST_FIRST возвращает первый элемент списка или NULL, если список пуст.

Макрос SLIST_FOREACH обходит список, на который ссылается head, от начало в конец, назначая var каждый элемент.

Макрос SLIST_INIT инициализирует список, на который ссылается head.

Макрос SLIST_INSERT_HEAD вставляет новый элемент elm в начало списка.

Макрос SLIST_INSERT_AFTER вставляет новый элемент elm за элементом listelm.

Макрос SLIST_NEXT возвращает следующий элемент списка.

Макрос SLIST_REMOVE_HEAD удаляет элемент elm из начала списка. В целях эффективности удаления элемента из начала списка нужно использовать именно этот макрос вместо обычного SLIST_REMOVE.

Макрос SLIST_REMOVE удаляет элемент elm из списка.

### Пример односвязного списка

```
SLIST_HEAD(slisthead, entry) head =
    SLIST_HEAD_INITIALIZER(head);
struct slisthead *headp;		/* начало односвязного
                                           списка */
struct entry {
	...
	SLIST_ENTRY(entry) entries;	/* односвязный список */
	...
} *n1, *n2, *n3, *np;

SLIST_INIT(&head);			/* инициализация списка */

n1 = malloc(sizeof(struct entry));	/* вставка начального элемента */
SLIST_INSERT_HEAD(&head, n1, entries);

n2 = malloc(sizeof(struct entry));	/* вставка последующих */
SLIST_INSERT_AFTER(n1, n2, entries);

SLIST_REMOVE(&head, n2, entry, entries);/* удаление */
free(n2);

n3 = SLIST_FIRST(&head);
SLIST_REMOVE_HEAD(&head, entries);	/* удаление начального элемента */
free(n3);
					/* обход из начала в конец */
SLIST_FOREACH(np, &head, entries)
	np-> ...

while (!SLIST_EMPTY(&head)) {		/* удаление списка */
	n1 = SLIST_FIRST(&head);
	SLIST_REMOVE_HEAD(&head, entries);
	free(n1);
}
```

### Односвязные хвостовые очереди
Односвязная хвостовая очередь начинается со структуры, определяемой макросом STAILQ_HEAD. В этой структуре содержится пара указателей, один на первый элемент хвостовой очереди, а другой на последний элемент. Элементы имеют по одной связи для минимизации занимаемого пространства, а дополнительный расход на операции с указателями равен O(n) при удалении произвольного элемента. Новые элементы можно добавлять в хвостовую очередь после существующего элемента, в начало или конец хвостовой очереди, Структура STAILQ_HEAD объявляется следующим образом:

```
STAILQ_HEAD(HEADNAME, TYPE) head;
```

где HEADNAME — имя определяемой структуры, а TYPE — тип связанных элементов в хвостовой очереди. Указатель на начало хвостовой очереди может в дальнейшем объявляться так:

```
struct HEADNAME *headp;
```

(Имена head и headp могут выбираться пользователем.)

Макрос STAILQ_HEAD_INITIALIZER запускает инициализатор для head хвостовой очереди.

Макрос STAILQ_CONCAT добавляет хвостовую очередь с началом head2 в конец очереди с началом head1, удаляя все элементы из первой.

Макрос STAILQ_EMPTY возвращает true, если в хвостовой очереди нет элементов.

Макрос STAILQ_ENTRY объявляет структуру, которая подключает элементы в хвостовую очередь.

Макрос STAILQ_FIRST возвращает первый элемент из хвостовой очереди или NULL, если очередь пуста.

Макрос STAILQ_FOREACH обходит хвостовую очередь, на которую ссылается head, из начала в конец, назначая var каждый элемент.

Макрос STAILQ_INIT инициализирует хвостовую очередь, на которую ссылается head.

Макрос STAILQ_INSERT_HEAD вставляет новый элемент I elm в начало хвостовой очереди.

Макрос STAILQ_INSERT_TAIL вставляет новый элемент elm в конец хвостовой очереди.

Макрос STAILQ_INSERT_AFTER вставляет новый элемент elm за элементом listelm.

Макрос STAILQ_NEXT возвращает следующий элемент из хвостовой очереди или NULL, если элемент последний.

Макрос STAILQ_REMOVE_HEAD удаляет элемент из начала хвостовой очереди. В целях эффективности удаления элемента из начала хвостовой очереди нужно использовать именно этот макрос вместо обычного STAILQ_REMOVE.

Макрос STAILQ_REMOVE удаляет элемент elm из хвостовой очереди.

### Пример односвязной хвостовой очереди

```
STAILQ_HEAD(stailhead, entry) head =
    STAILQ_HEAD_INITIALIZER(head);
struct stailhead *headp;		/* начало односвязной хвостовой
                               очереди */
struct entry {
	...
	STAILQ_ENTRY(entry) entries;	/* хвостовая очередь */
	...
} *n1, *n2, *n3, *np;

STAILQ_INIT(&head);			/* инициализация очереди */

n1 = malloc(sizeof(struct entry));	/* вставка начального элемента */
STAILQ_INSERT_HEAD(&head, n1, entries);

n1 = malloc(sizeof(struct entry));	/* вставка в очередь */
STAILQ_INSERT_TAIL(&head, n1, entries);

n2 = malloc(sizeof(struct entry));	/* вставка последующего */
STAILQ_INSERT_AFTER(&head, n1, n2, entries);
					/* удаление */
STAILQ_REMOVE(&head, n2, entry, entries);
free(n2);
					/* удаление из начала */
n3 = STAILQ_FIRST(&head);
STAILQ_REMOVE_HEAD(&head, entries);
free(n3);
					/* обход от начала в конец */
STAILQ_FOREACH(np, &head, entries)
	np-> ...
					/* удаление TailQ */
while (!STAILQ_EMPTY(&head)) {
	n1 = STAILQ_FIRST(&head);
	STAILQ_REMOVE_HEAD(&head, entries);
	free(n1);
}
					/* быстрое удаление TailQ */
n1 = STAILQ_FIRST(&head);
while (n1 != NULL) {
	n2 = STAILQ_NEXT(n1, entries);
	free(n1);
	n1 = n2;
}
STAILQ_INIT(&head);
```

### Списки
Список начинается структурой, определённой макросом LIST_HEAD. Эта структура содержит единственный указатель на первый элемент списка. Элементы дважды связаны, поэтому произвольный элемент можно удалить без прохода по всему списку. Новые элементы могут быть добавлены в список перед или после существующего элемента, а также в начало списка. Структура LIST_HEAD объявляется следующим образом:

```
LIST_HEAD(HEADNAME, TYPE) head;
```

где HEADNAME — имя определяемой структуры, а TYPE — тип элементов, объединяемых в список. Указатель на начало списка может в дальнейшем объявляться так:

```
struct HEADNAME *headp;
```

(Имена head и headp могут выбираться пользователем.)

Макрос LIST_HEAD_INITIALIZER запускает инициализатор для head списка.

Макрос LIST_EMPTY возвращает true, если в списке нет элементов.

Макрос LIST_ENTRY объявляет структуру, которая добавляет элементы в список.

Макрос LIST_FIRST возвращает первый элемент списка или NULL, если список пуст.

Макрос LIST_FOREACH обходит список, на который ссылается head, от начало в конец, назначая var каждый элемент.

Макрос LIST_INIT инициализирует список, на который ссылается head.

Макрос LIST_INSERT_HEAD вставляет новый элемент elm в начало списка.

Макрос LIST_INSERT_AFTER вставляет новый элемент elm за элементом listelm.

Макрос LIST_INSERT_AFTER вставляет новый элемент elm перед элементом listelm.

Макрос LIST_NEXT возвращает следующий элемент списка или NULL, если элемент последний.

Макрос LIST_REMOVE удаляет элемент elm из списка.

### Пример списка

```
LIST_HEAD(listhead, entry) head =
    LIST_HEAD_INITIALIZER(head);
struct listhead *headp;			/* начало списка */
struct entry {
	...
	LIST_ENTRY(entry) entries;	/* список */
	...
} *n1, *n2, *n3, *np, *np_temp;

LIST_INIT(&head);			/* инициализация списка */

n1 = malloc(sizeof(struct entry));	/* вставка в начало */
LIST_INSERT_HEAD(&head, n1, entries);

n2 = malloc(sizeof(struct entry));	/* вставка последующего */
LIST_INSERT_AFTER(n1, n2, entries);

n3 = malloc(sizeof(struct entry));	/* вставка перед */
LIST_INSERT_BEFORE(n2, n3, entries);

LIST_REMOVE(n2, entries);		/* удаление */
free(n2);
					/* обход из начала в конец */
LIST_FOREACH(np, &head, entries)
	np-> ...

while (!LIST_EMPTY(&head)) {		/* удаление списка */
	n1 = LIST_FIRST(&head);
	LIST_REMOVE(n1, entries);
	free(n1);
}

n1 = LIST_FIRST(&head);			/* быстрое удаление списка */
while (n1 != NULL) {
	n2 = LIST_NEXT(n1, entries);
	free(n1);
	n1 = n2;
}
LIST_INIT(&head);
```

### Хвостовые очереди
Хвостовая очередь начинается со структуры, определяемой макросом TAILQ_HEAD. Эта структура содержит пару указателей, один для первого элемента хвостовой очереди, а другой для последнего элемента хвостовой очереди. Элементы связаны дважды так, что любой элемент может быть удалён без прохождения по всей очереди. Новые элементы могут быть добавлены в хвостовую очередь перед и после существующего элемента, в конец или в начало очереди. Структура TAILQ_HEAD объявляется следующим образом:

```
TAILQ_HEAD(HEADNAME, TYPE) head;
```

где HEADNAME — имя определяемой структуры, а TYPE — тип связанных элементов в хвостовой очереди. Указатель на начало хвостовой очереди может в дальнейшем объявляться так:

```
struct HEADNAME *headp;
```

(Имена head и headp могут выбираться пользователем.)

Макрос TAILQ_HEAD_INITIALIZER запускает инициализатор для head хвостовой очереди.

Макрос TAILQ_CONCAT добавляет хвостовую очередь с началом head2 в конец очереди с началом head1, удаляя все элементы из первой.

Макрос TAILQ_EMPTY возвращает true, если в хвостовой очереди нет элементов.

Макрос TAILQ_ENTRY объявляет структуру, которая подключает элементы в хвостовую очередь.

Макрос TAILQ_FIRST возвращает первый элемент из хвостовой очереди или NULL, если очередь пуста.

Макрос TAILQ_FOREACH обходит хвостовую очередь, на которую ссылается head, из начала в конец, назначая var каждый элемент. Значение var равно NULL, если пройдена вся очередь или в ней нет элементов.

Макрос TAILQ_FOREACH_REVERSE обходит хвостовую очередь, на которую ссылается head, в обратном направлении, назначая var каждый элемент.

Макрос TAILQ_INIT инициализирует хвостовую очередь, на которую ссылается head.

Макрос TAILQ_INSERT_HEAD вставляет новый элемент I elm в начало хвостовой очереди.

Макрос TAILQ_INSERT_TAIL вставляет новый элемент elm в конец хвостовой очереди.

Макрос TAILQ_INSERT_AFTER вставляет новый элемент elm за элементом listelm.

Макрос TAILQ_INSERT_BEFORE вставляет новый элемент elm перед элементом listelm.

Макрос TAILQ_LAST возвращает последний элемент из хвостовой очереди или NULL, если очередь пуста.

Макрос TAILQ_NEXT возвращает следующий элемент из хвостовой очереди или NULL, если элемент последний.

Макрос TAILQ_PREV возвращает предыдущий элемент из хвостовой очереди или NULL, если элемент первый.

Макрос TAILQ_REMOVE удаляет элемент elm из хвостовой очереди.

Макрос TAILQ_SWAP меняет местами содержимое head1 и head2.

### Пример хвостовой очереди

```
TAILQ_HEAD(tailhead, entry) head =
    TAILQ_HEAD_INITIALIZER(head);
struct tailhead *headp;			/* начало хвостовой очереди */
struct entry {
	...
	TAILQ_ENTRY(entry) entries;	/* хвостовая очередь */
	...
} *n1, *n2, *n3, *np;

TAILQ_INIT(&head);			/* инициализация очереди */

n1 = malloc(sizeof(struct entry));	/* вставка в начало */
TAILQ_INSERT_HEAD(&head, n1, entries);

n1 = malloc(sizeof(struct entry));	/* вставка в конец */
TAILQ_INSERT_TAIL(&head, n1, entries);

n2 = malloc(sizeof(struct entry));	/* вставка последующего */
TAILQ_INSERT_AFTER(&head, n1, n2, entries);

n3 = malloc(sizeof(struct entry));	/* вставка перед */
TAILQ_INSERT_BEFORE(n2, n3, entries);

TAILQ_REMOVE(&head, n2, entries);	/* удаление */
free(n2);
					/* обход из начало в конец */
TAILQ_FOREACH(np, &head, entries)
	np-> ...
					/* обход в обратном направлении */
TAILQ_FOREACH_REVERSE(np, &head, tailhead, entries)
	np-> ...
					/* удаление TailQ */
while (!TAILQ_EMPTY(&head)) {
	n1 = TAILQ_FIRST(&head);
	TAILQ_REMOVE(&head, n1, entries);
	free(n1);
}
					/* быстрое удаление TailQ */
n1 = TAILQ_FIRST(&head);
while (n1 != NULL) {
	n2 = TAILQ_NEXT(n1, entries);
	free(n1);
	n1 = n2;
}

TAILQ_INIT(&head);
n2 = malloc(sizeof(struct entry));  /* вставка перед */
CIRCLEQ_INSERT_BEFORE(&head, n1, n2, entries);
                                    /* обход из начала в конец */
for (np = head.cqh_first; np != (void *)&head;
        np = np->entries.cqe_next)
    np-> ...
                                    /* обход в обратном направлении */
for (np = head.cqh_last; np != (void *)&head; np = np->entries.cqe_prev)
    np-> ...
                                    /* удаление */
while (head.cqh_first != (void *)&head)
    CIRCLEQ_REMOVE(&head, head.cqh_first, entries);
```

## СООТВЕТСТВИЕ СТАНДАРТАМ
Нет в POSIX.1, POSIX.1-2001 и POSIX.1-2008. Присутствует в BSD. Функции queue впервые появились в 4.4BSD.

## СМОТРИТЕ ТАКЖЕ
insque(3)


raise

title: raise(3)

summary: посылает сигнал вызывающему

text:
# raise(3)

## ИМЯ
raise - посылает сигнал вызывающему

## ОБЗОР

```
#include <signal.h>
```

```
int raise(int sig);
```

## ОПИСАНИЕ
Функция raise() посылает сигнал вызвавшему процессу или нити. В однонитевых программах это эквивалентно

```
kill(getpid(), sig);
```

В многонитевых программах это эквивалентно

```
pthread_kill(pthread_self(), sig);
```

Если из-за сигнала вызвался обработчик, то raise() вернёт управление только после завершения обработчика сигнала.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении функция raise() возвращает 0 или иное значение при ошибке.

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

raise()

Безвредность в нитях

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008, C89, C99.

## ЗАМЕЧАНИЯ
Начиная с версии 2.3.3 glibc реализует raise() с помощью tgkill(2), если ядро поддерживает этот системный вызов. Предыдущие версии glibc реализовали raise() с помощью kill(2).

## СМОТРИТЕ ТАКЖЕ
getpid(2), kill(2), sigaction(2), signal(2), pthread_kill(3), signal(7)


rand

title: rand(3)

summary: генератор псевдослучайных чисел

text:
# rand(3)

## ИМЯ
rand, rand_r, srand - генератор псевдослучайных чисел

## ОБЗОР

```
#include <stdlib.h>
```

```
int rand(void);
```

```
int rand_r(unsigned int *seedp);
```

```
void srand(unsigned int seed);
```

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

rand_r():

начиная с glibc 2.24:

_POSIX_C_SOURCE >= 199506L

в glibc 2.23 и старее

_POSIX_C_SOURCE

## ОПИСАНИЕ
Функция rand() возвращает псевдослучайное целое число в диапазоне от нуля до RAND_MAX включительно (т. е., из математического диапазона [0, RAND_MAX]).

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

Если основа не задана, то функция rand() автоматически устанавливает её равной 1.

Функция rand() не реентерабельная, так как она использует скрытое состояние, которое изменяется с каждым вызовом. Это может быть как просто значение основы, так и что-то более сложное. Чтобы получить воспроизводимое поведение в многонитевом приложении такое состояние нужно создать явным образом; это можно сделать с помощью реентерабельной функции rand_r().

Как и rand(), rand_r() возвращает псевдослучайное целое число из диапазона [0, RAND_MAX]. Аргумент seedp является указателем на число unsigned int, которое используется для хранения состояния между вызовами. Если rand_r() вызывается с одинаковым начальным значением целого, на которое указывает seedp, и это значение не изменяется между вызовами, то результатом будет одинаковая псевдослучайная последовательность.

Значение, на которое указывает аргумент seedp для rand_r(), предоставляет только очень малую часть состояния, поэтому данная функция будет очень не случайным псевдослучайным генератором. Используйте вместо неё drand48_r(3).

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Функции rand() и rand_r() возвращают значение в промежутке от 0 до RAND_MAX (включительно). Функция srand() не возвращает результат.

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

rand(), rand_r(), srand()

Безвредность в нитях

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
Функции rand() и srand() описаны в SVr4, 4.3BSD, C89, C99, POSIX.1-2001. Функция rand_r() описана в POSIX.1-2001. В POSIX.1-2008 функция rand_r() помечена как устаревшая.

## ЗАМЕЧАНИЯ
Версия функций rand() и srand() в библиотеке Си для Linux использует тот же генератор чисел, что и в функциях random(3) и srandom(3), так что младшие биты в числе случайны настолько, насколько и старшие. В то же время, в старых реализациях rand() и в текущих реализациях на других системах младшие биты являются гораздо менее случайными, чем старшие. Не используйте эту функцию в переносимых приложениях, для которых требуется большая случайность (вместо неё используйте random(3)).

## ПРИМЕР
В POSIX.1-2001 приведён следующий пример реализации rand() и srand(), возможно полезный, если требуется одинаковая последовательность на двух разных машинах.

```
static unsigned long next = 1;
/* предполагается, что RAND_MAX равно 32767 */
int myrand(void) {

    next = next * 1103515245 + 12345;

    return((unsigned)(next/65536) % 32768);
}
void mysrand(unsigned int seed) {

    next = seed;
}
```

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

```
#include <stdlib.h>
#include <stdio.h>
int
main(int argc, char *argv[])
{

    int j, r, nloops;

    unsigned int seed;

    if (argc != 3) {

        fprintf(stderr, "Использование: %s <seed> <nloops>\n", argv[0]);

        exit(EXIT_FAILURE);

    }

    seed = atoi(argv[1]);

    nloops = atoi(argv[2]);

    srand(seed);

    for (j = 0; j < nloops; j++) {

        r =  rand();

        printf("%d\n", r);

    }

    exit(EXIT_SUCCESS);
}
```

## СМОТРИТЕ ТАКЖЕ
drand48(3), random(3)


random

title: random(3)

summary: генератор случайных чисел

text:
# random(3)

## ИМЯ
random, srandom, initstate, setstate - генератор случайных чисел

## ОБЗОР

```
#include <stdlib.h>
```

```
long int random(void);
```

```
void srandom(unsigned int seed);
```

```
char *initstate(unsigned int seed, char *state, size_t n);
```

```
char *setstate(char *state);
```

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

random(), srandom(), initstate(), setstate():

_XOPEN_SOURCE >= 500

|| /* начиная с glibc 2.19: */ _DEFAULT_SOURCE

|| /* в версиях glibc <= 2.19: */ _SVID_SOURCE || _BSD_SOURCE

## ОПИСАНИЕ
Функция random() использует нелинейный возвратно-аддитивный генератор случайных чисел, используя по умолчанию таблицу из 31-ого длинного целого числа и возвращает очередное псевдослучайное число в промежутке от 0 до RAND_MAX. Период этого генератора очень велик, приблизительно 16 * ((2^31) - 1).

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

Функция initstate() позволяет инициализировать массив состояния state для использования в функции random(). Размер массива состояния n используется initstate() для определения, какой сложности генератор случайных чисел необходимо использовать — чем больше массив, тем полученные числа будут более случайными. Текущие «оптимальные» значения размера массива состояния n: 8, 32, 64, 128 и 256 байт; другие значения будут округлены до ближайшей нижней границы. Если значения меньше 8 байт, то возвращается ошибка. Значение seed — это семя последовательности для инициализации, которое определяет стартовую точку последовательности псевдослучайных чисел и позволяет перезапустить последовательность с той же точки.

Функция setstate() изменяет состояние массива состояния, используемого в random(). Массив состояния state используется для генерации случайных чисел до следующего вызова initstate() или setstate(). Значение state должно быть инициализировано с помощью функции initstate() или результатом предыдущего вызова setstate().

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Функция random() возвращает значение в промежутке от 0 до RAND_MAX. Функция srandom() не возвращает значение.

Функция initstate() возвращает указатель на предыдущий массив состояния. При ошибке в errno записывается соответствующий код.

При успешном выполнении функция setstate() возвращает указатель на предыдущий массив состояния. При ошибке она возвращает NULL и в errno записывает соответствующий код.

## ОШИБКИ
EINVAL

Аргумент state, указанный setstate(), равен NULL.

EINVAL

Функции initstate() передан массив состояния меньше 8 байт.

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

random(), srandom(), initstate(), setstate()

Безвредность в нитях

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008, 4.3BSD.

## ЗАМЕЧАНИЯ
Функция random() не должна использоваться в многонитевых программах, где требуется повторение поведения. Для этих целей используйте random_r(3).

Генерация случайных чисел является сложной проблемой. В главе 7 (Random Numbers) Numerical Recipes in C: The Art of Scientific Computing (William H. Press, Brian P. Flannery, Saul A. Teukolsky, William T. Vetterling; New York: Cambridge University Press, 2007, 3rd ed.) приведено великолепное обсуждение проблем практического применения генерации случайных чисел.

Также вы можете обратиться к теоретическому обсуждению, которое также объясняет многие практические проблемы, приведенному в главе 3 (Random Numbers) второго тома Искусства программирования Дональда Кнута (The Art of Computer Programming, volume 2 (Seminumerical Algorithms), 2nd ed.; Reading, Massachusetts: Addison-Wesley Publishing Company, 1981).

## ДЕФЕКТЫ
Согласно POSIX, initstate() должна возвращать NULL при ошибке. Реализация glibc в errno записывает код ошибки (как по стандарту), но не возвращает NULL.

## СМОТРИТЕ ТАКЖЕ
getrandom(2), drand48(3), rand(3), random_r(3), srand(3)


title: random_r(3)

summary: реентерабельный генератор

text:
# random_r(3)

## ИМЯ
random_r, srandom_r, initstate_r, setstate_r - реентерабельный генератор случайных чисел

## ОБЗОР

```
#include <stdlib.h>
```

```
int random_r(struct random_data *buf, int32_t *result);
```

```
int srandom_r(unsigned int seed, struct random_data *buf);
```

```
int initstate_r(unsigned int seed, char *statebuf,
                size_t statelen, struct random_data *buf);
```

```
int setstate_r(char *statebuf, struct random_data *buf);
```

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

random_r(), srandom_r(), initstate_r(), setstate_r():

/* в glibc начиная с 2.19: */ _DEFAULT_SOURCE

|| /* версии glibc <= 2.19: */ _SVID_SOURCE || _BSD_SOURCE

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

Функция random_r() подобна random(3), но вместо использования информации о состоянии, хранящейся в глобальный переменной, в ней используется информация о состоянии в аргументе, указанном в buf, который должен быть проинициализирован ранее с помощью initstate_r(). Сгенерированное случайное число возвращается в аргументе result.

Функция srandom_r() подобна srandom(3), но инициализирует семя для генератора случайных чисел, чьё состояние хранится в объекте, на который указывает buf который должен быть проинициализирован ранее с помощью initstate_r(), а не связывает семя с глобальной переменной состояния.

Функция initstate_r() подобна initstate(3), но инициализирует состояние в объекте, на который указывает buf, а не в глобальной переменной состояния. Перед вызовом этой функции в поле buf.state нужно записать NULL. Функция initstate_r() сохраняет указатель на аргумент statebuf внутри структуры, указанной в buf. Таким образом, statebuf не должна освобождаться пока используется buf (и statebuf обычно должна быть статической переменной или выделяться из кучи с помощью malloc(3) и подобных ей).

Функция setstate_r() подобна setstate(3), но изменяет состояние в объекте, на который указывает buf, а не в глобальной переменной состояния. Переменная state сначала должна инициализироваться с помощью initstate_r() или быть результатом предшествующего вызова setstate_r().

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении все функции возвращают 0. В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.

## ОШИБКИ
EINVAL

Функции initstate_r() передан массив состояния меньше 8 байт.

EINVAL

Аргумент statebuf или buf функции setstate_r() равнялся NULL.

EINVAL

Аргумент buf или result функции random_r() равнялся NULL.

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

random_r(), srandom_r(), initstate_r(), setstate_r()

Безвредность в нитях

MT-Safe race:buf

## СООТВЕТСТВИЕ СТАНДАРТАМ
Это функции являются расширениями glibc.

## ДЕФЕКТЫ
Интерфейс initstate_r() запутывает. Он появился для того, чтобы сделать тип random_data скрытым, но реализация требует от пользователя перед вызовом, или инициализировать поле buf.state значением NULL, или обнулить всю структуру.

## СМОТРИТЕ ТАКЖЕ
drand48(3), rand(3), random(3)


rcmd

title: rcmd(3)

text:
# rcmd(3)

## ИМЯ
rcmd, rresvport, iruserok, ruserok, rcmd_af, rresvport_af, iruserok_af, ruserok_af - процедуры возврата потока в удалённую команду

## ОБЗОР

```
#include <netdb.h>   /* или <unistd.h> в некоторых системах */
```

```
int rcmd(char **ahost, unsigned short inport, const char *locuser,
         const char *remuser, const char *cmd, int *fd2p);
```

```
int rresvport(int *port);
```

```
int iruserok(uint32_t raddr, int superuser,
             const char *ruser, const char *luser);
```

```
int ruserok(const char *rhost, int superuser,
            const char *ruser, const char *luser);
```

```
int rcmd_af(char **ahost, unsigned short inport, const char *locuser,
            const char *remuser, const char *cmd, int *fd2p,
            sa_family_t af);
```

```
int rresvport_af(int *port, sa_family_t af);
```

```
int iruserok_af(const void *raddr, int superuser,
                const char *ruser, const char *luser, sa_family_t af);
```

```
int ruserok_af(const char *rhost, int superuser,
               const char *ruser, const char *luser, sa_family_t af);
```

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

rcmd(), rcmd_af(), rresvport(), rresvport_af(), iruserok(), iruserok_af(), ruserok(), ruserok_af():

начиная с glibc 2.19:

_DEFAULT_SOURCE

в glibc 2.19 и старее:

_BSD_SOURCE

## ОПИСАНИЕ
Функция rcmd() применяется суперпользователем для исполнения команды на удалённой машине при помощи схемы аутентификации, основанной на зарезервированных номерах портов. Функция rresvport() возвращает файловый дескриптор сокета с адресом в привилегированном пространстве портов. Функции iruserok() и ruserok() используются серверами для аутентификации клиентов, запрашивающих сервис rcmd(). Все четыре функции используются сервером rshd(8) (среди прочих).

### rcmd()
Функция rcmd() ищет узел *ahost, используя gethostbyname(3) и возвращает -1, если узел не существует. Иначе *ahost устанавливается равным стандартному имени узла, при этом создаётся соединение с сервером на хорошо известном порту Интернет inport.

Если соединение успешно установлено, то вызывающему возвращается сокет в домене Интернет типа SOCK_STREAM, который для удалённой команды считается stdin и stdout. Если fd2p не равно нулю, то устанавливается вспомогательный канал до управляющего процесса, а его файловый дескриптор будет помещён в *fd2p. Управляющий процесс возвращает диагностический вывод из команды (устройства 2) в этот канал, а также принимает байты из этого канала, считая их номерами сигналов UNIX, для их пересылки группе процессов команды. Если fd2p равно 0, то stderr (устройство 2 удалённой команды) будет работать аналогично stdout и для отправки произвольных сигналов в удалённый процесс не будет создано никаких ходов, хотя вы сможете привлечь к себе внимание, используя внеполосную передачу данных.

Протокол подробно описан в rshd(8).

### rresvport()
Функция rresvport() используется для получения сокета с привязанным привилегированным портом. Этот сокет подходит для использования функцией rcmd() и некоторыми другими. Привилегированные порты Интернет — это порты с номерами от 0 до 1023. Только привилегированный процесс (в Linux это процесс с мандатом CAP_NET_BIND_SERVICE в пользовательском пространстве имён, управляющим своим сетевым пространством имён) может привязаться к привилегированному порту. В реализации glibc эта функция ограничена в использовании портов номерами с 512 по 1023. Аргумент port является значением-результатом: передаваемое в вызов значение используется в качестве начальной точки кругового поиска в диапазоне портов; при (успешном) возврате, он содержит номер порта, к которому была осуществлена привязка.

### iruserok() и ruserok()
Параметрами функций iruserok() и ruserok() являются, соответственно, IP-адрес или имя удалённого узла, два имени пользователя и флаг, указывающий, является ли имя локального пользователя именем суперпользователя. Далее, если пользователь не является суперпользователем, они проверяют файл /etc/hosts.equiv. Если ничего не находится или завершается с ошибкой, то проверяется .rhosts в домашнем каталоге пользователя (для получения информации о том, разрешены ли запросы к службе).

Если этот файл не существует, не является обычным файлом, если его владельцем является не текущий пользователь или не суперпользователь, если он доступен для записи кому-то помимо владельца или на него есть жёсткая ссылка, то проверка завершается с ошибкой. Если имя машины указано в файле hosts.equiv, или если узел и имя пользователя для удалённого доступа найдены в файле .rhosts, то возвращается 0; иначе iruserok() и ruserok() возвращают -1. Если имя локального домена (полученное вызовом gethostname(2)) совпадает с именем удалённого домена, то может указываться только имя машины.

Если IP-адрес удалённого узла известен, то должна использоваться iruserok() вместо ruserok(), так как при этом не требуется доверия к DNS-серверу для домена удалённого узла.

### Варианты *_af()
Все описанные ранее функции работают с сокетами IPv4 (AF_INET). Варианты «_af» имеют дополнительный аргумент, который позволяет указать адресное семейство сокета. Для этих функций значением аргумента af может быть AF_INET или AF_INET6. Также rcmd_af() поддерживает использование AF_UNSPEC.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Функция rcmd() при успешном выполнении возвращает корректный номер дескриптора сокета. При ошибках возвращается -1 и в стандартный поток ошибок выводится диагностическое сообщение.

Функция rresvport() при успешном выполнении возвращает корректный привязанный дескриптор сокета. При ошибках возвращается -1 и в глобальную переменную errno записывается код ошибки. Код ошибки EAGAIN означает «Все сетевые порты заняты».

Информацию о результатах ruserok() и iruserok() смотрите выше.

## ВЕРСИИ
Функции iruserok_af(), rcmd_af(), rresvport_af() и ruserok_af() появились в glibc начиная с версии 2.2.

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

rcmd(), rcmd_af()

Безвредность в нитях

MT-Unsafe

rresvport(), rresvport_af()

Безвредность в нитях

MT-Safe

iruserok(), ruserok(), iruserok_af(), ruserok_af()

Безвредность в нитях

MT-Safe locale

## СООТВЕТСТВИЕ СТАНДАРТАМ
Отсутствуют в POSIX.1. Есть в BSD, Solaris и многих других системах. Данные функции впервые появились в 4.2BSD. Варианты «_af» были добавлены позднее и распространены не так широко.

## ДЕФЕКТЫ
Функции iruserok() и iruserok_af() объявляются в заголовках glibc только начиная с версии 2.12.

## СМОТРИТЕ ТАКЖЕ
rlogin(1), rsh(1), intro(2), rexec(3), rexecd(8), rlogind(8), rshd(8)


title: re_comp(3)

summary: функции BSD для регулярных выражений

text:
# re_comp(3)

## ИМЯ
re_comp, re_exec - функции BSD для регулярных выражений

## ОБЗОР
\#define _REGEX_RE_COMP

\#include <sys/types.h>

\#include <regex.h>

char *re_comp(const char *regex);

int re_exec(const char *string);

## ОПИСАНИЕ
Функция re_comp() используется для компиляции регулярного выражения (завершающегося null), указанного regex. Скомпилированный шаблон располагается в статической области (буфере шаблонов), которая перезаписывается заново каждый раз при вызове re_comp(). Если значение regex равно NULL, то действие не выполняется и содержимое буфера шаблонов остаётся неизменным.

Функция re_exec() используется для проверки совпадения строки (завершается null), на которую указывает string, с предварительно скомпилированным regex.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Функция re_comp() возвращает NULL при успешной компиляции regex или указатель на соответствующее сообщение об ошибке.

Функция re_exec() возвращает 1 при совпадении или 0, если совпадения не было.

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

re_comp(), re_exec()

Безвредность в нитях

MT-Unsafe

## СООТВЕТСТВИЕ СТАНДАРТАМ
4.3BSD.

## ЗАМЕЧАНИЯ
Эти функции устарели; вместо них следует использовать функции, описанные в regcomp(3).

## СМОТРИТЕ ТАКЖЕ
regcomp(3), regex(7), руководство по регулярным выражениям GNU


readdir

title: readdir(3)

summary: чтение содержимого каталога

text:
# readdir(3)

## ИМЯ
readdir - чтение содержимого каталога

## ОБЗОР

```
#include <dirent.h>
```

```
struct dirent *readdir(DIR *dirp);
```

## ОПИСАНИЕ
Функция readdir() возвращает указатель на структуру dirent, представляющую следующую запись каталога в потоке каталога, указанного в dirp. Функция возвращает NULL по достижении последней записи в потоке каталога или если произошла ошибка.

В реализации glibc структура dirent определена следующим образом:

```
struct dirent {

    ino_t          d_ino;       /* номер иноды */

    off_t          d_off;       /* не смещение, смотрите ниже */

    unsigned short d_reclen;    /* длина этой записи */

    unsigned char  d_type;      /* тип файла; поддерживается

                                   не во всех файловых системах */

    char           d_name[256]; /* имя файла с null в конце */
};
```

В соответствие с POSIX.1, структура dirent обязательно должна содержать поле d_name[] и d_ino. Другие поля не стандартизованы и имеются не во всех системах; подробней смотрите ЗАМЕЧАНИЯ далее.

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

d_ino

Номер иноды файла.

d_off

Значение, возвращаемое в d_off, тоже самое что и после вызова telldir(3) в текущем положении курсора в потоке каталога. Учтите, что не смотря на тип и имя, в современных файловых системах поле d_off мало похоже на смещение в каталоге. Приложения должны считать, что это поле неизвестного типа(чёрным ящиком) и не делать предположений о его содержимом; смотрите также telldir(3).

d_reclen

Размер (в байтах) возвращаемой записи. Может не совпадать с размером структуры, показанной выше; смотрите ЗАМЕЧАНИЯ.

d_type

Это поле содержит значение типа файла, что позволяет не делать дополнительный вызов lstat(2), если дальнейшие действия зависят от типа файла.

Если определён подходящий макрос тестирования свойств (_DEFAULT_SOURCE в версиях glibc начиная с 2.19 или _BSD_SOURCE в версиях glibc 2.19 и старее), то для значения, возвращаемого в d_type, glibc определяет следующие макросы-константы:

DT_BLK

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

DT_CHR

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

DT_DIR

каталог

DT_FIFO

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

DT_LNK

символическая ссылка

DT_REG

обычный файл

DT_SOCK

доменный сокет UNIX

DT_UNKNOWN

Тип файла невозможно определить.

В настоящее время, только файловые системы (среди которых: Btrfs, ext2, ext3 и ext4) поддерживают возврат типа файла в d_type. Все приложения должны правильно обрабатывать возвращаемое значение DT_UNKNOWN.

d_name

Это поле содержит имя файла с завершающим null. Смотрите ЗАМЕЧАНИЯ.

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

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении readdir() возвращает указатель на структуру dirent (эта структура может выделяться статически; не пытайтесь освободить её с помощью free(3)).

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

## ОШИБКИ
EBADF

Неверный дескриптор потока каталога dirp.

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

readdir()

Безвредность в нитях

MT-Unsafe race:dirstream

В текущей спецификации POSIX.1 (POSIX.1-2008), от readdir() не требуется быть нитебезопасной. Однако в современных реализациях (включая glibc) параллельные вызовы readdir() для различных потоков каталога являются нитебезопасными. В случаях, когда несколько нитей должны читать один поток каталога, всё равно предпочтительней использовать readdir() с внешней синхронизацией, а не устаревшей readdir_r(3). Ожидается, что в будущей версии POSIX.1 для readdir() будет требоваться нитебезопасность при одновременной работе с разными потоками каталога.

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008, SVr4, 4.3BSD.

## ЗАМЕЧАНИЯ
Поток каталога открывается с помощью opendir(3).

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

В POSIX.1 определены только поля d_name и d_ino (расширение XSI). Кроме Linux, поле d_type доступно, преимущественно только в системах BSD. Остальные поля доступны во многих, но не во всех системах. В glibc программы могут определить доступность полей, не определённых в POSIX.1, по наличию макросов _DIRENT_HAVE_D_NAMLEN, _DIRENT_HAVE_D_RECLEN, _DIRENT_HAVE_D_OFF или _DIRENT_HAVE_D_TYPE.

### Поле d_name
Определение структуры dirent, показанное выше, взято из заголовочных файлов glibc и отражает поле d_name с постоянным размером.

Предупреждение: приложения не должны зависеть от размера поля d_name. В POSIX оно определено как char d_name[], массив символов неопределённого размера, не более NAME_MAX символов с конечным байтом null ('\0').

В POSIX.1 явно сказано, что это поле не должно использоваться как lvalue. В стандарте также отмечено, что использование sizeof(d_name) некорректно; вместо него используйте strlen(d_name) (в некоторых системах это поле определено как char d_name[1]!). Как следствие, использовать sizeof(struct dirent) для получения размера записи, включающей размер d_name также неправильно.

Заметим, что хотя вызов

fpathconf(fd, _PC_NAME_MAX)

и возвращает значение 255 в большинстве файловых систем, но в некоторых файловых системах (например, CIFS, серверы Windows SMB) имя файла с null конце, возвращаемое (правильно) в d_name, может превышать этот размер. В таких случаях поле d_reclen будет содержать значение, превышающее размер структуры glibc dirent, показанной выше.

## СМОТРИТЕ ТАКЖЕ
getdents(2), read(2), closedir(3), dirfd(3), ftw(3), offsetof(3), opendir(3), readdir_r(3), rewinddir(3), scandir(3), seekdir(3), telldir(3)


title: readdir_r(3)

summary: чтение содержимого каталога

text:
# readdir_r(3)

## ИМЯ
readdir_r - чтение содержимого каталога

## ОБЗОР

```
#include <dirent.h>
```

```
int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
```

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

readdir_r():

_POSIX_C_SOURCE

|| /* версии glibc <= 2.19: */ _BSD_SOURCE || _SVID_SOURCE

## ОПИСАНИЕ
Эта функция устарела; вместо неё используйте readdir(3).

Функция readdir_r() является реентерабельной версией readdir(3). Она читает следующий элемент каталога из потока каталога dirp и возвращает его в выделенный вызывающим буфер, на который указывает entry. Описание структуры dirent смотрите в readdir(3).

Указатель на возвращаемый буфер помещается в *result; если достигнут конец потока каталога, то в *result возвращается NULL..

В приложениях рекомендуется использовать readdir(3) вместо readdir_r(). Также, начиная с версии 2.24, в glibc readdir_r() считается устаревшей. Причины:

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

- В некоторых системах readdir_r() не может прочитать элементы каталога с очень длинными именами. Когда реализации glibc встречается такое имя, вызов readdir_r() завершается с ошибкой ENAMETOOLONG только после чтения последнего элемента каталога. В других системах readdir_r() может выполняться без ошибок, но возвращаемое поле d_name может не завершаться null или может быть обрезанным.

- В текущей спецификации POSIX.1 (POSIX.1-2008), от readdir(3) не требуется быть нитебезопасной. Однако в современных реализациях (включая glibc) параллельные вызовы readdir(3) для различных потоков каталога являются нитебезопасными. Поэтому использовать readdir_r() в многонитевых программах, обычно, не требуется. В случаях, когда несколько нитей должны читать один поток каталога, всё равно предпочтительней использовать readdir(3) с внешней синхронизацией, а не readdir_r(), по причинам, описанным выше.

- Ожидается, что в будущей версии POSIX.1 функция readdir_r() будет помечена как устаревшая, а для readdir(3) будет требоваться нитебезопасность при одновременной работе с разными потоками каталога.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении функция readdir_r() возвращает 0. При ошибке она возвращает положительный номер ошибки (перечислены в ОШИБКАХ). Если достигнут конец потока каталога, то readdir_r() возвращает 0 и NULL в *result.

## ОШИБКИ
EBADF

Неверный дескриптор потока каталога dirp.

ENAMETOOLONG

Обнаружено слишком длинное имя элемента каталога для чтения.

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

readdir_r()

Безвредность в нитях

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008.

## СМОТРИТЕ ТАКЖЕ
readdir(3)


realpath

title: realpath(3)

text:
# realpath(3)

## ИМЯ
realpath - возвращает канонизированный абсолютный путь

## ОБЗОР

```
#include <limits.h>
#include <stdlib.h>
```

```
char *realpath(const char *path, char *resolved_path);
```

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

realpath():

_XOPEN_SOURCE >= 500

|| /* в glibc начиная с 2.19: */ _DEFAULT_SOURCE

|| /* версии glibc <= 2.19: */ _BSD_SOURCE

## ОПИСАНИЕ
Функция realpath() раскрывает все символьные ссылки, конструкции /./, /../ и дополнительные символы «/» в строке path (завершается null) для создания канонического абсолютного пути. Получившееся имя сохраняется в виде строки (с null на конце) не длиннее чем PATH_MAX байт в буфере, указанном в resolved_path. Конечный путь не содержит символьных ссылок и компонентов /./ или /../.

Если значение resolved_path равно NULL, то realpath() выделяет буфер размером PATH_MAX байт с помощью malloc(3) для хранения полного пути и возвращает указатель на этот буфер. Вызывающий должен освободить буфер с помощью free(3).

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении realpath() возвращает указатель на resolved_path.

При ошибках возвращается NULL, содержимое массива resolved_path не определено и в errno указывается код ошибки.

## ОШИБКИ
EACCES

Запрещено чтение или поиск для компонента, содержащегося в пути.

EINVAL

Значение path равно NULL (в glibc до версии 2.3 эта ошибка также возвращалась и при resolved_path равном NULL).

EIO

При чтении файловой системы произошла ошибка ввода-вывода.

ELOOP

Во время определения pathname встретилось слишком много символьных ссылок.

ENAMETOOLONG

Компонент имени пути более NAME_MAX символов, или весь путь более PATH_MAX символов.

ENOENT

Указанный файл не существует.

ENOMEM

Не хватает памяти.

ENOTDIR

Компонент в префиксе пути не является каталогом.

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

realpath()

Безвредность в нитях

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
4.4BSD, POSIX.1-2001.

В POSIX.1-2001 сказано, что поведение при значении resolved_path равном NULL, зависит от реализации. В POSIX.1-2008 определено поведение, аналогичное описанию на этой странице.

## ЗАМЕЧАНИЯ
В 4.4BSD и Solaris максимальная длина пути равна MAXPATHLEN (находится в <sys/param.h>). В SUSv2 величины PATH_MAX и NAME_MAX представлены в <limits.h> или предоставляются функцией pathconf(3). Вот типичный фрагмент кода:

```
#ifdef PATH_MAX

  path_max = PATH_MAX;
#else

  path_max = pathconf(path, _PC_PATH_MAX);

  if (path_max <= 0)

    path_max = 4096;
#endif
```

(Но смотрите раздел ДЕФЕКТЫ)

### Расширения GNU
Если вызов завершается с ошибкой EACCES или ENOENT и значение resolved_path не равно NULL, то в resolved_path возвращается начало не читаемой или не существующей части path.

## ДЕФЕКТЫ
Стандартная версия этой функции POSIX.1-2001 некорректна изначально, так как невозможно определить подходящий размер для буфера результата. В соответствии с POSIX.1-2001 буфера размером PATH_MAX должно хватить, но PATH_MAX может не задаваться константой, а получаться через функцию pathconf(3). И запрос pathconf(3) особо не поможет, так как с одной стороны POSIX предупреждает, что результат pathconf(3) может быть слишком велик и не пригоден для выделения памяти. С другой стороны, pathconf(3) может возвратить -1 для обозначения того, что PATH_MAX неограничен. Свойство resolved_path == NULL, не стандартизованное в POSIX.1-2001, но стандартизованное в POSIX.1-2008, позволяет избежать этой проблемы проектирования.

## СМОТРИТЕ ТАКЖЕ
realpath(1), readlink(2), canonicalize_file_name(3), getcwd(3), pathconf(3), sysconf(3)


recno

title: recno(3)

text:
# recno(3)

## ИМЯ
recno - метод доступа к базам нумерованных данных

## ОБЗОР

```
#include <sys/types.h>
#include <db.h>
```

## ОПИСАНИЕ
Примечание: В этой странице описаны интерфейсы, предоставляемые glibc до версии 2.1. Начиная с версии 2.2, glibc больше не поддерживает эти интерфейсы. Вероятно, вы ищите API, предоставляемое библиотекой libdb.

Функция dbopen(3) — это библиотечный интерфейс к файлам баз данных. Один из поддерживаемых форматов файлов — нумерованные данные. Общее описание методов доступа к базам данных находится в dbopen(3). Эта справочная страница содержит только информацию, относящуюся к нумерованным данным.

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

Специальная структура метода доступа к данным recno, предоставляемая dbopen(3), определена в <db.h> следующим образом:

```
typedef struct {

    unsigned long flags;

    unsigned int  cachesize;

    unsigned int  psize;

    int           lorder;

    size_t        reclen;

    unsigned char bval;

    char         *bfname;
} RECNOINFO;
```

Элементы этой структуры определены так:

flags

Значение флага определяется логическим ИЛИ следующих значений:

R_FIXEDLEN

Записи фиксированной длины без разделительного байта. Полем reclen определяется длина записи, а поле bval используется как дополняющий символ. Все вставляемые в базу данных записи, размер которых меньше reclen байт, автоматически дополняются.

R_NOKEY

В интерфейсе, определённом dbopen(3), последовательная выборка записей заполняет структуры данных и ключа вызывающего. Если указан флаг R_NOKEY, то процедурам cursor не обязательно заполнять структуру ключа. Это позволяет приложениям извлекать записи из конца файлов без чтения всех промежуточных записей.

R_SNAPSHOT

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

cachesize

Предполагаемый максимальный размер кэша памяти в байтах. Эта величина только рекомендация, метод доступа скорее выделит больше памяти, чем завершится с ошибкой. Если значение cachesize равно 0 (размер не указан), то используется кэш по умолчанию.

psize

Метод доступа recno хранит копии своих записей в памяти в виде дерева btree. Это значение задаёт размер страниц (в байтах), используемых для узлов в этом дереве. Если значение psize равно 0 (размер страницы не указан), то размер выбирается на основе размера блока ввода-вывода нижележащей файловой системы. Подробней смотрите btree(3).

lorder

Порядок расположения байтов, используемый при хранении целых чисел в метаданных базы данных. Число должно отражать порядок размещения в виде целого значения; например, порядок «big endian» должен обозначаться числом 4321. Если lorder равно 0 (порядок не определён), то используется значение по умолчанию, принятое на машине.

reclen

Длина записи фиксированной длины.

bval

Разделительный байт, для использования в качестве отметки конца записи с переменной длиной и как заполняющий символ для записи с фиксированной длиной. Если значение не указано, то для отметки конца записи с переменной длиной используется символ новой строки («\n»), а записи с фиксированной длиной дополняются пробелом.

bfname

Метод доступа recno хранит в памяти копии своих записей в дереве btree. Если значение bfname не равно NULL, то им задаётся имя btree-файла в том же виде, что и при доступе dbopen(3) для доступа к btree-файлу.

Часть «данные» из пары ключ/данные, используемая методом доступа recno, является такой же, как в других методах доступа. Ключ используется иначе. Как следует из определения заголовочного файла <db.h>, поле ключа data должно быть указателем на расположение памяти типа recno_t. Этот тип, обычно, является наибольшим беззнаковым целочисленным типом данных, применяемым в реализации. Значение поля ключа size должен задавать размер этого типа.

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

В интерфейсе, определённым dbopen(3), использование интерфейса put для создания новой записи повлечёт за собой создание множества пустых записей, если номер записи больше, чем номер наибольшей записи, имеющейся в базе данных.

## ОШИБКИ
Функции метода доступа recno могут завершиться с ошибкой и присвоить errno любое значение из определённых для библиотеки функций dbopen(3), а также:

EINVAL

Попытка добавить слишком большую запись в базу данных фиксированной длины.

## ДЕФЕКТЫ
Поддерживаются значения только с прямым и обратным порядком байт.

## СМОТРИТЕ ТАКЖЕ
btree(3), dbopen(3), hash(3), mpool(3)

Document Processing in a Relational Database System, Michael Stonebraker, Heidi Stettner, Joseph Kalash, Antonin Guttman, Nadene Lynn, Memorandum No. UCB/ERL M82/32, May 1982.


regex

title: regex(3)

summary: функции регулярных выражений POSIX

text:
# regex(3)

## ИМЯ
regcomp, regexec, regerror, regfree - функции регулярных выражений POSIX

## ОБЗОР

```
#include <sys/types.h>
#include <regex.h>
```

```
int regcomp(regex_t *preg, const char *regex, int cflags);
```

```
int regexec(const regex_t *preg, const char *string, size_t nmatch,
            regmatch_t pmatch[], int eflags);
```

```
size_t regerror(int errcode, const regex_t *preg, char *errbuf,
                size_t errbuf_size);
```

```
void regfree(regex_t *preg);
```

## ОПИСАНИЕ

### Компилирование регулярных выражений POSIX
Функция regcomp() используется для компиляции регулярного выражения в формат, который подходит для последующих поисков с помощью regexec().

regcomp() передаётся указатель на область хранения буферного шаблона preg, указатель на заканчивающуюся null строку regex и флаги cflags, используемые для определения типа компиляции.

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

Значение cflags может состоять из поразрядного or нуля или нескольких следующих значений:

REG_EXTENDED

Использовать синтаксис расширенных регулярных выражений POSIX во время интерпретации regex. Если не включён этот флаг, то используется синтаксис простых регулярных выражений POSIX.

REG_ICASE

Не учитывать регистр. Последующие поиски regexec() с использованием данного буферного шаблона не будут зависеть от регистра.

REG_NOSUB

Не сообщать положение совпадений. Параметры nmatch и pmatch для regexec() игнорируются, если данный буферный шаблон был скомпилирован с этим включённым флагом.

REG_NEWLINE

Операторы совпадения с любым символом не совпадают с символом новой строки.

Список несовпадающих символов ([^...]) без символа новой строки не совпадает с новой строкой.

Оператор сравнения по началу строки (^) совпадает с пустой строкой сразу после новой строки независимо от того, что eflags, флаги выполнения regexec(), содержат REG_NOTBOL.

Оператор сравнения по концу строки ($) совпадает с пустой строкой до символа начала строки независимо от того, что eflags содержит REG_NOTEOL.

### Сравнение с регулярным выражением POSIX
Функция regexec() используется для сравнения строки, завершающейся null, с предварительно обработанным буферным шаблоном preg. Аргументы nmatch и pmatch используются для предоставления информации о местонахождении любых совпадений. Значение eflags может быть поразрядным ИЛИ одного или обоих значений REG_NOTBOL и REG_NOTEOL. Данные значения определяют поведение процесса сравнения так, как описано ниже.

REG_NOTBOL

Оператор сравнения по началу строки всегда завершается с ошибкой (но смотрите описанный выше флаг компиляции REG_NEWLINE). Этот флаг может использоваться, когда в regexec() передаются отдельные части строки, и начало такой строки в данном случае не должно интерпретироваться как начало новой строки.

REG_NOTEOL

Оператор сравнения по концу строки всегда завершается с ошибкой (но смотрите описанный выше флаг компиляции REG_NEWLINE).

REG_STARTEND

Использовать pmatch[0] на входной строке начиная с байта pmatch[0].rm_so и заканчивая перед байтом pmatch[0].rm_eo. Это позволяет искать встроенные байты NUL и избегать выполнения strlen(3) для длинных строк. Здесь не используется nmatch на входных данных и не изменяется обработка REG_NOTBOL или REG_NEWLINE. Этот флаг является расширением BSD и отсутствует в POSIX.

### Байтовые смещения
Если REG_NOSUB не установлен при компиляции буферного шаблона, то возможно получать информацию о положении совпадений. Значение pmatch должно быть определено так, чтобы иметь, по крайней мере, nmatch элементов. Они заполняются regexec() адресами внутристрочных совпадений. Смещения подвыражения, начинающегося с i-й открытой скобки, сохраняется в pmatch[i]. Адрес совпадения всего регулярного выражения сохраняется в pmatch[0] (заметим, что чтобы вернуть смещения совпадений N подвыражений, значение nmatch должно быть не менее N+1). Любые неиспользованные элементы структуры будут содержать значение -1.

Структура regmatch_t, являющаяся типом pmatch, определена в <regex.h>:

```
typedef struct {

    regoff_t rm_so;

    regoff_t rm_eo;
} regmatch_t;
```

Каждый элемент rm_so, не равный -1, показывает начальное смещение следующего совпадения наибольшей подстроки внутри заданной строки. Относительный элемент rm_eo указывает на смещение конца совпадения, которое является первым символом после совпавшего текста.

### Сообщение об ошибках POSIX
Функция regerror используется для преобразования кодов ошибок, которые могут быть получены от regcomp() и regexec(), в строки сообщений об ошибках.

В regerror передаются: код ошибки errcode, буферный шаблон preg, указатель на символьный буфер строки errbuf и размер буфера строки errbuf_size. Функция возвращает размер errbuf, который требуется для сохранения сообщения об ошибке в виде строки, оканчивающейся null. Если и errbuf, и errbuf_size не равны нулю, то errbuf заполняется первыми errbuf_size - 1 символами сообщения об ошибке и завершается байтом null ('\0').

### Освобождение буфера шаблона POSIX
Функция regfree() освобождает память, отведённую буферному шаблону preg во время процесса компиляции с помощью regcomp().

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Функция regcomp() возвращает ноль при успешной компиляции или в противном случае код ошибки.

Функция regexec() возвращает ноль при совпадении или REG_NOMATCH, если совпадений не было.

## ОШИБКИ
Функция regcomp() может возвращать следующие ошибки:

REG_BADBR

Неправильное использование оператора обратных ссылок.

REG_BADPAT

Неправильное использование операторов шаблона, таких, как операторы группы или списка.

REG_BADRPT

Неправильное использование операторов повторения, например, использование «*» в качестве первого символа.

REG_EBRACE

Непарные скобки в операторах интервала.

REG_EBRACK

Непарные квадратные скобки в операторах списка.

REG_ECOLLATE

Неправильный элемент сортировки.

REG_ECTYPE

Неизвестное имя класса символов.

REG_EEND

Потенциальная ошибка. Не определена в POSIX.2.

REG_EESCAPE

Конечная обратная косая черта.

REG_EPAREN

Непарные круглые скобки в операторах группировки.

REG_ERANGE

Неправильное использование оператора области: например, конец области появляется прежде её начала.

REG_ESIZE

Скомпилированное регулярное выражение требует буферный шаблон размером, большим 64 Кб. Это не определено в POSIX.2.

REG_ESPACE

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

REG_ESUBREG

Неправильная обратная ссылка на подвыражение.

## АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).

Интерфейс

Атрибут

Значение

regcomp(), regexec()

Безвредность в нитях

MT-Safe locale

regerror()

Безвредность в нитях

MT-Safe env

regfree()

Безвредность в нитях

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008.

## СМОТРИТЕ ТАКЖЕ
grep(1), regex(7)

Раздел руководства glibc Regular Expressions