Приложение 1 Вспомогательный код для UNIX

Заголовочный файл etcp.h

Почти все программы в этой книге начинаются с заголовочного файла etcp. h (листинг П1.1). Он подключает и другие необходимые файлы, в том числе skel. h (листинг П2.1), а также определения некоторых констант, типов данных и прототипов.

Листинг П1.1. Заголовочный файл etcp.h

etcp.h

1 #ifndef _ЕТСР_Н_

2 #define _ЕТСР_Н_

3 /* Включаем стандартные заголовки. */

4 #include <errno.h>

5 #include <stdlib.h>

6 #include <unistd.h>

7 #include <stdio.h>

8 #include <stdarg.h>

9 #include <string.h>

10 #include <netdb.h>

11 #include <signal.h>

12 #include <fcntl.h>

13 ttinclude <sys/socket.h>

14 ttinclude <sys/wait.h>

15 #include <sys/time.h>

16 #include <sys/resource.h>

17 #include <sys/stat.h>

18 #include <netinet/in.h>

19 #include <arpa/inet.h>

20 #include "skel.h"

21 #define TRUE 1

22 #define FALSE 0

23 #define NLISTEN 5 /* Максимальное число ожидающих соединений. */

24 #define NSMB 5 /* Число буферов в разделяемой памяти. */

25 #define SMBUFSZ256/* Размер буфера в разделяемой памяти. */

26 extern char *program_name; /* Для сообщений об ошибках. */

27 #ifdef _SVR4

28 #define bzero(b,n) memset( ( b ), 0, ( n ) )

29 #endif

30 typedef void ( *tofunc_t )( void * );

31 void error( int, int, char*, ... );

32 int readn( SOCKET, char *, size_t );

33 int readvrec( SOCKET, char *, size_t );

34 int readcrlft SOCKET, char *, size_t );

35 int readline( SOCKET, char *, size_t );

36 int tcp_server( char *, char * ) ;

37 int tcp_client( char *, char * ) ;

38 int udp_server( char *, char * );

39 int udp_client( char *, char *, struct sockaddr_in * );

40 int tselect( int, fd_set *, fd_set *, fd_set *);

41 unsigned int timeout( tofunc_t, void *, int );

42 void untimeout( unsigned int );

43 void init_smb( int ) ;

44 void *smballoc( void );

45 void smbfree( void * ) ;

46 void smbsendt SOCKET, void * ) ;

47 void *smbrecv( SOCKET ) ;

48 void set_address( char *, char *, struct sockaddr_in *, char * );

49 #endif /* _ETCP_H_ */

etcp.h

Функция daemon

Функция daemon, которая использована в программе tcpmux, входит в стандартную библиотеку, поставляемую с системой BSD. Для систем SVR4 приводится версия, текст которой показан в листинге П1.2.

Листинги 1.2. Функция daemon

daemon.с

1 int daemon ( int nocd, int nodose )

2 {

3 struct rlimit rlim;

4 pid_t pid;

5 int i;

6 umask( 0 ); /* Очистить маску создания файлов. */

7 /* Получить максимальное число открытых файлов. *,/

8 if ( getrlimitf RLIMIT_NOFILE, &rlim ) < 0 )

9 error( 1, errno, "getrlimit failed" );

10 /* Стать лидером сессии, потеряв при этом управляющий терминал... */

11 pid = fork() ;

12 if ( pid < 0 )

13 return -1;

14 if ( pid != 0 )

15 exit ( 0 ) ;

16 setsid();

17 /* ... и гарантировать, что больше его не будет. */

18 signal( SIGHUP, SIG_IGN );

19 pid = forkf);

20 if ( pid < 0 )

21 return -1;

22 if ( pid != 0 )

23 exit( 0 );

24 /* Сделать текущим корневой каталог, если не требовалось обратное */

25 if ( !nocd )

26 chdir( "/" ) ;

27 /*

28 * Если нас не просили этого не делать, закрыть все файлы.

29 * Затем перенаправить stdin, stdout и stderr

30 * на /dev/null.

31 */

32 if ( Inoclose )

33 {

34 #if 0 /* Заменить на 1 для закрытия всех файлов. */

35 if ( rlim.rlim_max == RLIM_INFINITY )

36 rlim.rlim_max = 1024;

37 for ( i = 0; i < rlim.rlim_max; i++ )

38 close( i );

39 ttendif

40 i = open( "/dev/null", 0_RDWR );

41 if ( i < 0 )

42 return -1;

43 dup2( i, 0 );

44 dup2( i, 1 );

45 dup2( i, 2 );

46 if ( i > 2 )

47 close( i ) ;

48 }

49 return 0;

50 }

daemon.с

Функция signal

В этой книге уже упоминалось, что в некоторых версиях UNIX функция signal реализована на основе семантики ненадежных сигналов. В таком случае для получения семантики надежных сигналов следует использовать функцию sigaction. Чтобы повысить переносимость, необходимо реализовать signal с помощью sigaction (листинг П1.3)

Листинги1.3. Функция signal

signal.с 

/* signal - надежная версия для SVR4 и некоторых других систем. */

1 typedef void sighndlr_t( int ) ;

2 sighndlr_t *signal( int sig, sighndlr_t *hndlr )

3 {

4 struct sigaction.act;

5 struct sigaction xact;

6 act.sa_handler = hndlr;

7 act.sa_flags = 0;

8 sigemptyset( &act.sa_mask );

9 if ( sigaction( sig, &act, &xact ) < 0 )

10 return SIG_ERR;

11 return xact.sa_handler;

12 }

signal.с



Опубликовал admin
14 Авг, Суббота 2004г.



Программирование для чайников.