dbopen

title: dbopen(3)

summary: методы доступа к базе данных

text:
# dbopen(3)

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

## ОБЗОР

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

```
DB *dbopen(const char *file, int flags, int mode, DBTYPE type,
           const void *openinfo);
```

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

dbopen() — это библиотека для взаимодействия с файлами баз данных. Поддерживаются форматы файлов btree, hashed и UNIX. Формат btree представляет собой отсортированную, сбалансированную древовидную структуру. Формат hashed — это гибкая, динамическая схема хэширования. Формат простого файла UNIX — поток байтов с записями постоянной или переменной длины. Сами форматы и формат файлов описываются детально в соответствующих справочных страницах btree(3), hash(3) и recno(3).

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

Значения аргументов flags и mode те же, что у вызова open(2), однако имеют значение только флаги O_CREAT, O_EXCL, O_EXLOCK, O_NONBLOCK, O_RDONLY, O_RDWR, O_SHLOCK и O_TRUNC. Открытие файла базы данных с O_WRONLY невозможно.

Аргумент type имеет тип DBTYPE (определён в файле заголовков <db.h>) и может быть равен DB_BTREE, DB_HASH или DB_RECNO.

Аргумент openinfo является указателем на структуру метода доступа, описанную в справочной странице, посвящённой методам доступа. Если значение openinfo равно NULL, то каждый метод доступа будет использовать установки по умолчанию для системы и метода доступа.

При успешном выполнении dbopen() возвращает указатель на структуру DB и NULL при ошибке. Структура DB определена в файле <db.h> и содержит, как минимум, следующие поля:

```
typedef struct {

    DBTYPE type;

    int (*close)(const DB *db);

    int (*del)(const DB *db, const DBT *key, unsigned int flags);

    int (*fd)(const DB *db);

    int (*get)(const DB *db, DBT *key, DBT *data,

               unsigned int flags);

    int (*put)(const DB *db, DBT *key, const DBT *data,

               unsigned int flags);

    int (*sync)(const DB *db, unsigned int flags);

    int (*seq)(const DB *db, DBT *key, DBT *data,

               unsigned int flags);
} DB;
```

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

type

Тип лежащего в основе метода доступа (и формат файла).

close

Указатель на функцию, которая записывает любую кэшированную информацию на диск, освобождает занятые ресурсы и закрывает используемый файл(-ы). Так как пары ключ/данные могут быть кэшированы в памяти, ошибка синхронизации файла при функциях close или sync может привести к повреждению или потере данных. Функция close возвращает -1 при ошибках (меняя при этом, соответственно, значение переменной errno) и 0 при успешном выполнении.

del

Указатель на функцию для удаления пар ключ/данные из базы данных.

Значение параметра flag может быть следующим:

R_CURSOR

Удаление записи, на которую ссылается курсор. Курсор предварительно должен быть инициализирован.

Функция delete возвращает -1 при ошибке (изменяет errno), 0 при успешном выполнении и 1, если указанного ключа key нет в файле.

fd

Указатель на функцию, которая возвращает дескриптор файла, представляющий используемую базу данных. Дескриптор файла, ссылающийся на тот же файл, будет возвращаться всем процессам, которые вызывают dbopen() с этим именем файла file. Этот дескриптор файла может быть использован как аргумент для блокирующих функций fcntl(2) и flock(2). Файловый дескриптор необязательно связывать с какими-либо из файлов, лежащих в основе используемого метода доступа. Для баз данных в памяти файловые дескрипторы недоступны. Функция fd возвращает -1 при ошибке (меняет при этом, соответственно, значение переменной errno) или дескриптор файла при успешном выполнении.

get

Указатель на функцию, которая является интерфейсом для поиска по ключу в базе данных. Адрес и размер данных, связанных с указанным ключом key, возвращается в структуре, указываемой data. Функция get возвращает -1 при ошибке (меняя при этом, соответственно, значение переменной errno), 0 при успешном выполнении и 1, если ключа key нет в файле.

put

Указатель на функцию, сохраняющую пары ключ/данные в базе данных.

Значение параметра flag может быть одним из следующих:

R_CURSOR

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

R_IAFTER

Добавление данных сразу после тех данных, которые связаны с ключом key; создание новой пары ключ/данные. Номер записи добавленной пары ключ/данные возвращается в структуре key (применимо только в случае метода доступа DB_RECNO).

R_IBEFORE

Вставка данных перед данными, связанными с ключом key; создание новой пары ключ/данные. Номер записи добавленной пары ключ/данные возвращается в структуре key (применимо только в случае метода доступа DB_RECNO).

R_NOOVERWRITE

Добавление новой пары ключ/данные, только если ключ ещё не существовал.

R_SETCURSOR

Сохранение пары ключ/данные, установка или инициализация позиции курсора для ссылки на неё (применимо только в случае метода доступа DB_BTREE и DB_RECNO).

Значение R_SETCURSOR доступно только в случае методов доступа DB_BTREE и DB_RECNO, поскольку они предполагают, что ключи имеют определённый порядок, который не изменяется.

Значения R_IAFTER и R_IBEFORE доступны только в случае метода доступа DB_RECNO, поскольку предполагается, что метод доступа позволяет создавать новые ключи. Это возможно, только если ключи отсортированы и независимы, например, они могут представлять собой номера записей.

Поведение по умолчанию функции put предусматривает ввод новой пары ключ/данные, заменяя при этом уже существующий ключ.

Функция put возвращает -1 при ошибке (меняя при этом, соответственно, значение переменной errno), 0 при успешном выполнении и 1, если значение flag равно R_NOOVERWRITE и ключ в файле уже существует.

seq

Указатель на функцию, которая является интерфейсом для последовательной выборки в базе данных. Адрес и размер ключа возвращается в структуре, определяемой key, а адрес и размер данных — в структуре, определяемой data.

Последовательная выборка пар ключ/данные может быть начата в любой момент, и позиция «курсора» не подвергнется изменениям при вызове функций del, get, put или sync. Изменение базы данных в процессе последовательного просмотра отразится на просмотре, т. е. запись, вставленная позади курсора, не будет возвращена, пока не будет возвращена запись, вставленная перед курсором.

Значение флага должно быть равно одному из следующих значений:

R_CURSOR

Возвращаются данные, связанные с указанным ключом. Отличается от функции get тем, что дополнительно происходит установка или инициализация курсора. Заметим, что при методе доступа DB_BTREE необязательно, чтобы возвращаемый ключ в точности соответствовал указанному. Возвращаемый ключ — наименьший ключ из больших или равных указанному ключу. При этом допускается частичное соответствие ключей и поиск их в диапазонах.

R_FIRST

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

R_LAST

Возвращается последняя пара ключ/данные из базы данных, а курсор устанавливается или инициализируется для ссылки на него. Применимо только для методов доступа DB_BTREE и DB_RECNO.

R_NEXT

Возвращается пара ключ/данные, стоящая непосредственно после курсора. Если курсор ещё не был установлен, выполняется тоже, что при флаге R_FIRST.

R_PREV

Возвращается пара ключ/данные, стоящая непосредственно перед курсором. Если курсор ещё не был установлен, выполняется тоже, что при флаге R_LAST. Применимо только для методов доступа DB_BTREE и DB_RECNO.

Флаги R_LAST и R_PREV подходят только для методов доступа DB_BTREE и DB_RECNO, поскольку при этом предполагается, что ключи расположены в строгом неизменном порядке.

Функция seq возвращает -1 при ошибке (изменяя при этом значение переменной errno), 0 при успешном выполнении и 1, если не обнаруживается пары ключ/данные, меньшей или большей по значению, чем указанный или текущий ключ. Если используется метод доступа DB_RECNO, а файл базы данных представляет собой специальный символьный файл (и нет доступных полных пар ключ/данные), то функция seq возвращает значение 2.

sync

Указатель на функцию, которая записывает любые кэшированные данные на диск. Если база данных находится только в памяти, функция sync не выполняет никаких действий и всегда выполняется без ошибок.

Значение параметра flag может быть следующим:

R_RECNOSYNC

При методе доступа DB_RECNO этот флаг служит причиной применения функции sync к файлу btree, лежащему в основе файла recno, а не к самому файлу recno (см. поле bfname в справочной странице recno(3)).

Функция sync возвращает -1 при ошибке (меняя при этом значение переменной errno) или 0 при успешном выполнении.

### Пары ключ/данные
Доступ ко всем типам файлов основан на парах ключ/данные. Ключ и данные описываются следующей структурой данных:

```
typedef struct {

    void  *data;

    size_t size;
} DBT;
```

Элементы структуры DBT определяются так:

data

Указатель на строку байтов.

size

Размер строки байтов.

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

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

EFTYPE

Файл неверного формата.

EINVAL

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

Функция close может завершиться с ошибкой и присвоить переменной errno любое значение из определённых в библиотечных функциях close(2), read(2), write(2), free(3) или fsync(2).

Функции del, get, put и seq могут некорректно завершаться с ошибкой и присвоить переменной errno любое значение из определённых в библиотечных функциях read(2), write(2), free(3) или malloc(3).

Функция fd может завершиться с ошибкой и присвоить переменной errno значение ENOENT (для баз данных, находящихся в памяти).

Функции sync могут завершиться с ошибкой и присвоить errno любое значение из определённых для библиотеки функций fsync(2).

## ДЕФЕКТЫ
Название типа DBT является сокращением от «data base thang» и используется в настоящее время, поскольку никто ещё не придумал подходящего для него имени, которое ранее нигде не применялось.

Доступ через дескриптор файла устарел и будет удалён в будущей версии интерфейса.

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

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

LIBTP: Portable, Modular Transactions for UNIX, Margo Seltzer, Michael Olson, USENIX proceedings, Winter 1992.


package: man-pages-ru

title: des_crypt(3)

summary: быстрое

text:
# des_crypt(3)

## ИМЯ
des_crypt, ecb_crypt, cbc_crypt, des_setparity, DES_FAILED - быстрое шифрование DES

## ОБЗОР

```
#include <rpc/des_crypt.h>
```

```
int ecb_crypt(char *key, char *data, unsigned datalen,
              unsigned mode);
```

```
int cbc_crypt(char *key, char *data, unsigned datalen,
              unsigned mode, char *ivec);
```

```
void des_setparity(char *key);
```

```
int DES_FAILED(int status);
```

## ОПИСАНИЕ
В функциях ecb_crypt() и cbc_crypt() реализован стандарт шифрования данных NBS DES (Data Encryption Standard). Они более быстры и имеют более широкое предназначение, чем crypt(3). Также они могут использовать (при наличии) оборудование DES. Функция ecb_crypt() шифрует данные в режиме ECB (Electronic Code Book), при котором блоки данных шифруются независимо друг от друга. Функция cbc_crypt() шифрует данные в режиме CBC (Cipher Block Chaining), при котором вместе связываются рядом стоящие блоки. Режим CBC защищает от вставки, удаления или подмены блоков. Также повторяющиеся отрезки простого текста не появятся в зашифрованном в таком режиме коде.

Рассмотрим применение этих функций. Первый параметр, key, является 8-байтным ключом шифрования с чётностью. Для установки чётности ключа, которая для DES находится в младшем бите каждого байта, используйте des_setparity. Второй параметр, data, содержит данные для шифрования или расшифровки. Третий параметр, datalen, задаёт длину блока данных data в байтах, длина должна быть кратна 8. Четвертый параметр, mode, формируется через логическое сложение (OR) нескольких вещей. Чтобы указать тип операции добавляется либо DES_ENCRYPT, либо DES_DECRYPT. Чтобы применить программное шифрование или использовать специальное оборудование, добавляется либо DES_HW, либо DES_SW. Если указано DES_HW и оборудование не обнаружено, то шифрование выполняется в программном режиме, а функция возвращает DESERR_NOHWDEVICE. В cbc_crypt() параметр ivec используется как 8-байтовый вектор инициализации для шифрования цепочек. Он обновляется на следующий вектор инициализации при возврате.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
DESERR_NONE

Нет ошибок.

DESERR_NOHWDEVICE

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

DESERR_HWERROR

Ошибка в оборудовании или драйвере.

DESERR_BADPARAM

Некорректный параметр функции.

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

## ВЕРСИИ
Эти функции присутствуют в glibc 2.1 и более новых.

## ВЕРСИИ
Функции ecb_crypt(), ecb_crypt(), crypt_r() и des_setparity() удалены из glibc 2.28, так как они используют блочный шифр DES, который теперь считается небезопасным. В приложениях следует использовать современную библиотеку шифрования, например libgcrypt.

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

Интерфейс

Атрибут

Значение

ecb_crypt(), cbc_crypt(), des_setparity()

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

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
4.3BSD. Отсутствует в POSIX-1.

## СМОТРИТЕ ТАКЖЕ
des(1), crypt(3), xcrypt(3)


difftime

title: difftime(3)

summary: вычисляет разницу во времени

text:
# difftime(3)

## ИМЯ
difftime - вычисляет разницу во времени

## ОБЗОР

```
#include <time.h>
```

```
double difftime(time_t time1, time_t time0);
```

## ОПИСАНИЕ
Функция difftime() возвращает количество секунд, прошедших со времени time1 и до времени time0, представленного типом double. Оба времени должны быть календарным временем, т. е. временем (в секундах), прошедшем с начала эпохи (с 00:00:00 1 января 1970 года всеобщего скоординированного времени (UTC)).

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

Интерфейс

Атрибут

Значение

difftime()

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

MT-Safe

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

## ЗАМЕЧАНИЯ
В системе POSIX значение time_t является числом и функция может быть просто определена как

```
#define difftime(t1,t0) (double)(t1 - t0)
```

когда возможное переполнение при вычитании не проблема.

## СМОТРИТЕ ТАКЖЕ
date(1), gettimeofday(2), time(2), ctime(3), gmtime(3), localtime(3)


dirfd

title: dirfd(3)

text:
# dirfd(3)

## ИМЯ
dirfd - получение файлового дескриптора потока каталога

## ОБЗОР
\#include <sys/types.h>

\#include <dirent.h>

int dirfd(DIR *dirp);

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

dirfd():

/* начиная с glibc 2.10: */ _POSIX_C_SOURCE >= 200809L

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

## ОПИСАНИЕ
Функция dirfd() возвращает файловый дескриптор, связанный с потоком каталога dirp.

Этот файловый дескриптор используется внутри функции потоком каталога. В результате он полезен только для функций, которые не зависят и не изменяют положение в файле, например fstat(2) и fchdir(2). Он автоматически закрывается при вызове closedir(3).

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

## ОШИБКИ
В POSIX.1-2008 определены две ошибки, ни одна из которых не возвращается текущей реализацией.

EINVAL

Значение dirp не указывает на допустимый поток каталога.

ENOTSUP

Реализация не поддерживает связь файлового дескриптора с каталогом.

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

Интерфейс

Атрибут

Значение

dirfd()

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

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2008. Данная функция была расширением BSD, появилась в 4.3BSD-Reno, не в 4.2BSD.

## СМОТРИТЕ ТАКЖЕ
open(2), closedir(3), opendir(3), readdir(3), rewinddir(3), scandir(3), seekdir(3), telldir(3)


div

title: div(3)

text:
# div(3)

## ИМЯ
div, ldiv, lldiv, imaxdiv - вычисляет частное и остаток деления целого числа

## ОБЗОР

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

```
div_t div(int numerator, int denominator);
ldiv_t ldiv(long numerator, long denominator);
lldiv_t lldiv(long long numerator, long long denominator);
```

```
#include <inttypes.h>
```

```
imaxdiv_t imaxdiv(intmax_t numerator, intmax_t denominator);
```

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

lldiv():

_ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L

## ОПИСАНИЕ
Функция div() вычисляет величину numerator/denominator и возвращает частное и остаток в структуре div_t, которая содержит два целочисленных поля (в неопределённом порядке) quot и rem. Частное округляется до ближайшего нуля. Результат равняется quot*denominator+rem = numerator.

Функции ldiv(), lldiv() и imaxdiv() выполняют эту же функцию, деля числа соответствующего типа и возвращая результат в структуре с соответствующим именем, всегда с полями quot и rem того же типа, что и аргументы функции.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Структура div_t (и т. д.).

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

Интерфейс

Атрибут

Значение

div(), ldiv(), lldiv(), imaxdiv()

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

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008, C89, C99, SVr4, 4.3BSD. Функции lldiv() и imaxdiv() добавлены в C99.

## ПРИМЕР
После

```
div_t q = div(-5, 3);
```

значения q.quot и q.rem равны -1 и -2, соответственно.

## СМОТРИТЕ ТАКЖЕ
abs(3), remainder(3)


title: dl_iterate_phdr(3)

summary: обход списка общих объектов

text:
# dl_iterate_phdr(3)

## ИМЯ
dl_iterate_phdr - обход списка общих объектов

## ОБЗОР

```
#define _GNU_SOURCE         /* см. feature_test_macros(7) */
#include <link.h>
```

```
int dl_iterate_phdr(
          int (*callback) (struct dl_phdr_info *info,
                           size_t size, void *data),
          void *data);
```

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

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

При каждом вызове в callback передаётся три параметра: info (указатель на структуру с информацией об общем объекте), size (размер структуры, на которую указывает info) и data (копия любого значения, переданного вызывающей программой во втором параметре (также называемом data) в вызов dl_iterate_phdr().

Параметр info представляет собой структуру следующего вида:

```
struct dl_phdr_info {

    ElfW(Addr)        dlpi_addr;  /* базовый адрес объекта */

    const char       *dlpi_name;  /* имя объекта

                                     (оканчивается Null) */

    const ElfW(Phdr) *dlpi_phdr;  /* указатель на массив

                                     программных заголовков ELF

                                     этого объекта */

    ElfW(Half)        dlpi_phnum; /* кол-во элементов в dlpi_phdr */

    /* Следующие поля были добавлены в glibc 2.4, после опубликования

       первой версии этой структуры. Из аргумента size,

       передаваемом в dl_iterate_phdr, можно определить

       были ли добавлены новые члены. */

    unsigned long long int dlpi_adds;

                    /* увеличивается, когда мог быть

                       добавлен новый объект */

    unsigned long long int dlpi_subs;

                    /* увеличивается, когда мог быть

                       удалён новый объект */

    size_t dlpi_tls_modid;

                    /* если существует сегмент PT_TLS, это его

                       ID модуля, используемый в

                       перестановках TLS, иначе 0 */

    void  *dlpi_tls_data;

                    /* адрес экземпляра вызывающей нити

                       сегмента PT_TLS этого модуля, если он есть

                       и был выделен в вызывающей нити,

                       иначе указатель null */
};
```

(Макрос ElfW() преобразует свой аргумент в имя типа данных ELF, подходящее для аппаратной архитектуры. Например, на 32-битной платформе ElfW(Addr) вернёт имя типа данных Elf32_Addr. Дополнительную информацию можно найти в заголовочных файлах <elf.h> и <link.h>.)

В поле dlpi_addr указывается базовый адрес общего объекта (т. е., разница между виртуальным адресом памяти общего объекта и смещением до этого объекта в файле, из которого он был загружен). Поле dlpi_name представляет собой строку с null на конце, определяющую путь, из которого был загружен общий объект.

Чтобы понять назначение полей dlpi_phdr и dlpi_phnum, нам необходимо представлять, что общий объект ELF состоит из набора сегментов, каждый из которых имеет соответствующий программный заголовок, описывающий сегмент. Поле dlpi_phdr представляет собой указатель на массив программных заголовков этого общего объекта. В поле dlpi_phnum задаётся размер этого массива.

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

```
typedef struct {

    Elf32_Word  p_type;    /* тип сегмента */

    Elf32_Off   p_offset;  /* смещение сегмента в файле */

    Elf32_Addr  p_vaddr;   /* виртуальный адрес сегмента */

    Elf32_Addr  p_paddr;   /* физический адрес сегмента */

    Elf32_Word  p_filesz;  /* размер сегмента в файле */

    Elf32_Word  p_memsz;   /* размер сегмента в памяти */

    Elf32_Word  p_flags;   /* флаги сегмента */

    Elf32_Word  p_align;   /* выравнивание сегмента */
} Elf32_Phdr;
```

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

```
addr == info->dlpi_addr + info->dlpi_phdr[x].p_vaddr;
```

Возможными значениями p_type поля могут быть (подробности смотрите в <elf.h>):

```
#define PT_LOAD         1    /* загружаемый сегмент программы */
#define PT_DYNAMIC      2    /* информация о динамической компоновке */
#define PT_INTERP       3    /* интерпретатор программы */
#define PT_NOTE         4    /* вспомогательная информация */
#define PT_SHLIB        5    /* зарезервировано */
#define PT_PHDR         6    /* сам элемент таблицы заголовков */
#define PT_TLS          7    /* сегмент локального хранилища нити */
#define PT_GNU_EH_FRAME 0x6474e550 /* сегмент GCC .eh_frame_hdr */
#define PT_GNU_STACK  0x6474e551 /* показывает, что стек — исполняемый */
#define PT_GNU_RELRO  0x6474e552 /* только чтения после перемещения */
```

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

## ВЕРСИИ
Функция dl_iterate_phdr() доступна в glibc начиная с версии 2.2.4.

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

Интерфейс

Атрибут

Значение

dl_iterate_phdr()

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

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
Функция dl_iterate_phdr() не описана в каком-либо стандарте. Эта функция есть в некоторых других системах, при чём возвращаемая структура dl_phdr_info имеет другой формат. В BSD и Solaris, в структуре есть поля dlpi_addr, dlpi_name, dlpi_phdr и dlpi_phnum (помимо других внесённых реализацией полей).

## ЗАМЕЧАНИЯ
В будущих версиях библиотеки C в структуре dl_phdr_info могут появиться дополнительные поля; для этого случая предусмотрен аргумент size, который предоставляет вызываемой функции механизм обнаружения того, что она работает в системе с добавленными полями.

Первый объект, просматриваемый callback, это главная программа. У главной программы поле dlpi_name будет содержать пустую строку.

## ПРИМЕР
Следующая программа выводит список путей общих объектов, из которых они были загружены. Для каждого общего объекта программа выводит информацию из каждого сегмента объектов ELF (виртуальный адрес, размер, флаги и тип).

В следующем сеансе оболочки показан вывод программы, запущенной в системе с архитектурой x86-64. Первый показанный общий объект это основная программа (вместо имени пустая строка).

```
$ ./a.out
Имя: "" (9 сегментов)

     0: [      0x400040; memsz:    1f8] flags: 0x5; PT_PHDR

     1: [      0x400238; memsz:     1c] flags: 0x4; PT_INTERP

     2: [      0x400000; memsz:    ac4] flags: 0x5; PT_LOAD

     3: [      0x600e10; memsz:    240] flags: 0x6; PT_LOAD

     4: [      0x600e28; memsz:    1d0] flags: 0x6; PT_DYNAMIC

     5: [      0x400254; memsz:     44] flags: 0x4; PT_NOTE

     6: [      0x400970; memsz:     3c] flags: 0x4; PT_GNU_EH_FRAME

     7: [         (nil); memsz:      0] flags: 0x6; PT_GNU_STACK

     8: [      0x600e10; memsz:    1f0] flags: 0x4; PT_GNU_RELRO
Имя: "linux-vdso.so.1" (4 сегментов)

     0: [0x7ffc6edd1000; memsz:    e89] flags: 0x5; PT_LOAD

     1: [0x7ffc6edd1360; memsz:    110] flags: 0x4; PT_DYNAMIC

     2: [0x7ffc6edd17b0; memsz:     3c] flags: 0x4; PT_NOTE

     3: [0x7ffc6edd17ec; memsz:     3c] flags: 0x4; PT_GNU_EH_FRAME
Имя: "/lib64/libc.so.6" (10 сегментов)

     0: [0x7f55712ce040; memsz:    230] flags: 0x5; PT_PHDR

     1: [0x7f557145b980; memsz:     1c] flags: 0x4; PT_INTERP

     2: [0x7f55712ce000; memsz: 1b6a5c] flags: 0x5; PT_LOAD

     3: [0x7f55716857a0; memsz:   9240] flags: 0x6; PT_LOAD

     4: [0x7f5571688b80; memsz:    1f0] flags: 0x6; PT_DYNAMIC

     5: [0x7f55712ce270; memsz:     44] flags: 0x4; PT_NOTE

     6: [0x7f55716857a0; memsz:     78] flags: 0x4; PT_TLS

     7: [0x7f557145b99c; memsz:   544c] flags: 0x4; PT_GNU_EH_FRAME

     8: [0x7f55712ce000; memsz:      0] flags: 0x6; PT_GNU_STACK

     9: [0x7f55716857a0; memsz:   3860] flags: 0x4; PT_GNU_RELRO
Имя: "/lib64/ld-linux-x86-64.so.2" (7 сегментов)

     0: [0x7f557168f000; memsz:  20828] flags: 0x5; PT_LOAD

     1: [0x7f55718afba0; memsz:   15a8] flags: 0x6; PT_LOAD

     2: [0x7f55718afe10; memsz:    190] flags: 0x6; PT_DYNAMIC

     3: [0x7f557168f1c8; memsz:     24] flags: 0x4; PT_NOTE

     4: [0x7f55716acec4; memsz:    604] flags: 0x4; PT_GNU_EH_FRAME

     5: [0x7f557168f000; memsz:      0] flags: 0x6; PT_GNU_STACK

     6: [0x7f55718afba0; memsz:    460] flags: 0x4; PT_GNU_RELRO
```

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

```
#define _GNU_SOURCE
#include <link.h>
#include <stdlib.h>
#include <stdio.h>
static int
callback(struct dl_phdr_info *info, size_t size, void *data)
{

    char *type;

    int p_type, j;

    printf("Имя: \"%s\" (%d сегментов)\n", info->dlpi_name,

               info->dlpi_phnum);

    for (j = 0; j < info->dlpi_phnum; j++) {

        p_type = info->dlpi_phdr[j].p_type;

        type =  (p_type == PT_LOAD) ? "PT_LOAD" :

                (p_type == PT_DYNAMIC) ? "PT_DYNAMIC" :

                (p_type == PT_INTERP) ? "PT_INTERP" :

                (p_type == PT_NOTE) ? "PT_NOTE" :

                (p_type == PT_INTERP) ? "PT_INTERP" :

                (p_type == PT_PHDR) ? "PT_PHDR" :

                (p_type == PT_TLS) ? "PT_TLS" :

                (p_type == PT_GNU_EH_FRAME) ? "PT_GNU_EH_FRAME" :

                (p_type == PT_GNU_STACK) ? "PT_GNU_STACK" :

                (p_type == PT_GNU_RELRO) ? "PT_GNU_RELRO" : NULL;

        printf("    %2d: [%14p; memsz:%7lx] flags: 0x%x; ", j,

                (void *) (info->dlpi_addr + info->dlpi_phdr[j].p_vaddr),

                info->dlpi_phdr[j].p_memsz,

                info->dlpi_phdr[j].p_flags);

        if (type != NULL)

            printf("%s\n", type);

        else

            printf("[другой (0x%x)]\n", p_type);

    }

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

    dl_iterate_phdr(callback, NULL);

    exit(EXIT_SUCCESS);
}
```

## СМОТРИТЕ ТАКЖЕ
ldd(1), objdump(1), readelf(1), dladdr(3), dlopen(3), elf(5), ld.so(8)

Executable and Linking Format Specification в веб.


dladdr

title: dladdr(3)

text:
# dladdr(3)

## ИМЯ
dladdr, dladdr1 - транслирует адрес в информацию о символе

## ОБЗОР

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

```
int dladdr(void *addr, Dl_info *info);
```

```
int dladdr1(void *addr, Dl_info *info, void **extra_info, int flags);
```

```
Компонуется при указании параметра -ldl.
```

## ОПИСАНИЕ
Функция dladdr() определяет, в каком из загруженных общих объектов приложения расположен адрес, указанный в addr. Если объект находится, то dladdr() возвращает информацию об общем объекте и символе, который относится к адресу addr. Данная информация возвращается в виде структуры Dl_info:

```
typedef struct {

    const char *dli_fname;  /* путь к общему объекту, который

                               содержит адрес */

    void       *dli_fbase;  /* начальный адрес, по которому расположен

                               общий объект */

    const char *dli_sname;  /* имя символа, к которому относится

                               адрес addr */

    void       *dli_saddr;  /* точный адрес символа с

                               именем dli_sname */
} Dl_info;
```

Если символ, соответствующий адресу addr, не найден, то dli_sname и dli_saddr устанавливаются в NULL.

Функция dladdr1() подобна dladdr(), но возвращает дополнительную информацию в аргументе extra_info. Возвращаемая информация зависит от значения, указанного в flags, которое может быть одним из:

RTLD_DL_LINKMAP

Возвратить указатель на карту ссылок для совпадающего файла. Аргумент extra_info указывает на указатель на структуру link_map (т. е., struct link_map **), определённую в <link.h> так:

```
struct link_map {

    ElfW(Addr) l_addr;  /* разница между

                           адресом в файле ELF и

                           адресом в памяти */

    char      *l_name;  /* абсолютный путь, где

                           был найден объект */

    ElfW(Dyn) *l_ld;    /* динамический раздел

                           общего объекта */

    struct link_map *l_next, *l_prev;

                        /* цепочка загруженных объектов */

    /* дополнительные поля, зависящие от

       реализации */
};

```

RTLD_DL_SYMENT

Возвращает указатель на элемент символьной таблицы ELF с совпадающим символом. Аргумент extra_info — указатель на символьный указатель: const ElfW(Sym) **. Макрос ElfW() преобразует этот аргумент в имя типа данных ELF, подходящее для аппаратной архитектуры. Например, на 64-битной платформе ElfW(Sym) возвращает имя типа данных Elf64_Sym, которое определено в <elf.h> так:

```
typedef struct  {

    Elf64_Word    st_name;     /* имя символа */

    unsigned char st_info;     /* тип символа и привязка */

    unsigned char st_other;    /* видимость символа */

    Elf64_Section st_shndx;    /* номер раздела */

    Elf64_Addr    st_value;    /* значение символа */

    Elf64_Xword   st_size;     /* размер символа */
} Elf64_Sym;

```

Поле st_name — номер в строковой таблице.

В поле st_info закодирован тип и привязка символа. Тип можно извлечь с помощью макроса ELF64_ST_TYPE(st_info) (или ELF32_ST_TYPE(), на 32-битных платформах), который возвращает одно из следующих значений:

Значение

Описание

STT_NOTYPE

тип символа не указан

STT_OBJECT

символ является объектом данных

STT_FUNC

символ является объектом кода

STT_SECTION

символ, связанный с разделом

STT_FILE

имя символа является именем файла

STT_COMMON

символ является объектом общих данных

STT_TLS

символ является объектом локальных данных нити

STT_GNU_IFUNC

символ является объектом скрытого кода

Привязку символа можно извлечь из поля st_info с помощью макроса ELF64_ST_BIND(st_info) (или ELF32_ST_BIND(), на 32-битных платформах), который возвращает одно из следующих значений:

Значение

Описание

STB_LOCAL

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

STB_GLOBAL

глобальный символ

STB_WEAK

символ со слабой привязкой

STB_GNU_UNIQUE

уникальный символ

В поле st_other содержится значение видимости символа, которую можно извлечь с помощью макроса ELF64_ST_VISIBILITY(st_info) (или ELF32_ST_VISIBILITY(), на 32-битных платформах), который возвращает одно из следующих значений:

Значение

Описание

STV_DEFAULT

правила видимости символов по умолчанию

STV_INTERNAL

скрытый класс, зависящий от процессора

STV_HIDDEN

Символ недоступен в других модулях

STV_PROTECTED

невыгружаемый, не экспортируется

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении эти функции возвращают ненулевое значение. Если адрес, указанный в addr, мог бы совпасть с общим объектом, но не с символом в общем объекте, то полям info->dli_sname и info->dli_saddr присваивается значение NULL.

Если адрес, указанный addr, мог бы совпасть с общим объектом, то эти функции возвращают 0. В этом случае сообщение об ошибке не доступно через dlerror(3).

## ВЕРСИИ
Функция dladdr() есть в glibc 2.0 и новее. Функция dladdr1() впервые появилась в glibc 2.3.3.

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

Интерфейс

Атрибут

Значение

dladdr(), dladdr1()

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

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
Данные функции являются нестандартными расширениями GNU, которые также присутствуют в Solaris.

## ДЕФЕКТЫ
Иногда указатели на функции, передаваемые в dladdr(), могут вас удивить. На некоторых архитектурах (в частности, i386- и x86-64), dli_fname и dli_fbase могут указывать на объект, из которого вызывалась функция dladdr(), даже если функция, использовавшаяся как аргумент, должна быть из динамически скомпонованной библиотеки.

Проблема в том, что указатель на функцию по прежнему ищется во время компиляции, но всего лишь указывает на раздел plt (таблицу компоновки процедур) первоначального объекта (которая размещает вызов после запроса динамического компоновщика на поиск символа). Чтобы обойти это, вы можете попробовать скомпилировать независимый от размещения код: в этом случае компилятор больше не сможет подготовить указатель во время компиляции и gcc(1) создаст код, который просто загрузит конечный адрес символа из got (глобальной таблицы смещений) при запуске до передачи его в dladdr().

## СМОТРИТЕ ТАКЖЕ
dl_iterate_phdr(3), dlinfo(3), dlopen(3), dlsym(3), ld.so(8)


dlerror

title: dlerror(3)

text:
# dlerror(3)

## ИМЯ
dlerror - возвращает справку по ошибке для функций программного интерфейса dlopen

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

char *dlerror(void);

Компонуется при указании параметра -ldl.

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

Функция dlerror() возвращает NULL, если ошибок не было с начала инициализации или с момента её последнего вызова.

## ВЕРСИИ
Функция dlerror() есть в glibc 2.0 и новее.

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

Интерфейс

Атрибут

Значение

dlerror()

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

MT-Safe

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

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

### История
Эта функция является частью программного интерфейса dlopen, возникшего в SunOS.

## ПРИМЕР
Смотрите dlopen(3).

## СМОТРИТЕ ТАКЖЕ
dladdr(3), dlinfo(3), dlopen(3), dlsym(3)


dlinfo

title: dlinfo(3)

text:
# dlinfo(3)

## ИМЯ
dlinfo - возвращает информацию о динамически загруженном объекте

## ОБЗОР

```
#define _GNU_SOURCE
#include <link.h>
#include <dlfcn.h>
```

```
int dlinfo(void *handle, int request, void *info);
```

```
Компонуется при указании параметра -ldl.
```

## ОПИСАНИЕ
Функция dlinfo() возвращает информацию о динамически загруженном объекте, на который указывает handle (обычно полученный ранее вызовом dlopen(3) или dlmopen(3)). В аргументе request указывается какую информацию нужно получить. Аргумент info — указатель на буфер для хранения информации, возвращаемой вызовом; тип данного аргумента зависит от request.

Для request поддерживаются следующие значения (соответствующий тип info показан в скобках):

RTLD_DI_LMID (Lmid_t *)

Возвратить ID списка карты связи (link-map list, пространство имён), в который загружен handle.

RTLD_DI_LINKMAP (struct link_map **)

Возвратить указатель на структуру link_map, соответствующую handle. Аргумент info указывает на указатель на структуру link_map, определённую в <link.h> следующим образом:

```
struct link_map {

    ElfW(Addr) l_addr;  /* разница между

                           адресом в файле ELF и

                           адресом в памяти */

    char      *l_name;  /* абсолютный путь, где

                           был найден объект */

    ElfW(Dyn) *l_ld;    /* динамический раздел

                           общего объекта */

    struct link_map *l_next, *l_prev;

                        /* цепочка загруженных объектов */

    /* дополнительные поля, зависящие от

       реализации */
};

```

RTLD_DI_ORIGIN (char *)

Скопировать путь источника общего объекта соответствующего handle в место, указанное info.

RTLD_DI_SERINFO (Dl_serinfo *)

Возвратить пути поиска библиотек общего объекта, на который указывает handle. Аргумент info — указатель на Dl_serinfo с путями поиска. Так как количество путей поиска может быть разным, то размер структуры, на которую указывает info, может быть различным. Запрос RTLD_DI_SERINFOSIZE, описанный далее, позволяет приложению установить подходящий размер. Вызывающий должен выполнить следующие шаги:

1.

Использовать запрос RTLD_DI_SERINFOSIZE для заполнения структуры Dl_serinfo размером (dls_size) структуры, необходимой для последующего запроса RTLD_DI_SERINFO.

2.

Выделить буфер Dl_serinfo правильного размера (dls_size).

3.

Использовать запрос RTLD_DI_SERINFOSIZE для заполнения полей dls_size и dls_cnt буфера, выделенного на предыдущем шаге.

4.

Использовать RTLD_DI_SERINFO для получения путей поиска библиотек.

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

```
typedef struct {

    size_t dls_size;           /* размер в байтах

                                  всего буфера */

    unsigned int dls_cnt;      /* количество элементов

                                  в «dls_serpath» */

    Dl_serpath dls_serpath[1]; /* на самом деле больше,

                                  элементы «dls_cnt» */
} Dl_serinfo;

```

Каждый из элементов dls_serpath, в упомянутой выше структуре, представляет собой структуру следующего вида:

```
typedef struct {

    char *dls_name;            /* имя каталога в

                                   путях поиска библиотек */

    unsigned int dls_flags;    /* показывает, откуда

                                  возник каталог */
} Dl_serpath;

```

Поле dls_flags в настоящее время не используется и всегда равно нулю.

RTLD_DI_SERINFOSIZE (Dl_serinfo *)

Заполнить поля dls_size и dls_cnt структуры Dl_serinfo, на которую указывает info, значениями, подходящими для выделения буфера, который будет использоваться в последующем запросе RTLD_DI_SERINFO.

RTLD_DI_TLS_MODID (size_t *, начиная с glibc 2.4)

Получить ID модуля сегмента TLS (локальное хранилище нити) общего объекта, которое используется в перемещениях TLS. Если этот объект не задаёт сегмент TLS, то в *info помещается ноль.

RTLD_DI_TLS_DATA (void **, начиная с glibc 2.4)

Получить указатель на блок TLS вызывающей нити, соответствующий этому сегменту TLS общего объекта. Если этот объект не задаёт сегмент PT_TLS, или если у вызывающей нити для этого не выделен блок, то в *info помещается NULL.

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

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

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

Интерфейс

Атрибут

Значение

dlinfo()

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

MT-Safe

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

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

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

```
$ ./a.out /lib64/libm.so.6
dls_serpath[0].dls_name = /lib64
dls_serpath[1].dls_name = /usr/lib64
```

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

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

    void *handle;

    Dl_serinfo serinfo;

    Dl_serinfo *sip;

    int j;

    if (argc != 2) {

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

        exit(EXIT_FAILURE);

    }

    /* получаем описатель общего объекта, указанного в командной строке */

    handle = dlopen(argv[1], RTLD_NOW);

    if (handle == NULL) {

        fprintf(stderr, "ошибка dlopen(): %s\n", dlerror());

        exit(EXIT_FAILURE);

    }

    /* определяем размер буфера, который мы должны передать

       RTLD_DI_SERINFO */

    if (dlinfo(handle, RTLD_DI_SERINFOSIZE, &serinfo) == -1) {

        fprintf(stderr, "ошибка RTLD_DI_SERINFOSIZE: %s\n", dlerror());

        exit(EXIT_FAILURE);

    }

    /* выделяем буфер для RTLD_DI_SERINFO */

    sip = malloc(serinfo.dls_size);

    if (sip == NULL) {

        perror("malloc");

        exit(EXIT_FAILURE);

    }

    /* инициализируем поля 'dls_size' и 'dls_cnt' в только

       что выделенном буфере */

    if (dlinfo(handle, RTLD_DI_SERINFOSIZE, sip) == -1) {

        fprintf(stderr, "ошибка RTLD_DI_SERINFOSIZE: %s\n", dlerror());

        exit(EXIT_FAILURE);

    }

    /* получаем и печатаем список поиска библиотек */

    if (dlinfo(handle, RTLD_DI_SERINFO, sip) == -1) {

        fprintf(stderr, "ошибка RTLD_DI_SERINFO: %s\n", dlerror());

        exit(EXIT_FAILURE);

    }

    for (j = 0; j < serinfo.dls_cnt; j++)

        printf("dls_serpath[%d].dls_name = %s\n",

                j, sip->dls_serpath[j].dls_name);

    exit(EXIT_SUCCESS);
}
```

## СМОТРИТЕ ТАКЖЕ
dl_iterate_phdr(3), dladdr(3), dlerror(3), dlopen(3), dlsym(3), ld.so(8)


dlopen

title: dlopen(3)

summary: открывает и закрывает общий объект

text:
# dlopen(3)

## ИМЯ
dlclose, dlopen, dlmopen - открывает и закрывает общий объект

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

void *dlopen(const char *filename, int flags);

int dlclose(void *handle);

\#define _GNU_SOURCE

\#include <dlfcn.h>

void *dlmopen (Lmid_t lmid, const char *filename, int flags);

Компонуется при указании параметра -ldl.

## ОПИСАНИЕ

### dlopen()
Функция dlopen() загружает динамический общий объект (общую библиотеку) из файла, имя которого указано в строке filename (завершается null) и возвращает скрытный описатель на загруженный объект. Данный описатель используется другими функциями программного интерфейса dlopen, такими как dlsym(3), dladdr(3), dlinfo(3) и dlclose().

Если filename равно NULL, то возвращается описатель основной программы. Если filename содержит косую черту («/»), то это воспринимается как имя с путём (относительным или абсолютным). Иначе динамический компоновщик ищет объект в следующих местах (подробности смотрите в ld.so(8)):

o

(только в ELF) Если исполняемый файл вызывающей программы содержит метку DT_RPATH, т не содержит метки DT_RUNPATH, то производится поиск в каталогах, описанных в метке DT_RPATH.

o

Если при запуске программы была определена переменная окружения LD_LIBRARY_PATH, содержащая список каталогов через двоеточие, то производится поиск в этих каталогах (по соображениям безопасности эта переменная игнорируется для программ с установленными битами set-user-ID и set-group-ID).

o

(только в ELF) Если исполняемый файл вызывающей программы содержит метку DT_RUNPATH, то производится поиск по каталогам, перечисленным в этой метке.

o

Производится проверка в кэширующем файле /etc/ld.so.cache (обслуживается ldconfig(8)) на предмет наличия записи для filename.

o

Просматриваются каталоги /lib и /usr/lib (именно в таком порядке).

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

В flags должно быть одно из двух следующих значений:

RTLD_LAZY

Выполнять позднее связывание (lazy binding). Выполняется поиск только тех символов, на которые есть ссылки из кода. Если на символ никогда не ссылаются, то он никогда не будет разрешён (позднее связывание выполняется только при ссылке на функции; ссылки на переменные всегда привязываются сразу при загрузке общего объекта). Начиная с libc 2.1.1, этот флаг заменяется на значение переменной окружения LD_BIND_NOW.

RTLD_NOW

Если указано данное значение или переменная окружения LD_BIND_NOW не пуста, то все неопределённые символы в общем объекте ищутся до возврата из dlopen(). Если этого сделать не удаётся, то возвращается ошибка.

Также в В flags может быть ноль или более значение, объединяемых по ИЛИ:

RTLD_GLOBAL

Символы, определённые в этом общем объекте, будут доступны при поиске символов, для общих объектов, загружаемых далее.

RTLD_LOCAL

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

RTLD_NODELETE (начиная с glibc 2.2)

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

RTLD_NOLOAD (начиная с glibc 2.2)

Не загружать общий объект. Это можно использовать для тестирования того, что объект уже загружен (dlopen() возвращает NULL, если нет, или описатель объекта в противном случае). Данный флаг также можно использовать для изменения флагов уже загруженного объекта. Например, общий объект, который был загружен ранее с RTLD_LOCAL, можно открыть повторно с RTLD_NOLOAD | RTLD_GLOBAL.

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

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

Если значение filename равно NULL, то возвращается описатель для главной программы. При передаче в dlsym(), этот описатель вызывает поиск символа в главной программе, затем во все общих объектах, загруженных при запуске программы, и затем во всех общих объектах, загруженных dlopen() с флагом RTLD_GLOBAL.

Поиск символьных ссылок общего объекта производится следующим образом (в таком порядке): символы в карте ссылок объектов, загруженных для главной программы и её зависимостей; символы в общих объектах (и их зависимостях), которые были открыты ранее с помощью dlopen() и флага RTLD_GLOBAL; определения в самом общем объекте (и любых зависимостях, которые были загружены для этого объекта).

Все глобальные символы в исполняемом файле, которые были помещены в его таблицу динамических символов посредством ld(1), также могут быть использованы при поиске ссылок динамически загружаемого общего объекта. Символы могут попасть в таблицу динамических символов из-за того, что исполняемый файл был скомпонован с флагом «-rdynamic» (или его синонимом «--export-dynamic»), который помещает что все глобальные символы исполняемого файла в таблицу динамических символов, или из-за того, что ld(1) определил зависимость от символа из другого объекта при статической компоновке.

Если общий объект загружается с помощью dlopen() повторно, то возвращается тот же описатель на объект. Динамический компоновщик ведёт счётчик ссылок для описателей объектов, поэтому динамически загруженный общий объект не высвобождается dlclose() до тех пор, пока он не будет вызвана столько же раз сколько и dlopen(). Процедуры инициализации (смотрите ниже) вызываются только когда объект действительно загружается в память (т. е., когда счётчик ссылок увеличивается на 1).

Последующий вызов dlopen(), загружающий тот же общий объект с флагом RTLD_NOW, может привести к поиску символов для общего объекта ранее загруженного с флагом RTLD_LAZY. Схожим образом объект, открытый ранее с флагом RTLD_LOCAL, в последующем вызове dlopen() может быть преобразован в RTLD_GLOBAL.

Если по какой-то причине dlopen() завершается неудачно, то возвращается NULL.

### dlmopen()
Данная функция делает то же самое что и dlopen(), аргументы filename и flags, а также возвращаемое значение — такие же, отличия описаны далее.

Функция dlmopen() отличается от dlopen(), главным образом в том, что имеет дополнительный аргумент lmid, в котором задаётся список карт связей (link-map list, ещё называемый пространством имён), в который должен быть загружен общий объект (dlopen() добавляет динамически загружаемый общий объект в тоже пространство имён, в котором находится общий объект, из которого был вызван dlopen()). Тип Lmid_t является скрытым описателем, который ссылается на пространство имён.

В аргументе lmid может быть указан ID существующего пространства имён (который может быть получен с помощью dlinfo(3) с запросом RTLD_DI_LMID) или одно из следующих специальных значений:

LM_ID_BASE

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

LM_ID_NEWLM

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

Если filename равно NULL, то для lmid разрешено только значение LM_ID_BASE.

### dlclose()
Функция dlclose() уменьшает счётчик ссылок на динамически загружаемый общий объект, на который ссылается handle.

Если счётчик ссылок достигает нуля и символы этого объекта не нужны другим объектам, то объект выгружается после первого вызова любого деструктора, определённого в объекте (символы в этом объекте могут требоваться в другом объекте из-за того, что этот объект был открыт с флагом RTLD_GLOBAL и один из его символов совпадает с расположением из другого объекта).

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

Успешный возврат из dlclose() не гарантирует, что символы, связанные с handle удалятся из адресного пространства вызывающего. В дополнении к ссылкам, полученным из-за явного вызова dlopen(), общий объект может быть загружен неявно (и увеличится счётчик ссылок), так как от него зависят другие общие объекты. Общий объект будет удалён из адресного пространства только когда будут удалены все ссылки на него.

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

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

Ошибки, возникшие в этих функциях, можно определить с помощью dlerror(3).

## ВЕРСИИ
Функции dlopen() и dlclose() имеются в glibc 2.0 и новее. Функция dlmopen() впервые появилась в glibc 2.3.4.

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

Интерфейс

Атрибут

Значение

dlopen(), dlmopen(), dlclose()

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

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
В POSIX.1-2001 описаны dlclose() и dlopen(). Функция dlmopen() является расширением GNU.

Флаги RTLD_NOLOAD, RTLD_NODELETE и RTLD_DEEPBIND являются расширением GNU; первые два этих флага есть также в Solaris.

## ЗАМЕЧАНИЯ

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

Функция dlmopen() позволяет достичь изоляции загружаемых объектов — загружает общий объект в новое пространство имён без показа символов всему приложению, а только новому объекту. Заметим, что использование флага RTLD_LOCAL недостаточно для этой цели, так как он делает недоступным символы общего объекта любому другому общему объекту. В некоторых случаях может понадобиться, чтобы символы динамически загружаемого общего объекта были доступны другим общим объектам (но не всем объектам) без показа этих символов всему приложению. Этого можно достичь используя отдельное пространство имён и флаг RTLD_GLOBAL.

Функцию dlmopen() также можно использовать для получения изолированности, большей чем с флагом RTLD_LOCAL. В частности, общие объекты, загруженные с RTLD_LOCAL, могут быть видимы при флаге RTLD_GLOBAL, если они зависят от другого общего объекта, загруженного с флагом RTLD_GLOBAL. То есть, RTLD_LOCAL недостаточно изолирует загружаемый общий объект, за исключением случая (редкого), где он явно контролирует зависимости всех загружаемых общих объектов.

Возможный случай применения dlmopen() — модули, где автор инфраструктуры модулей не может доверять авторам модулей и не хочет, чтобы все неопределённые символы инфраструктуры модулей определялись из модулей. Другой случай использования — загрузка одного объекта несколько раз. Без dlmopen() это потребовало бы создание отдельных копий файлов общего объекта. С помощью dlmopen() можно загрузить один файл общего объекта в разные пространства имён.

В реализации glibc поддерживается до 16 пространств имён.

### Функции инициализации и завершения
Общие объекты могут экспортировать с помощью атрибутов функций __attribute__((constructor)) и __attribute__((destructor)). Функции-конструкторы выполняются перед возвратом из dlopen(), а функции-деструкторы выполняются перед возвратом из dlclose(). Общий объект может экспортировать несколько конструкторов и деструкторов, с каждой функцией может быть связан приоритет, которым определяется порядок выполнения функций. Подробней смотрите info-страницу gcc (раздел «Атрибуты функции»).

Старым способом достижения того же (частично) результата является использование двух специальных символов, распознаваемых компоновщиком: _init и _fini. Если динамически загружаемый общий объект экспортирует процедуру с именем _init(), то её код выполняется после загрузки общего объекта, но возвращения из dlopen(). Если общий объект экспортирует процедуру с именем _fini(), то её код выполняется перед выгрузкой объекта. В этом случае не должна выполняться компоновка с системными файлами начального запуска, в которых содержатся версии по умолчанию этих файлов; для этого нужно вызывать gcc(1) с параметром командной строки -nostartfiles.

Использование _init и _fini теперь не рекомендуется, используйте упомянутые конструкторы и деструкторы, которые, среди прочих преимуществ, позволяют определять многократно вызываемые функции инициализации и завершения.

Начиная с glibc 2.2.3, atexit(3) может использоваться для регистрации обработчика завершения работы, который автоматически вызывается при выгрузке общего объекта.

### История
Эти функции являются часть программного интерфейса dlopen, возникшего в SunOS.

## ДЕФЕКТЫ
В glibc 2.24 указание флага RTLD_GLOBAL при вызове dlmopen() приводит к ошибке. Кроме этого, указание RTLD_GLOBAL при вызове dlopen() приводит к падению программы (SIGSEGV), если вызов делается из любого объекта, загруженного в пространство имён, отличное от начального пространства имён.

## ПРИМЕР
Программа, представленная ниже, загружает библиотеку math (glibc), ищет адрес функции cos(3) и печатает косинус 2.0. Пример сборки и выполнения программы:

```
$ cc dlopen_demo.c -ldl
$ ./a.out
-0.416147
```

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

```
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <gnu/lib-names.h>  /* определение LIBM_SO (который

                               является строкой вида libm.so.6») */
int
main(void)
{

    void *handle;

    double (*cosine)(double);

    char *error;

    handle = dlopen(LIBM_SO, RTLD_LAZY);

    if (!handle) {

        fprintf(stderr, "%s\n", dlerror());

        exit(EXIT_FAILURE);

    }

    dlerror();    /* Очистка всех результатов ошибок */

    cosine = (double (*)(double)) dlsym(handle, "cos");

    /* Согласно стандарту ISO C, преобразование между указателями на

       функции и «void *», использовавшемуся выше, приводит к

       неопределённым результатам. В POSIX.1-2003 и POSIX.1-2008

       принимается такое поведение и предлагается следующий

       обходной вариант:

           *(void **) (&cosine) = dlsym(handle, "cos");

       Такое (топорное) преобразование удовлетворяет стандарту ISO C и

       предупреждений компилятора не будет.

       Список опечаток 2013 к POSIX.1-2008 (т.н. POSIX.1-2013) улучшает

       состояние, требуя от реализаций поддержки преобразования «void *»

       в указатель на функцию. Тем не менее, некоторые компиляторы

       (например, gcc с параметром «-pedantic») могут выдавать

       предупреждение о преобразовании в этой программе. */

    error = dlerror();

    if (error != NULL) {

        fprintf(stderr, "%s\n", error);

        exit(EXIT_FAILURE);

    }

    printf("%f\n", (*cosine)(2.0));

    dlclose(handle);

    exit(EXIT_SUCCESS);
}
```

## СМОТРИТЕ ТАКЖЕ
ld(1), ldd(1), pldd(1), dl_iterate_phdr(3), dladdr(3), dlerror(3), dlinfo(3), dlsym(3), rtld-audit(7), ld.so(8), ldconfig(8)

Страницы в формате Info для gcc и ld


dlsym

title: dlsym(3)

text:
# dlsym(3)

## ИМЯ
dlsym, dlvsym - возвращает адрес символа из общего объекта или исполняемого файла

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

void *dlsym(void *handle, const char *symbol);

\#define _GNU_SOURCE

\#include <dlfcn.h>

void *dlvsym(void *handle, char *symbol, char *version);

Компонуется при указании параметра -ldl.

## ОПИСАНИЕ
Функции dlsym() передаётся «описатель» динамически загруженного объекта, возвращаемого dlopen(3) и имя символа (с null в конце). В результате функция возвращает адрес, по которому символ расположен в памяти. Если символ не найден в указанном объекте или во всех общих объектах, которые были автоматически загружены dlopen(3) на момент загрузки объекта, то dlsym() возвращает NULL (поиск, выполняемый dlsym(), охватывает всё дерево зависимостей этих общих объектов).

В нестандартных ситуациях (смотрите ЗАМЕЧАНИЯ) в действительности значение символа может быть NULL. Поэтому NULL, возвращаемый dlsym(), ненужно считать ошибкой. Правильным способом определения ошибки, если символ равен NULL, является вызов dlerror(3) для сброса старого состояния ошибки, а затем вызов dlsym(), и повторный вызов dlerror(3), сохранение полученного значения в переменную и проверка этого значения на NULL.

Существует два специальных псевдо-описателя, которые можно указать в handle:

RTLD_DEFAULT

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

RTLD_NEXT

Найти следующее появление нужного символа, начиная поиск с текущего объекта. Это позволяет предоставить обёрточную функцию в другой общем объекте, таким образом, что например, определение функции в предварительно загружаемом общем объекте (смотрите LD_PRELOAD в ld.so(8)) может найти и вызвать «реальную» функцию, предоставленную в другом общем объекте (или, что важно, «следующее» определение функции в случаях, когда есть несколько уровней предварительной загрузки).

Чтобы получить определения RTLD_DEFAULT и RTLD_NEXT из <dlfcn.h>, нужно задать макрос тестирования свойств _GNU_SOURCE.

Функция dlvsym() делает то же самое что и dlsym(), но в качестве дополнительного аргумента ожидает строку версии.

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

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

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

Интерфейс

Атрибут

Значение

dlsym(), dlvsym()

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

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
В POSIX.1-2001 есть описание dlsym(). Функция dlvsym() является расширением GNU.

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

### История
Функция dlsym() является частью программного интерфейса dlopen, возникшего в SunOS. В этой системе нет dlvsym().

## ПРИМЕР
Смотрите dlopen(3).

## СМОТРИТЕ ТАКЖЕ
dl_iterate_phdr(3), dladdr(3), dlerror(3), dlinfo(3), dlopen(3), ld.so(8)


title: drand48(3)

text:
# drand48(3)

## ИМЯ
drand48, erand48, lrand48, nrand48, mrand48, jrand48, srand48, seed48, lcong48 - генерация равномерно распределённых псевдослучайных чисел

## ОБЗОР

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

```
double drand48(void);
```

```
double erand48(unsigned short xsubi[3]);
```

```
long int lrand48(void);
```

```
long int nrand48(unsigned short xsubi[3]);
```

```
long int mrand48(void);
```

```
long int jrand48(unsigned short xsubi[3]);
```

```
void srand48(long int seedval);
```

```
unsigned short *seed48(unsigned short seed16v[3]);
```

```
void lcong48(unsigned short param[7]);
```

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

Для всех вышеуказанных функций: _XOPEN_SOURCE

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

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

## ОПИСАНИЕ
Данные функции генерируют псевдослучайные числа при помощи линейного конгруэнтного метода и арифметики на основе 48-битного целого.

Функции drand48() и erand48() возвращают неотрицательное значение в формате с плавающей запятой двойной точности, равномерно распределённые в диапазоне [0.0, 1.0).

Функции lrand48() и nrand48() возвращают неотрицательные целые числа типа long, равномерно распределённые в интервале [0, 2^31).

Функции mrand48() и jrand48() возвращают целые числа типа long со знаком, равномерно распределённые в интервале [-2^31, 2^31).

Функции srand48(), seed48() и lcong48() являются функциями-инициализаторами и должны быть вызваны до использования drand48(), lrand48() или mrand48(). Функциям erand48(), nrand48() и jrand48() для первого вызова инициализаторы не требуются.

Все функции работают за счёт генерации последовательности 48-битных целых чисел Xi согласно формуле линейного конгруэнтного метода:

```
Xn+1 = (aXn + c) mod m, где n >= 0
```

Параметр m = 2^48, поэтому в вычислениях используются 48-битные целые числа. Если lcong48() не вызывалась, то a и c принимают следующие значения:

```
a = 0x5DEECE66D
c = 0xB
```

Для получения значения, возвращаемого любой из функций (drand48(), erand48(), lrand48(), nrand48(), mrand48() или jrand48()), сначала генерируется следующее 48-битное Xi в последовательности. Затем подходящее число бит (согласно типу возвращаемых данных) копируется в верхние биты Xi и трансформируется во возвращаемое значение.

Функции drand48(), lrand48() и mrand48() сохраняют последнее сгенерированное 48-битное значение Xi во внутреннем буфере. Для функций erand48(), nrand48() и jrand48() требуется, чтобы вызывающая программа создавала хранилище для последующих значений Xi и указывала его в аргументе-массиве xsubi. Функции инициализируются путём помещения начального значения Xi в массив до их первого вызова.

Функция инициализации srand48() устанавливает верхние 32 бита Xi в аргументе seedval. Нижние 16 бит устанавливаются в обязательное значение 0x330E.

Функция инициализации seed48() устанавливает Xi в 48-битное значение, указанное в аргументе-массиве seed16v. Предыдущее значение Xi копируется во внутренний буфер, указатель на который возвращается seed48().

Функция инициализации lcong48() позволяет пользователю указывать первоначальные значения для Xi, a и c. Для Xi используется аргумент массива param[0-2], для a — param[3-5], а для c — param[6]. После вызова lcong48() следующий вызов srand48() или seed48() восстановит стандартные значения a и c.

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

Интерфейс

Атрибут

Значение

drand48(), erand48(), lrand48(), nrand48(), mrand48(), jrand48(), srand48(), seed48(), lcong48()

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

MT-Unsafe race:drand48

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

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

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


title: drand48_r(3)

text:
# drand48_r(3)

## ИМЯ
drand48_r, erand48_r, lrand48_r, nrand48_r, mrand48_r, jrand48_r, srand48_r, seed48_r, lcong48_r - генерация равномерно распределённых псевдослучайных чисел реентерабельным способом

## ОБЗОР

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

```
int drand48_r(struct drand48_data *buffer, double *result);
```

```
int erand48_r(unsigned short xsubi[3],
              struct drand48_data *buffer, double *result);
```

```
int lrand48_r(struct drand48_data *buffer, long int *result);
```

```
int nrand48_r(unsigned short int xsubi[3],
              struct drand48_data *buffer, long int *result);
```

```
int mrand48_r(struct drand48_data *buffer,long int *result);
```

```
int jrand48_r(unsigned short int xsubi[3],
              struct drand48_data *buffer, long int *result);
```

```
int srand48_r(long int seedval, struct drand48_data *buffer);
```

```
int seed48_r(unsigned short int seed16v[3],
             struct drand48_data *buffer);
```

```
int lcong48_r(unsigned short int param[7],
              struct drand48_data *buffer);
```

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

Для всех вышеуказанных функций:

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

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

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

Перед первым использованием эта структура должна быть инициализирована, например, заполнена нулями или посредством вызова функции srand48_r(), seed48_r() или lcong48_r().

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Возвращаемое значение равно 0.

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

Интерфейс

Атрибут

Значение

drand48_r(), erand48_r(), lrand48_r(), nrand48_r(), mrand48_r(), jrand48_r(), srand48_r(), seed48_r(), lcong48_r()

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

MT-Safe race:buffer

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

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


duplocale

title: duplocale(3)

summary: создаёт копию объекта локали

text:
# duplocale(3)

## ИМЯ
duplocale - создаёт копию объекта локали

## ОБЗОР

```
#include <locale.h>
```

```
locale_t duplocale(locale_t locobj);
```

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

duplocale():

Начиная с glibc 2.10:

_XOPEN_SOURCE >= 700

До glibc 2.10:

_GNU_SOURCE

## ОПИСАНИЕ
Функция duplocale() создаёт копию объекта локали, на которую указывает locobj.

Если значение locobj равно LC_GLOBAL_LOCALE, то duplocale() создаёт объект локали, содержащий копию глобальной локали, задаваемой setlocale(3).

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении duplocale() возвращает описатель нового объекта локали. При ошибке возвращается (locale_t) 0, а errno присваивается код ошибки.

## ОШИБКИ
ENOMEM

Недостаточно памяти для создания копии объекта локали.

## ВЕРСИИ
Функция duplocale() впервые появилась в версии 2.3 библиотеки GNU C.

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

## ЗАМЕЧАНИЯ
Создание копии локали может пригодиться в следующих случаях:

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

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

loc = uselocale((locale_t) 0);

Такая последовательность необходима, так как вызов uselocale(3) может вернуть значение LC_GLOBAL_LOCALE, которое вызовет непредсказуемое поведение, если будет передано в функции, подобные toupper_l(3). Вызов duplocale() можно использовать для проверки, что значение LC_GLOBAL_LOCALE преобразуется в подходящий объект локали. Смотрите ПРИМЕР далее.

Каждый объект локали, созданный duplocale(), должен освобождаться с помощью freelocale(3).

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

```
$ ./a.out abc
ABC
```

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

```
#define _XOPEN_SOURCE 700
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \

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

    locale_t loc, nloc;

    char *p;

    if (argc != 2) {

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

        exit(EXIT_FAILURE);

    }

    /* Эта последовательность необходима, так как uselocale() может

       вернуть значение LC_GLOBAL_LOCALE, которое нельзя

       передавать как аргумент в toupper_l() */

    loc = uselocale((locale_t) 0);

    if (loc == (locale_t) 0)

        errExit("uselocale");

    nloc = duplocale(loc);

    if (nloc == (locale_t) 0)

        errExit("duplocale");

    for (p = argv[1]; *p; p++)

        putchar(toupper_l(*p, nloc));

    printf("\n");

    freelocale(nloc);

    exit(EXIT_SUCCESS);
}
```

## СМОТРИТЕ ТАКЖЕ
freelocale(3), newlocale(3), setlocale(3), uselocale(3), locale(5), locale(7)


dysize

title: dysize(3)

text:
# dysize(3)

## ИМЯ
dysize - возвращает количество дней в указанном году

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

int dysize(int year);

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

dysize():

начиная с glibc 2.19:

_DEFAULT_SOURCE

в glibc 2.19 и старее:

_BSD_SOURCE || _SVID_SOURCE

## ОПИСАНИЕ
Функция возвращает 365 для обычного года и 366 — для високосного. Подсчёт високосного года основан на формуле:

```
(year) %4 == 0 && ((year) %100 != 0 || (year) %400 == 0)
```

Формула определена в макросе __isleap(year), также находящемся в <time.h>.

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

Интерфейс

Атрибут

Значение

dysize()

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

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
Функция появилась в SunOS 4.x.

## ЗАМЕЧАНИЯ
Функция введена только для совместимости. Не используйте её в новых программах.

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


ecvt

title: ecvt(3)

text:
# ecvt(3)

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

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

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

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

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

ecvt(), fcvt():

Начиная с glibc 2.12:

```
(_XOPEN_SOURCE >= 500) ! (_POSIX_C_SOURCE >= 200112L)

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

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

До glibc 2.12:

_SVID_SOURCE || _XOPEN_SOURCE >= 500

## ОПИСАНИЕ
Функция ecvt() преобразует number в строку с завершающим null-символом ndigits цифр (количество ndigits усекается до пределов точности, определённых форматом double) и возвращает указатель на строку. Самый старший разряд полученного числа не будет равен нулю, если только само число number не равно нулю. Самый младший разряд округляется. Строка сама по себе не содержит разделителя целой и дробной части, однако позиция разделителя относительно начала строки сохраняется в *decpt. Отрицательное значение *decpt означает, что разделитель находится слева от начала строки. Если число number отрицательное, то *sign устанавливается в ненулевое значение, иначе равно нулю. Если number равно нулю, то не определено, равен ли *decpt 0 или 1.

Функция fcvt() аналогична ecvt(), за исключением того, что ndigits указывает число цифр после разделителя.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Обе функции, ecvt() и fcvt(), возвращают указатель на статическую строку, содержащую ASCII-представление number. Статическая строка перезаписывается каждый раз при вызове ecvt() или fcvt().

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

Интерфейс

Атрибут

Значение

ecvt()

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

MT-Unsafe race:ecvt

fcvt()

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

MT-Unsafe race:fcvt

## СООТВЕТСТВИЕ СТАНДАРТАМ
SVr2; отмечены в POSIX.1-2001 как УСТАРЕВШИЕ. В POSIX.1-2008 спецификации ecvt() и fcvt() удалены, вместо них рекомендуется использовать sprintf(3) (однако snprintf(3) может быть предпочтительнее).

## ЗАМЕЧАНИЯ
Не все локали используют точку в качестве разделителя целой и дробной части («десятичная точка»).

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


title: ecvt_r(3)

summary: преобразует число с плавающей запятой в

text:
# ecvt_r(3)

## ИМЯ
ecvt_r, fcvt_r, qecvt_r, qfcvt_r - преобразует число с плавающей запятой в строку

## ОБЗОР

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

```
int ecvt_r(double number, int ndigits, int *decpt,
           int *sign, char *buf, size_t len);
```

```
int fcvt_r(double number, int ndigits, int *decpt,
           int *sign, char *buf, size_t len);
```

```
int qecvt_r(long double number, int ndigits, int *decpt,
           int *sign, char *buf, size_t len);
```

```
int qfcvt_r(long double number, int ndigits, int *decpt,
           int *sign, char *buf, size_t len);
```

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

ecvt_r(), fcvt_r(), qecvt_r(), qfcvt_r():

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

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

## ОПИСАНИЕ
Функции ecvt_r(), fcvt_r(), qecvt_r() и qfcvt_r() идентичны функциям ecvt(3), fcvt(3), qecvt(3) и qfcvt(3), соответственно, за исключением того, что они не возвращают результаты в статическом буфере, а вместо этого используют указанный buf размером len. Смотрите ecvt(3) и qecvt(3).

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

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

Интерфейс

Атрибут

Значение

ecvt_r(), fcvt_r(), qecvt_r(), qfcvt_r()

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

MT-Safe

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

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

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


encrypt

title: encrypt(3)

summary: шифрование 64\-битных сообщений

text:
# encrypt(3)

## ИМЯ
encrypt, setkey, encrypt_r, setkey_r - шифрование 64-битных сообщений

## ОБЗОР

```
#define _XOPEN_SOURCE       /* См. feature_test_macros(7) */
#include <unistd.h>
```

```
void encrypt(char block[64], int edflag);
#define _XOPEN_SOURCE       /* смотрите feature_test_macros(7) */
#include <stdlib.h>
```

```
void setkey(const char *key);
#define _GNU_SOURCE         /* смотрите feature_test_macros(7) */
#include <crypt.h>
```

```
void setkey_r(const char *key, struct crypt_data *data);
void encrypt_r(char *block, int edflag, struct crypt_data *data);
```

Для любой функции требуется компоновка с параметром -lcrypt.

## ОПИСАНИЕ
Эти функции кодируют и декодируют 64-битные сообщения. Функцией setkey() задаётся ключ, который затем используется encrypt(). Параметр key является массивом из 64 байтов, каждый из которых имеет значение 1 или 0. Байты key[n], где n=8*i-1 — игнорируются, так что действительная длина ключа равна 56 битам.

Функция encrypt() изменяет переданный буфер и, если значение edflag равно 0, то кодирует его, а если равно 1 — то декодирует. Как и параметр key, аргумент block также является представлением битового вектора действительного кодируемого значения. Результат возвращается в этом же векторе.

Эти две функции не являются повторно используемыми, то есть данные ключа хранятся в статическом хранилище. Функции setkey_r() и encrypt_r() являются повторно используемыми версиями. Они используют следующую структуру для хранения данных ключа:

```
struct crypt_data {

    char     keysched[16 * 8];

    char     sb0[32768];

    char     sb1[32768];

    char     sb2[32768];

    char     sb3[32768];

    char     crypt_3_buf[14];

    char     current_salt[2];

    long int current_saltbits;

    int      direction;

    int      initialized;
};
```

Перед вызовом setkey_r() обнулите data->initialized.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Данные функции не возвращают никаких значений.

## ОШИБКИ
Установите переменную errno в ноль перед вызовом этих функций. При нормальном завершении работы её значение не изменится.

ENOSYS

Функция не предусмотрена (например, из-за старых запретов США на экспорт).

## ВЕРСИИ
Функции crypt(), crypt_r(), setkey() и setkey_r() удалены из glibc 2.28, так как они используют блочный шифр DES, который теперь считается небезопасным. В приложениях следует использовать современную библиотеку шифрования, например libgcrypt.

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

Интерфейс

Атрибут

Значение

encrypt(), setkey()

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

MT-Unsafe race:crypt

encrypt_r(), setkey_r()

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

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
encrypt(), setkey(): POSIX.1-2001, POSIX.1-2008, SUS, SVr4.

Функции encrypt_r() и setkey_r() являются расширениями GNU.

## ЗАМЕЧАНИЯ

### Доступность в glibc
Смотрите crypt(3).

### Свойства в glibc
В glibc 2.2 в данных функциях используется алгоритм DES.

## ПРИМЕР

```
#define _XOPEN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <crypt.h>
int
main(void)
{

    char key[64];

    char orig[9] = "eggplant";

    char buf[64];

    char txt[9];

    int i, j;

    for (i = 0; i < 64; i++) {

        key[i] = rand() & 1;

    }

    for (i = 0; i < 8; i++) {

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

            buf[i * 8 + j] = orig[i] >> j & 1;

        }

        setkey(key);

    }

    printf("До шифрования: %s\n", orig);

    encrypt(buf, 0);

    for (i = 0; i < 8; i++) {

        for (j = 0, txt[i] = '\0'; j < 8; j++) {

            txt[i] |= buf[i * 8 + j] << j;

        }

        txt[8] = '\0';

    }

    printf("После шифрования:  %s\n", txt);

    encrypt(buf, 1);

    for (i = 0; i < 8; i++) {

        for (j = 0, txt[i] = '\0'; j < 8; j++) {

            txt[i] |= buf[i * 8 + j] << j;

        }

        txt[8] = '\0';

    }

    printf("После расшифровки:  %s\n", txt);

    exit(EXIT_SUCCESS);
}
```

## СМОТРИТЕ ТАКЖЕ
cbc_crypt(3), crypt(3), ecb_crypt(3),


end

title: end(3)

summary: конец программных сегментов

text:
# end(3)

## ИМЯ
etext, edata, end - конец программных сегментов

## ОБЗОР

```
extern etext;
extern edata;
extern end;
```

## ОПИСАНИЕ
Адреса этих символов соответствуют концам различных программных сегментов:

etext

Первый адрес за концом сегмента текста (кода программы).

edata

Первый адрес за концом сегмента инициализированных данных.

end

Первый адрес за концом сегмента неинициализированных данных (сегмента BSS).

## СООТВЕТСТВИЕ СТАНДАРТАМ
Хотя эти символы уже давно присутствуют в большинстве систем UNIX, они не стандартизованы. Используйте осторожно.

## ЗАМЕЧАНИЯ
Программа должна явно объявлять эти символы; они не определены в заголовочных файлах.

В некоторых системах имена этих символов начинаются с подчёркивания: _etext, _edata и _end. Эти символы также определены в программах, скомпонованных на Linux.

В начале выполнения программы, повреждение программы будет где-нибудь рядом c &end (возможно, в начале следующей страницы). Однако, поломка изменяет память как при выделении с помощью brk(2) или malloc(3). Используйте sbrk(2) с аргументом 0 для поиска текущего значения поломки программы.

## ПРИМЕР
Нижеследующая программа выдает такие результаты:

```
$ ./a.out
First address past:

    program text (etext)       0x8048568

    initialized data (edata)   0x804a01c

    uninitialized data (end)   0x804a024
```

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

```
#include <stdio.h>
#include <stdlib.h>
extern char etext, edata, end; /* Символы должны иметь какой-то тип,

                                   иначе предупреждения от «gcc -Wall» */
int
main(int argc, char *argv[])
{

    printf("First address past:\n");

    printf("    program text (etext)      %10p\n", &etext);

    printf("    initialized data (edata)  %10p\n", &edata);

    printf("    uninitialized data (end)  %10p\n", &end);

    exit(EXIT_SUCCESS);
}
```

## СМОТРИТЕ ТАКЖЕ
objdump(1), readelf(1), sbrk(2), elf(5)


endian

title: endian(3)

summary: изменяет порядок байт у целого числа

text:
# endian(3)

## ИМЯ
htobe16, htole16, be16toh, le16toh, htobe32, htole32, be32toh, le32toh, htobe64, htole64, be64toh, le64toh - изменяет порядок байт у целого числа

## ОБЗОР

```
#include <endian.h>
```

```
uint16_t htobe16(uint16_t host_16bits);
uint16_t htole16(uint16_t host_16bits);
uint16_t be16toh(uint16_t big_endian_16bits);
uint16_t le16toh(uint16_t little_endian_16bits);
```

```
uint32_t htobe32(uint32_t host_32bits);
uint32_t htole32(uint32_t host_32bits);
uint32_t be32toh(uint32_t big_endian_32bits);
uint32_t le32toh(uint32_t little_endian_32bits);
```

```
uint64_t htobe64(uint64_t host_64bits);
uint64_t htole64(uint64_t host_64bits);
uint64_t be64toh(uint64_t big_endian_64bits);
uint64_t le64toh(uint64_t little_endian_64bits);
```

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

htobe16(), htole16(), be16toh(), le16toh(), htobe32(), htole32(), be32toh(), le32toh(), htobe64(), htole64(), be64toh(), le64toh():

```
    начиная с glibc 2.19:

        _DEFAULT_SOURCE

    в glibc до версии 2.19 включительно:

        _BSD_SOURCE
```

## ОПИСАНИЕ
Эти функции преобразуют кодирование байт целых значений из/в порядок байт, используемом в работающем ЦП («порядок байт узла»), от младшего к старшему (little-endian) и от старшего к младшему (big-endian).

Число nn в имени каждой функции показывает размер целого, с которым работает функция — может быть 16, 32 или 64 бита.

Функции с именами вида «htobenn» преобразуют число с порядком байт узла в число с порядком байт от старшего к младшему.

Функции с именами вида «htolenn» преобразуют число с порядком байт узла в число с порядком байт от младшего к старшему.

Функции с именами вида «benntoh» преобразуют число с порядком байт от старшего к младшему в число с порядком байт узла.

Функции с именами вида «lenntoh» преобразуют число с порядком байт от младшего к старшему в число с порядком байт узла.

## ВЕРСИИ
Эти функции добавлены в glibc версии 2.9.

## СООТВЕТСТВИЕ СТАНДАРТАМ
Это нестандартные функции. Подобные функции есть в BSD, где вместо <endian.h> для них требуется заголовочный файл <sys/endian.h>. К сожалению, NetBSD, FreeBSD и glibc не следуют изначальному соглашению об именах функций в OpenBSD, где часть nn всегда находится в конце имени функции (то есть, например, в NetBSD, FreeBSD и glibc используется «be32toh» вместо эквивалентной «betoh32» из OpenBSD).

## ЗАМЕЧАНИЯ
Данные функции похожи на функции старого семейства byteorder(3). Например, be32toh() идентична ntohl().

Преимущество функций byteorder(3) в том, что они являются стандартными и доступны во всех системах UNIX. С другой стороны, тот факт, что они разрабатывались для использования в контексте TCP/IP означает, что среди них нет функций для 64-битных значений и чисел с порядком байт от младшего к старшему, описанных в этой странице.

## ПРИМЕР
Ниже представлена программа, которая выводит результаты преобразования целого с порядком байт узла в целое с порядком байт от младшего к старшему и от старшего к младшему. Так как порядок байт узла будет эквивалентен порядку от младшего к старшему или от старшего к младшему, то реально выполняется только одно преобразование. Если эта программа запускается на системе с порядком байт от младшего к старшему, например x86-32, то мы увидим следующее:

```
$ ./a.out
x.u32 = 0x44332211
htole32(x.u32) = 0x44332211
htobe32(x.u32) = 0x11223344
```

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

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

    union {

        uint32_t u32;

        uint8_t arr[4];

    } x;

    x.arr[0] = 0x11;	/* низший адресуемый байт */

    x.arr[1] = 0x22;

    x.arr[2] = 0x33;

    x.arr[3] = 0x44;	/* высший адресуемый байт */

    printf("x.u32 = 0x%x\n", x.u32);

    printf("htole32(x.u32) = 0x%x\n", htole32(x.u32));

    printf("htobe32(x.u32) = 0x%x\n", htobe32(x.u32));

    exit(EXIT_SUCCESS);
}
```

## СМОТРИТЕ ТАКЖЕ
bswap(3), byteorder(3)


title: envz_add(3)

text:
# envz_add(3)

## ИМЯ
envz_add, envz_entry, envz_get, envz_merge, envz_remove, envz_strip - поддержка строк окружения

## ОБЗОР

```
#include <envz.h>
```

```
error_t envz_add(char **envz, size_t *envz_len,
                 const char *name, const char *value);
```

```
char *envz_entry(const char *envz, size_t envz_len, const char *name);
```

```
char *envz_get(const char *envz, size_t envz_len, const char *name);
```

```
error_t envz_merge(char **envz, size_t *envz_len,
                   const char *envz2, size_t envz2_len, int override);
```

```
void envz_remove(char **envz, size_t *envz_len, const char *name);
```

```
void envz_strip(char **envz, size_t *envz_len);
```

## ОПИСАНИЕ
Эти функции есть только в glibc.

Вектор argz представляет собой указатель на символьный буфер и его длину (смотрите argz_add(3)). Вектор envz является особым вектором argz, в нём содержатся строки вида «имя=значение». Всё, что расположено за первым '=', считается значением. Если '=' отсутствует, то значение считается равным NULL (если '=' указано в конце, то значение равно пустой строке "").

Эти функции предназначены для работы с векторами envz.

Функция envz_add() добавляет строку "name=value" (если name не равно NULL) или "name" (если value равно NULL) в вектор envz (*envz, *envz_len) и обновляет *envz и *envz_len. Если запись с таким значением name уже существует, то она удаляется.

Функция envz_entry() ищет значение name в векторе envz (envz, envz_len) и возвращает запись, если такое имя найдено, и NULL, если не найдено.

Функция envz_get() ищет значение name в векторе envz (envz, envz_len) и возвращает значение, если такое имя найдено, и NULL, если не найдено (заметим, что значение само по себе может быть равно NULL, особенно, если есть запись для name без знака '=').

Функция envz_merge() добавляет все записи из envz2 в *envz, как если бы это делалось с помощью envz_add(). Если значение override истинно, то значения в envz2 будут заменять значения с такими же именами в *envz, иначе — нет.

Функция envz_remove() удаляет запись для name из (*envz, *envz_len), если она есть.

Функция envz_strip() удаляет все записи со значением NULL.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Все функции envz, в которых происходит выделение памяти, возвращают результат, имеющий тип error_t: 0 — при успешном выполнении и ENOMEM — при ошибке выделения памяти.

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

Интерфейс

Атрибут

Значение

envz_add(), envz_entry(), envz_get(), envz_merge(), envz_remove(), envz_strip()

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

MT-Safe

## СООТВЕТСТВИЕ СТАНДАРТАМ
Данные функции являются расширениями GNU. Используйте с осторожностью.

## ПРИМЕР

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

    int i, e_len = 0;

    char *str;

    for (i = 0; envp[i] != NULL; i++)

        e_len += strlen(envp[i]) + 1;

    str = envz_entry(*envp, e_len, "HOME");

    printf("%s\n", str);

    str = envz_get(*envp, e_len, "HOME");

    printf("%s\n", str);

    exit(EXIT_SUCCESS);
}
```

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


erf

title: erf(3)

summary: функция ошибки

text:
# erf(3)

## ИМЯ
erf, erff, erfl - функция ошибки

## ОБЗОР

```
#include <math.h>
```

```
double erf(double x);
float erff(float x);
long double erfl(long double x);
```

```

```

Компонуется при указании параметра -lm.

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

erf():

_ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE

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

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

erff(), erfl(): _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L

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

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

## ОПИСАНИЕ
Эти функции возвращают функцию ошибки от x, определённую как

erf(x) = 2/sqrt(pi)* интеграл от 0 до x по exp(-t*t) dt

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

Если x имеет значение NaN, будет возвращено NaN.

Если x равно +0 (-0), будет возвращено +0 (-0).

Если x стремится к плюс или минус бесконечности, то будет возвращено +1 или -1.

Если значение x субнормально, то генерируется ошибка диапазона и возвращается значение 2*x/sqrt(pi).

## ОШИБКИ
Смотрите math_error(7), чтобы определить, какие ошибки могут возникать при вызове этих функций.

Могут возникать следующие ошибки:

Ошибка диапазона: результат исчерпал степень(число x субнормально)

Возникает исключение исчерпания степени чисел с плавающей запятой (FE_UNDERFLOW).

Эти функции не изменяют errno.

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

Интерфейс

Атрибут

Значение

erf(), erff(), erfl()

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

MT-Safe

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

Вариант, возвращающий значение типа double, также соответствует SVr4, 4.3BSD.

## СМОТРИТЕ ТАКЖЕ
cerf(3), erfc(3), exp(3)


erfc

title: erfc(3)

summary: дополнительная функция ошибки

text:
# erfc(3)

## ИМЯ
erfc, erfcf, erfcl - дополнительная функция ошибки

## ОБЗОР

```
#include <math.h>
```

```
double erfc(double x);
float erfcf(float x);
long double erfcl(long double x);
```

Компонуется при указании параметра -lm.

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

erfc():

_ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE

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

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

erfcf(), erfcl(): _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L

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

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

## ОПИСАНИЕ
Эти функции возвращают дополнительную функцию ошибки от x, то есть 1.0 - erf(x).

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

Если x имеет значение NaN, будет возвращено NaN.

Если x равен +0 или -0, возвращается -1.

Если x стремится к плюс бесконечности, то будет возвращено +0.

Если x равно минус бесконечности, возвращается +2.

Если результат функции исчерпал степень, что грозит созданием непредставимого числа, то возвращается значение 0.0.

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

## ОШИБКИ
Смотрите math_error(7), чтобы определить, какие ошибки могут возникать при вызове этих функций.

Могут возникать следующие ошибки:

Ошибка диапазона: результат исчерпал степень(результат субнормален)

Возникает исключение исчерпания степени чисел с плавающей запятой (FE_UNDERFLOW).

Эти функции не изменяют errno.

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

Интерфейс

Атрибут

Значение

erfc(), erfcf(), erfcl()

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

MT-Safe

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

Вариант, возвращающий значение типа double, также соответствует SVr4, 4.3BSD.

## ЗАМЕЧАНИЯ
Функции erfc(), erfcf() и erfcl() созданы с целью избежания потери точности, которая возникает при вычислении 1-erf(x) для больших значений x (для которых значение erf(x) стремится к 1).

## СМОТРИТЕ ТАКЖЕ
cerf(3), erf(3), exp(3)


err

title: err(3)

summary: форматирует сообщения

text:
# err(3)

## ИМЯ
err, verr, errx, verrx, warn, vwarn, warnx, vwarnx - форматирует сообщения об ошибках

## ОБЗОР

```
#include <err.h>
```

```
void err(int eval, const char *fmt, ...);
```

```
void errx(int eval, const char *fmt, ...);
```

```
void warn(const char *fmt, ...);
```

```
void warnx(const char *fmt, ...);
#include <stdarg.h>
```

```
void verr(int eval, const char *fmt, va_list args);
```

```
void verrx(int eval, const char *fmt, va_list args);
```

```
void vwarn(const char *fmt, va_list args);
```

```
void vwarnx(const char *fmt, va_list args);
```

## ОПИСАНИЕ
Семейства функций err() и warn() выводят форматированное сообщение об ошибке в стандартный поток ошибок. При выводе всегда показывается последний компонент имени программы, двоеточие и пробел. Если значение fmt не равно NULL, то выводится сообщение об ошибке, отформатированное согласно printf(3). Вывод завершается символом новой строки.

Функции err(), verr(), warn() и vwarn() добавляют сообщение об ошибке, полученное от strerror(3) для значения глобальной переменной errno, начиная его с двоеточия и пробела, если значение fmt равно NULL.

Функции errx() и warnx() не добавляют сообщение об ошибке.

Функции err(), verr(), errx() и verrx() не возвращают управление в программу, а завершают её с кодом выхода, равным значению eval.

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

Интерфейс

Атрибут

Значение

err(), errx(), warn(), warnx(), verr(), verrx(), vwarn(), vwarnx()

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

MT-Safe locale

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

## ПРИМЕР
Показать строку с информацией о текущем errno и закончить работу:

```
p = malloc(size);
if (p == NULL)

    err(1, NULL);
fd = open(file_name, O_RDONLY, 0);
if (fd == -1)

    err(1, "%s", file_name);
```

Показать сообщение об ошибке и закончить работу:

```
if (tm.tm_hour < START_TIME)

    errx(1, "слишком рано, ждём до %s", start_time_string);
```

Предупреждение об ошибке:

```
fd = open(raw_device, O_RDONLY, 0);
if (fd == -1)

    warnx("%s: %s: пробуем блочное устройство",

            raw_device, strerror(errno));
fd = open(block_device, O_RDONLY, 0);
if (fd == -1)

    err(1, "%s", block_device);
```

## СМОТРИТЕ ТАКЖЕ
error(3), exit(3), perror(3), printf(3), strerror(3)