Чтение онлайн

ЖАНРЫ

Разработка приложений в среде Linux. Второе издание

Троан Эрик В.

Шрифт:

Знание этих макросов необходимо, так как набор макросов, определенных по умолчанию, не обеспечивает полную функциональность

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

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

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

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

Макросы определяются в системном заголовочном файле

feature.h
, который не должен включаться непосредственно. Взамен его
включают все другие заголовочные файлы, которые зависят от содержимого
feature.h
.

Набор макросов по умолчанию содержит

_SVID_SOURCE=1
,
_BSD_SOURCE=1
,
_POSIX_SOURCE=1
и
_POSIX_C_SOURCE=199506L
. Описание каждой из этих опций можно найти ниже, но все это, по сути, транслируется в поддержку возможностей стандарта 1995 POSIX (этот стандарт использовался до объединения стандартов POSIX и Single Unix), всех стандартных функций System V и всех функций BSD, которые не конфликтуют с функциями System V. Данного набора макросов достаточно для большинства программ.

При определении в

gcc
опции
– ansi
, как было описано ранее, автоматически определяется внутренний макрос
__STRICT_ANSI__
, который отключает все макросы, определенные по умолчанию.

За исключением

__STRICT_ANSI__
, который представляет собой специальный макрос (и должен настраиваться только компилятором в контексте опции командной строки
– ansi
), эти макросы имеют накопительный характер, то есть можно определять любые их комбинации. Точное определение изменений
_BSD_SOURCE
зависит от настройки других макросов (более детально об этом — ниже); все
остальные
макросы — исключительно накопительные.

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

glibc
.

_POSIX_SOURCE
Если указан этот макрос, становятся доступными все интерфейсы, определенные как часть оригинальной спецификации POSIX.1. Данный макрос был определен в первоначальном стандарте POSIX.1-1990.
_POSIX_C_SOURCE
Этот макрос может заменять
_POSIX_SOURCE
. Если установлен в 1, то эквивалентен
_POSIX_SOURCE
. Если его значение больше либо равно 2, макрос включает интерфейсы С, соответствующие POSIX.2, и задействует регулярные выражения. Если значение больше либо равно 199309L, макрос включает в себя дополнительные интерфейсы С, соответствующие пересмотренному в 1993 году стандарту POSIX, в частности, включая функциональность реального времени. Если его значение больше либо равно 199506L (по умолчанию), макрос включает дополнительные интерфейсы С, соответствующие пересмотренному в 1995 году стандарту POSIX, в частности, включая потоки POSIX. Этот макрос был описан версией POSIX, выпущенной после 1990 года для разграничения поддержки различных версий стандартов POSIX (а теперь также и Single Unix). Во многих случаях полностью замещается
_XOPEN_SOURCE
.
_XOPEN_SOURCE
Макрос
_XOPEN_SOURCE
определен XSI-частью стандарта Single Unix и описывает логическое надмножество интерфейсов, включенных с помощью
_POSIX_C_SOURCE
. Этот макрос также был определен XPG. Если макрос определен, указываются функциональные возможности из начального стандарта XPG4 (Unix95). Если макрос определен со значением
500
, включаются функциональные возможности из стандарта XPG5 (Unix98, SuS версии 2). Если установлено значение
600
, включаются функциональные возможности из начального стандарта IEEE Std 1003.1-2003 (комбинированный документ по POSIX и SuS).
_ISOC99_SOURCE
Этот макрос проверки возможностей экспортирует интерфейсы, определенные в новых стандартах ISO/IEC С99.
_SVID_SOURCE
При указании данного макроса для выбора возможностей становится доступным стандарт SVID (System V Interface Definition). Это не значит, что
glibc
обеспечивает полную реализацию стандарта SVID; она всего лишь открывает указанную функциональность SVID, существующую в
glibc
.
_BSD_SOURCE
Функции BSD могут конфликтовать с другими функциями, и эти конфликты всегда разрешаются в пользу поведения, соответствующего стандарту System V, или, если определен или подразумевается любой макрос функций POSIX, X/Open или System V, единственным макросом, который включает поведение BSD является
_ISOC99_SOURCE
. (Точное определение этого макроса временами изменялось и может меняться в дальнейшем, поскольку он не регламентируется каким-либо стандартом.)
_GNU_SOURCE
В случаях конфликта
_GNU_SOURCE
включает все, что возможно, отдавая предпочтение интерфейсам System V, а не BSD. Этот макрос также добавляет некоторые специальные для GNU и Linux интерфейсы, например, владение файлами.

Когда стандартного набора макросов недостаточно, обычно определяют макрос

_GNU_SOURCE
(включает все — самое простое решение),
_XOPEN_SOURCE=600
(наиболее вероятно, что пригодится поднабор
_GNU_SOURCE
) или
_ISOC99_SOURCE
(использование функций наиболее позднего стандарта С, поднабор
_XOPEN_SOURCE=600
).

6.2. Интерфейсы POSIX

6.2.1. Обязательные типы POSIX

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

<sys/types.h>
, которые используются для многих аргументов и возвращаемых значений. Эти определения типов важны, потому что стандартные типы языка С могут быть разными на различных машинах, так как они нестрого определены в стандарте С. Из-за такого нестрогого определения язык С полезен на широком диапазоне оборудования — размер слов на 16-разрядных машинах отличается от такового на 64-разрядных машинах, а язык программирования низкого уровня не должен скрывать эту разницу — но для POSIX требуется большая гарантия. От заголовочного файла библиотеки С
<sys/types.h>
требуется определение набора соответствующих типов для каждой машины, которая поддерживает POSIX. Каждый из этих определений
типов можно легко отличить от собственного типа С, поскольку он заканчивается на
_t
.

Ниже описано подмножество, используемое для интерфейсов.

dev_t
Арифметический тип данных, содержащий старшие (major) и младшие (minor) числа, соответствующие специальным файлам устройств, обычно расположенным в подкаталоге
/dev
. В Linux
dev_t
можно манипулировать с помощью макросов
major
,
minor
и
makedev
, которые определены в
<sys/sysmacros.h>
. Обычно
dev_t
используется только в системном программировании, описанном в главе 11.
uid_t
,
gid_t
Целочисленные типы, содержащие уникальные идентификаторы, соответственно, пользователя и группы. Удостоверения идентификаторов пользователя и группы рассматриваются в главе 10.
pid_t
Целочисленный тип, обеспечивающий уникальное значение для системного процесса (описан в главе 10).
id_t
Целочисленный тип, способный хранить без усечения любой тип
pid_t
,
uid_t
или
gid_t
.
off_t
Целочисленный тип со знаком для измерения размера файла в байтах.
size_t
Целочисленный тип без знака для измерения размеров объектов в памяти, например, символьных строк, массивов или буферов.
ssize_t
Целочисленный тип со знаком для подсчета байтов (положительные значения) или хранения кода возврата ошибки (отрицательные значения).
time_t
Целочисленный тип (во всех обычных системах) или тип с плавающей точкой (позволяет рассматривать VMS как операционную систему POSIX), выдающий время в секундах, как описано в главе 18.

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

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

6.2.2. Раскрытие возможностей времени выполнения

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

Функция

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

#include <unistd.h>

long sysconf (int);

Целочисленный аргумент в

sysconf
— это один из наборов макросов с префиксом
_SC_
. Ниже перечислены макросы, которые используются чаще всего.

_SC_CLK_TCK
Возвращает количество тактов в секунду внутренних часов ядра, различаемое программами. Следует отметить, что ядро может содержать одни или больше часов, работающих на более высокой частоте.
_SC_CLK_TCK
обеспечивает подсчет тактов, которые используются для получения информации из ядра, и этот макрос не является индикатором времени ожидания системы.
_SC_STREAM_MAX
Возвращает максимальное количество стандартных потоков ввода-вывода С, которые могут быть одновременно открыты в системе.
_SC_ARG_MAX
Возвращает максимальную длину аргумента командной строки и переменных окружения в байтах, которые используются любой из функций
exec
. Если это ограничение превышено,
exec
вернет ошибку
Е2ВIG
.
_SC_OPEN_MAX
Возвращает максимальное количество файлов, которые одновременно могут быть открыты процессом; это то же самое, что и программное ограничение
RLIMIT_NOFILE
, которое может быть запрошено функцией
getrlimit
и установлено функцией
setrlimit
. Это единственное значение
sysconf
, которое может изменяться во время выполнения программы; при вызове
setrlimit
для изменения ограничения
RLIMIT_NOFILE
.
_SC_OPEN_MAX
также подчиняется новому программному ограничению.
_SC_PAGESIZE
или
_SC_PAGE_SIZE
Возвращает размер одной страницы в байтах. В системах, которые могут поддерживать разные размеры страниц, возвращается размер одной обычной страницы, для которой выделено определенное количество памяти и которая считается естественным размером страниц для конкретной системы.
_SC_LINE_MAX
Возвращает максимальную длину в байтах входной строки, обрабатываемой текстовыми утилитами, включая завершающий символ новой строки. Следует отметить, что во многих утилитах GNU, используемых в Linux-системах, фактически нет жестко закодированной максимальной длины строки, потому могут применяться входные строки произвольной длины. Однако переносимая программа не должна вызывать текстовые утилиты для строк, длина которых превышает
_SC_LINE_MAX
; во многих Unix-системах утилиты работают с фиксированным максимальным размером строки, и его превышение может привести к неопределенным результатам.
_SC_NGROUPS_MAX
Возвращает количество дополнительных групп (см. главу 10), которые может иметь процесс.
Поделиться с друзьями: