UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
if (write( ... ) != nbytes)
fprintf(stderr, "write error, errno = %dn", errno);
errno = errno_save; /* восстанавливаем значение этой переменной
при завершении */
}
В этом коде мы также вызываем функцию
fprintf
Мы вернемся к проблеме повторного вхождения в главе 26 и увидим, как проблема с переменной
errno
11.19. Функции gethostbyname_r и gethostbyaddr_r
Чтобы превратить функцию, не допускающую повторное вхождение, такую как
gethostbyname
1. Вместо заполнения и возвращения статической структуры вызывающий процесс размещает структуру в памяти, и функция, допускающая повторное вхождение, заполняет эту структуру. Эта технология используется для перехода от функции
gethostbyname
gethostbyname_r
hostent
hostent
hostent
h_errno
h_errno
errno
Эта технология также используется функциями
getnameinfo
inet_ntop
2. Входящая функция вызывает функцию
malloc
getaddrinfo
freeaddrinfo
Обсудим функции Solaris 2.x, допускающие повторное вхождение, не используемые для сопоставления имен с адресами, и наоборот (то есть для разрешения имен).
#include <netdb.h>
struct hostent *gethostbyname_r(const char *<i>hostname</i>,
struct hostent *<i>result</i>, char *<i>buf</i>, int <i>buflen</i>, int *<i>h_errnop</i>);
struct hostent *gethostbyaddr_r(const char *<i>addr</i>, int <i>len</i>,
int <i>type</i>, struct hostent *<i>result</i>, char *<i>buf</i>, int <i>buflen</i>,
int *<i>h_errnop</i>);
<i>Обе функции возвращают: непустой указатель в случае успешного выполнения, NULL в случае ошибки</i>
Для каждой функции требуется четыре дополнительных аргумента. Аргумент
result
hostent
Аргумент
buf
buflen
hostent
result
gethostbyname
Если происходит ошибка, код ошибки возвращается через указатель
h_errnop
h_errno
К сожалению, проблема повторного вхождения гораздо серьезнее, чем может показаться. Во-первых, не существует стандарта относительно повторного вхождения и функций gethostbyname и gethostbyaddr. POSIX утверждает, что эти две функции не обязаны быть безопасными в многопоточной среде.
Во-вторых, не существует стандарта для функций _r. В этом разделе (в качестве примера) мы привели две функции _r, предоставляемые Solaris 2.x. В Linux присутствуют аналогичные функции, возвращающие hostent в качестве аргумента типа значение-результат. В Digital Unix и HP-UX имеются версии этих функций с другими аргументами. Первые два аргумента функции gethostbyname_r такие же, как и в версии Solaris, но оставшиеся три аргумента версии Solaris объединены в новую структуру hostent_data (которая должна быть размещена в памяти вызывающим процессом), а указатель на эту структуру — это третий и последний аргумент. Обычные функции gethostbyname и gethostbyaddr в Digital Unix 4.0 и в HP-UX 10.30 допускают повторное вхождение при использовании собственных данных потоков (см. раздел 23.5). Интересный рассказ о разработке функций _r Solaris 2.x содержится в [70].
Наконец, хотя версия функции gethostbyname, допускающая повторное вхождение, может обеспечить безопасность, когда ее одновременно вызывают несколько различных потоков, это ничего не говорит нам о возможности повторного вхождения для лежащих в ее основе функций распознавателя.