Эффективное программирование TCP-IP




Совет 18. Подумайте о том, чтобы - часть 5


28-35 Ищем в таблице service_table имя запрошенного сервиса. Если оно отсутствует, то посылаем клиенту сообщение об ошибке и завершаем работу.

36-38 Если имя сервиса начинается со знака +, посылаем клиенту подтверждение. В противном случае даем возможность сделать это серверу.

39-45 С помощью системного вызова dup дублируем дескриптор сокета на stdin, stdout и stderr, после чего закрываем исходный сокет. И, наконец, подменяем процесс процессом сервера с помощью вызова execv. После этого запрошенный клиентом сервер - это процесс-потомок. Если execv возвращает управление, то сообщаем клиенту, что не смогли запустить запрошенный сервер, и завершаем сеанс.

В листинге 3.9 приведен текст подпрограммы parsetab. Она выполняет простой, но несколько утомительный разбор файла tcpmux. conf. Файл имеет следующий формат:

имя_сервиса путь аргументы ...

Листинг 3.9. Функция parsetab

1    static void parsetab( void )

2    {

3    FILE *fp;

4    servtab_t *stp = service_table;

5    char *cp;

6    int i;

7    int lineno;

8    char line[ MAXLINE ];

9    fp = fopen( CONFIG, "r" );

10   if ( fp == NULL )

11     error( 1, errno, "не могу открыть %s", CONFIG );

12   lineno = 0;

13   while ( fgets( line, sizeof( line ), fp ) != NULL )

14   {

15     lineno++;

16     if ( line[ strlen( line ) - 1 ] != '\n' )

17      error( 1, 0, "строка %d слишком длинная\п", lineno );

18     if ( stp >= service_table + NSERVTAB )

19      error( 1, 0, "слишком много строк в tcpmux.conf\n" );

20     cp = strchr( line, '#' );

21     if ( cp != NULL )

22      *cp = '\0';

23     cp = strtok( line, " \t\n" ) ;

24     if ( cp == NULL )

25      continue;

26     if ( *cp =='+')

28      stp->flag = TRUE;

29     cp++;

30     if ( *cp == '\0' strchrf " \t\n", *cp ) != NULL )

31      error( 1, 0, "строка %d: пробел после ‘+’'\n",

32       lineno );

34     stp->service = strdup( cp );

35     if ( stp->service == NULL )




Содержание  Назад  Вперед