Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ для Linux. ΠŸΡ€ΠΎΡ„Π΅ΡΡΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 56

Автор ΠœΠ°Ρ€ΠΊ ΠœΠΈΡ‚Ρ‡Π΅Π»Π»

  return ptr;

}


char* xstrdup(const char* s) {

 char* copy = strdup(s);

 /* АварийноС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅, Ссли Π²Ρ‹Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΏΠ°ΠΌΡΡ‚ΡŒ Π½Π΅ ΡƒΠ΄Π°Π»ΠΎΡΡŒ. */

 if (сору == NULL)

  abort();

 else

  return copy;

}


void system_error(const char* operation) {

 /* Π’Ρ‹Π²ΠΎΠ΄ сообщСния ΠΎΠ± ошибкС Π½Π° основании значСния

    ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ errno. */

 error(operation, strerror(errno));

}


void error(const char* cause, const char* message) {

 /* Π—Π°ΠΏΠΈΡΡŒ сообщСния ΠΎΠ± ошибкС Π² ΠΏΠΎΡ‚ΠΎΠΊ stderr. */

 fprintf(stderr, "%s: error: (%s) %s\n", program_name,

  cause, message);

 /* Π—Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ */

 exit(1);

}


char* get_self_executable_directory() {

 int rval;

 char link_target[1024];

 char* last_slash;

 size_t result_length;

 char* result;


/* Π§Ρ‚Π΅Π½ΠΈΠ΅ содСрТимого символичСской ссылки /proc/self/exe. */

 rval =

  readlink("/proc/self/exe", link_target,

 sizeof(link_target));

 if (rval == -1)

 /* Ѐункция readlink() Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ»Π°ΡΡŒ Π½Π΅ΡƒΠ΄Π°Ρ‡Π΅ΠΉ, поэтому Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ

    ΠΈΠ· ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. */

 abort();

 else

  /* Π—Π°ΠΏΠΈΡΡŒ Π½ΡƒΠ»Π΅Π²ΠΎΠ³ΠΎ символа Π² ΠΊΠΎΠ½Π΅Ρ† строки. */

  link_target[rval] = '\0';

 /* Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ ΠΈΠΌΠ΅Π½ΠΈ Ρ„Π°ΠΉΠ»Π°,

    Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ имя ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°. */

 last_slash = strrchr(link_target, '/');

 if (last_slash == NULL || last_slash == link_target)

 /* Π€ΠΎΡ€ΠΌΠ°Ρ‚ ΠΈΠΌΠ΅Π½ΠΈ Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π΅Π½. */

 abort();

 /* Π’Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π±ΡƒΡ„Π΅Ρ€Π° для Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΉ строки. */

 result_length = last_slash - link_target;

 result = (char*)xmalloc(result_length + 1);

 /* ΠšΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°. */

 strncpy(result, link_target, result_length);

 result[result_length] = '\0';

 return result;

}

ΠŸΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹Π΅ здСсь Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² самых Ρ€Π°Π·Π½Ρ‹Ρ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°Ρ….

β–  Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ xmalloc(), xrealloc() ΠΈ xstrdup() ΡΠ²Π»ΡΡŽΡ‚ΡΡ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½Π½Ρ‹ΠΌΠΈ вСрсиями стандартных Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ malloc(), realloc() ΠΈ strdup(), Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ ΠΊΠΎΠ΄ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ошибок. Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ стандартных Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ пустой ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π² случаС ошибки, наши Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, Ссли Π² систСмС нСдостаточно памяти.

Π Π°Π½Π½Π΅Π΅ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ Π½Π΅Ρ…Π²Π°Ρ‚ΠΊΠΈ памяти β€” Ρ…ΠΎΡ€ΠΎΡˆΠ°Ρ идСя. Если этого Π½Π΅ Π΄Π΅Π»Π°Ρ‚ΡŒ, пустыС ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠΎΡΠ²Π»ΡΡ‚ΡŒΡΡ Π² самых Π½Π΅ΠΎΠΆΠΈΠ΄Π°Π½Π½Ρ‹Ρ… мСстах ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Π‘ΠΈΡ‚ΡƒΠ°Ρ†ΠΈΠΈ, связанныС с Π½Π΅Ρ…Π²Π°Ρ‚ΠΊΠΎΠΉ памяти, нСпросто воспроизвСсти, поэтому ΠΈΡ… ΠΎΡ‚Π»Π°Π΄ΠΊΠ° Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°Ρ‚Ρ€ΡƒΠ΄Π½Π΅Π½Π°. Ошибки выдСлСния памяти ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΈΠΌΠ΅ΡŽΡ‚ катастрофичСскиС послСдствия для ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Π°Π²Π°Ρ€ΠΈΠΉΠ½ΠΎΠ΅ Π΅Π΅ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ β€” Π²ΠΏΠΎΠ»Π½Π΅ ΠΏΡ€ΠΈΠ΅ΠΌΠ»Π΅ΠΌΡ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Ρ€Π΅Π°ΠΊΡ†ΠΈΠΈ.

β–  Π€ΡƒΠ½ΠΊΡ†ΠΈΡ error() сообщаСт ΠΎ Ρ„Π°Ρ‚Π°Π»ΡŒΠ½ΠΎΠΉ ошибкС, ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ΅Π΄ΡˆΠ΅ΠΉ Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅. ΠŸΡ€ΠΈ этом Π² ΠΏΠΎΡ‚ΠΎΠΊ stderr записываСтся сообщСниС ΠΎΠ± ошибкС, ΠΈ Ρ€Π°Π±ΠΎΡ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ. Для ошибок, ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ΅Π΄ΡˆΠΈΡ… Π² систСмных Π²Ρ‹Π·ΠΎΠ²Π°Ρ… ΠΈΠ»ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅Ρ‡Π½Ρ‹Ρ… функциях, ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π° функция system_error(), которая Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ сообщСниС ΠΎΠ± ошибкС Π½Π° основании значСния ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ errno (см. Ρ€Π°Π·Π΄Π΅Π» 2.2.3, "ΠšΠΎΠ΄Ρ‹ ошибок систСмных Π²Ρ‹Π·ΠΎΠ²ΠΎΠ²").

β–  Π€ΡƒΠ½ΠΊΡ†ΠΈΡ get_self_executable_directory() опрСдСляСт ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ содСрТится исполняСмый Ρ„Π°ΠΉΠ» Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ процСсса. Π­Ρ‚ΠΎ позволяСт ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ свои внСшниС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹. Ѐункция провСряСт содСрТимоС символичСской ссылки /proc/self/exe (см. Ρ€Π°Π·Π΄Π΅Ρ‚ 7.2.1, "Π€Π°ΠΉΠ» /proc/self).

Π’ Ρ„Π°ΠΉΠ»Π΅ common.c ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ Π΄Π²Π΅ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Π΅ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅.

β–  ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ program_name содСрТит имя выполняСмой ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ΅ Π² спискС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки (см. Ρ€Π°Π·Π΄Π΅Π» 2.1.1, "Бписок Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ²").

β–  ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ verbose Π½Π΅ Ρ€Π°Π²Π½Π° Π½ΡƒΠ»ΡŽ, Ссли ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ Π²Ρ‹Π΄Π°Ρ‡ΠΈ Ρ€Π°Π·Π²Π΅Ρ€Π½ΡƒΡ‚Ρ‹Ρ… сообщСний. Π’ Ρ‚Π°ΠΊΠΎΠΌ случаС ΠΌΠ½ΠΎΠ³ΠΈΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ Π±ΡƒΠ΄ΡƒΡ‚ Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ Π² ΠΏΠΎΡ‚ΠΎΠΊ stdout сообщСния ΠΎ Ρ…ΠΎΠ΄Π΅ выполнСния Π·Π°Π΄Π°Ρ‡ΠΈ.

11.2.2. Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° сСрвСрных ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ

Π’ Ρ„Π°ΠΉΠ»Π΅ module.c (листинг 11.3) содСрТится рСализация динамичСски Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌΡ‹Ρ… сСрвСрных ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ. Π—Π°Π³Ρ€ΡƒΠΆΠ΅Π½Π½ΠΎΠΌΡƒ ΠΌΠΎΠ΄ΡƒΠ»ΡŽ соотвСтствуСт структура Ρ‚ΠΈΠΏΠ° server_module, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ Π² Ρ„Π°ΠΉΠ»Π΅ server.h.

Листинг 11.3. (module.c) Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΈ Π²Ρ‹Π³Ρ€ΡƒΠ·ΠΊΠ° сСрвСрных ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ

#include <dlfcn.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include "server.h"


char* module_dir;


struct server_module* module_open(const char* module_name) {

 char* module_path;

 void* handle;

 void (*module_generate)(int);

 struct server_module* module;

 /* Π€ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΡƒΡ‚Π΅Π²ΠΎΠ³ΠΎ ΠΈΠΌΠ΅Π½ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ содСрТится

    Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌΡ‹ΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ. */

 module_path =

  (char*)xmalloc(strlen(module_dir) +

  strlen(module_name) + 2);

 sprintf(module_path, "%s/%s", module_dir, module_name);


 /* ΠŸΠΎΠΏΡ‹Ρ‚ΠΊΠ° ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ Ρ„Π°ΠΉΠ» MODULE_PATH ΠΊΠ°ΠΊ совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡƒΡŽ

    Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ. */

 handle = dlopen(module_path, RTLD_NOW);

 free (module_path);

 if (handle == NULL) {

  /* Ошибка: Π»ΠΈΠ±ΠΎ ΠΏΡƒΡ‚ΡŒ Π½Π΅ сущСствуСт, Π»ΠΈΠ±ΠΎ Ρ„Π°ΠΉΠ» Π½Π΅ являСтся

     совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΎΠΉ. */

  return NULL;

 }


 /* Π§Ρ‚Π΅Π½ΠΈΠ΅ константы module_generate ΠΈΠ· Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ. */

 module_generatΠ΅ =

  (void(*)int))dlsym(handle,

  "module_generate");

 /* ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, Π½Π°ΠΉΠ΄Π΅Π½Π° Π»ΠΈ константа. */

 if (module_generate == NULL) {

  /* ΠšΠΎΠ½ΡΡ‚Π°Π½Ρ‚Π° отсутствуСт Π² Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅. ΠžΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ, Ρ„Π°ΠΉΠ» Π½Π΅

     являСтся сСрвСрным ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΌ. */

  dlclose(handle);

  return NULL;

 }


 /* Π’Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΈ инициализация ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° server_module. */

 module =

  (struct server_module*)xmalloc

  (sizeof (struct server_module));

 module->handle = handle;

 module->name = xstrdup(module_name);

 module->generate_function = module_generate;

 /* УспСшноС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. */

 return module;

}


void module_close(struct server_module* module) {

 /* Π—Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ. */

 dlclose(module->handle);

 /* Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ строки с ΠΈΠΌΠ΅Π½Π΅ΠΌ модуля. */

 free((char*)module->name);

 /* Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° module. */

 free(module);

}

ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ содСрТится Π² Ρ„Π°ΠΉΠ»Π΅ совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ (см. Ρ€Π°Π·Π΄Π΅Π» 2.3.2, "БовмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ") ΠΈ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠΊΡΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ module_generate(). Π­Ρ‚Π° функция Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ HTML-ΠΊΠΎΠ΄ Web-страницы ΠΈ записываСт Π΅Π³ΠΎ Π² сокСт, дСскриптор ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½ Π΅ΠΉ Π² качСствС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°.

Π’ Ρ„Π°ΠΉΠ»Π΅ module.c ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ Π΄Π²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.

β–  Π€ΡƒΠ½ΠΊΡ†ΠΈΡ module_open() пытаСтся Π·Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ сСрвСрный ΠΌΠΎΠ΄ΡƒΠ»ΡŒ с ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ. Π€Π°ΠΉΠ» модуля ΠΈΠΌΠ΅Π΅Ρ‚ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ .so, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ это совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠ°Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°. Ѐункция ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ dlopen() ΠΈ ΠΈΡ‰Π΅Ρ‚ Π² Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ константу module_generate посрСдством Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ dlsym() (описаны Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 2.3.6, "ДинамичСская Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΈ Π²Ρ‹Π³Ρ€ΡƒΠ·ΠΊΠ°"). Если Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ Π½Π΅ ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ ΠΈΠ»ΠΈ Π² Π½Π΅ΠΉ Π½Π΅ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½Π° экспортируСмая константа module_generate, возвращаСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ NULL. Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС выдСляСтся ΠΈ возвращаСтся ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ module.

β–  Π€ΡƒΠ½ΠΊΡ†ΠΈΡ module_close() Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡƒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌΡƒ ΠΌΠΎΠ΄ΡƒΠ»ΡŽ, ΠΈ удаляСт ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ module.

Π’ Ρ„Π°ΠΉΠ»Π΅ module.c ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° Ρ‚Π°ΠΊΠΆΠ΅ глобальная пСрСмСнная module_dir. Π’ Π½Π΅ΠΉ записано имя ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ функция module_open() Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΊΠ°Ρ‚ΡŒ совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ.

11.2.3. Π‘Π΅Ρ€Π²Π΅Ρ€

Π€Π°ΠΉΠ» server.c (листинг 11.4) прСдставляСт собой Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠ΅Π³ΠΎ HTTP-сСрвСра.

Листинг 11.4. (server.c) РСализация HTTP-сСрвСра

#include <arpa/inet.h>

#include <assert.h>

#include <errno.h>

#include <netinet/in.h>

#include <signal.h>

#include <stdio.h>

#include <string.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <sys/wait.h>

#include <unistd.h>

#include "server.h"


/* HTTP-ΠΎΡ‚Π²Π΅Ρ‚ ΠΈ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ Π² случаС

   ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ запроса. */

static char* ok_response =

 "HTTP/1.0 100 OK\n"

 "Content-type: text/html\n"

 "\n";


/* HTTP-ΠΎΡ‚Π²Π΅Ρ‚, Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈ Ρ‚Π΅Π»ΠΎ страницы Π½Π° случай

   нСпонятного запроса. */

static char* bad_request_response =

 "HTTP/1.0 400 Bad Reguest\n"

 "Content-type: text/html\n"

 "\n"

 "<html>\n"

 " <body>\n"

 "  <h1>Bad Request</h1>\n"

 " 

This server did not understand your request.

\n"