87
В будущем это может измениться, поскольку в ядре реализуются мелкомодульные системные полномочия.
88
Файл /etc/passwd обновляется только процессами, создающими новую копию файла с модификациями и затем заменяющими оригинал с помощью системного вызова rename(). Поскольку такая последовательность является атомарной, процессы могут считывать из etc/passwd в любое время.
89
Файловая система Andrew Filesystem (AFS), доступная в Linux, но не включенная в стандартное ядро, поддерживает O_EXCL во всей сети.
90
Эта ситуация более сложна для потоков. Многие ядра и библиотеки Linux рассматривают потоки как разные процессы, что увеличивает потенциал возникновения конфликтов файловых блокировок между потоками (а это не совместимо со стандартной моделью потоков POSIX). Linux предлагает более традиционную модель потоков, при которой файловые блокировки разделяются между всеми потоками одного процесса, но в многопоточных программах лучше применять потоковые механизмы блокировки POSIX, а не полагаться на поведение файловых блокировок.
91
Эта манипуляция блокировками происходит атомарно — не имеет значения, какая часть области разблокирована.
92
Эффект, производимый вызовами fork() и exec() на файловые блокировки, является наиболее существенным отличием между файловой блокировкой POSIX (а, следовательно, и блокировкой lockf()) и файловой блокировкой flock() в BSD.
93
Одним из самых частых пользователей аренды файлов является файловый сервер Samba, позволяющий клиентам кэшировать свои записи для увеличения производительности.
94
Если тот факт, что аренда записи уведомляет процесс об открытии файла для чтения, может показаться несколько странным, посмотрите на него с точки зрения процесса, получающего аренду. Ему необходимо знать, делает ли другой процесс читать файл, только в случае, когда основной процесс сам что-либо записывает в этот файл.
95
Ядра предшествующих версий при успешной операции возвращает ноль либо единицу, тогда как более новые ядра всегда возвращают в данном случае ноль. В другом случае проверка на положительное или отрицательное значение работает нормально.
96
Если один сигнал используется для аренды множества файлов, убедитесь, что сигнал является сигналом реального времени, так что множество событий аренды ставятся в очередь. Если используется обычный сигнал, он может потеряться либо события аренды могут возникать через очень короткие промежутки времени.
97
До тех пор пока O_NONBLOCK не будет определен как флаг open(); в этом случае возвращается EWOULDBLOCK.
98
Они так именуются, поскольку чтение разбрасывает данные по всей памяти, а запись собирает данные из разных областей памяти. Они также известны как векторное чтение и запись. Этим объясняется наличие "v" в конце readv() и writev().
99
Эта эмулированная версия в большинстве случаев ведет себя корректно, но действует не так, как фактический системный вызов, если сигналы принимаются во время его выполнения.
100
Это верно; PATH_MAX не является фактическим пределом. POSIX считает его неопределенным, что обычно является эквивалентом "не используйте его".
101
Имя этого пути эквивалентно более простому /usr/bin/less.
102
Функции ftw() необходимо выполнять stat() для каждого файла для выяснения, является ли он каталогом, и передача этой информации обратному вызову во многих случаях избавляет последний от необходимости повторного выполнения stat() для файлов.
103
Это то же, что и метод, используемый для владения файлами (глава 13).
104
Обработчик сигналов все еще следует регистрировать с помощью флага SA_SIGINFO, чтобы файловый дескриптор надлежащим образом получил доступ к сигналу.
105
Остановленные процессы, однако, не могут генерировать сигналы, поэтому они также не могут перезапускаться.
106
Обычно клавиатурной комбинацией приостановки является <Ctrl+Z>. Программа stty позволяет пользователям менять эту комбинацию. Подробнее это рассматривается в главе 16.
107
То есть устройства, используемые как для ввода, так и для вывода.
108
Реализации Unix старого типа предоставляли эту функцию с помощью TIOCSPGRP ioctl(), до сих пор поддерживаемого Linux. Для сравнения, tcsetpgrp() можно реализовать как ioctl(ttyfd, TIOCSPGRP, &pgrp).
109
Более подробно о сигналах и их взаимодействии с управлением заданиями рассказывается в главе 12.
110
На man-странице setserial описан способ обхода этого ограничения, специфический для Linux.
111
Обратите внимание: "бит в секунду" ("бит/с"), а не "бод". Бит в секунду определяет интенсивность передачи информации. Бод является техническим термином, описывающим смены фаз в течение секунды. Бод не соответствует termios, но слово бод, к сожалению, попало в названия некоторых флагов termios, не рассматриваемых в этой книге.
112
Например, приложения настройки сетевых протоколов, передающие информацию с помощью устройств tty.
113
B134 в действительности равняется 134,5 бит/с, скорость, используемая устаревшим терминалом IBM.
114
Linux также использует c_cflag для хранения скорости, но не стоит на это полагаться. Вместо этого применяйте cfsetospeed() и cfstispeed().
115
Ядра 2.6.x, рассматриваемые в настоящей книге, поддерживают как версию 4, так и версию 6 (на последнюю обычно ссылаются как на IPv6 из набора TCP/IP).
116
Кстати, именно так работают сети на основе коммутации пакетов. Альтернативная конструкция, сети с коммутацией каналов, более похожа на телефонные соединения. Однако они не часто используются при организации компьютерных сетей.
117
Вот почему криптография приобрела такую значимость с тех пор как появилась всемирная сеть Internet.
118
Многие высокоуровневые протоколы, такие как BOOTP и NFS, построены на основе UDP.
119
Допустимы еще несколько значений данного параметра, однако они редко применяются в коде приложений.
120
Системный вызов connect() может также быть неблокируемым, что позволит пользователям гораздо быстрее открывать несколько TCP соединений (он позволяет продолжать работу программы, в то время как выполняется процесс синхронизации TCP). Подробности по этой теме можно найти в [33].
121
Различные формы select() помечают сокет как открытый для чтения, тогда как accept() не может блокировать его, даже если сокет не помечен как неблокируемый. Для обеспечения максимальной переносимости функцию select() необходимо применять только для принятия соглашений с неблокируемыми сокетами, хотя в системе Linux это фактически не нужно. Причины этого подробно рассматриваются в [33].
122
Варианты BSD не поддерживают такую модель поведения, в таких системах ошибки проходят без отчетов.
123
И для bind(), и для connect() процесс должен иметь права на выполнение для каталогов, через которые проходит поиск путевого имени (почти как при открытии стандартных файлов).
124
Исходя из условий реального мира, большинство серверных программ должны быть параллельными. Однако многие из них фактически созданы как итерационные сервера. Например, Web-серверы, в основном, обрабатывают только одно соединение за раз через данный процесс. Для того чтобы разрешить соединение нескольким клиентам, сервер организован в виде множества отдельных процессов. Это делает создание Web-сервера более простым. Если ошибка прерывает работу одного из таких процессов, она затрагивает только одно клиентское соединение.
125