superd.c
上传用户:wei_4586
上传日期:2008-05-28
资源大小:18k
文件大小:3k
源码类别:

网络

开发平台:

Unix_Linux

  1. /* superd.c - main */
  2. #define _USE_BSD
  3. #include <sys/types.h>
  4. #include <sys/param.h>
  5. #include <sys/socket.h>
  6. #include <sys/time.h>
  7. #include <sys/resource.h>
  8. #include <sys/errno.h>
  9. #include <sys/signal.h>
  10. #include <sys/wait.h>
  11. #include <netinet/in.h>
  12. #include <unistd.h>
  13. #include <stdlib.h>
  14. #include <stdio.h>
  15. #include <string.h>
  16. extern int errno;
  17. #define UDP_SERV 0
  18. #define TCP_SERV 1
  19. #define NOSOCK -1 /* an invalid socket descriptor */
  20. struct service {
  21. char *sv_name;
  22. char sv_useTCP;
  23. int sv_sock;
  24. void (*sv_func)(int);
  25. };
  26. void TCPechod(int), TCPchargend(int), TCPdaytimed(int), TCPtimed(int);
  27. int passiveTCP(const char *service, int qlen);
  28. int passiveUDP(const char *service);
  29. int errexit(const char *format, ...);
  30. void doTCP(struct service *psv);
  31. void reaper(int sig);
  32. struct service svent[] =
  33. { { "echo", TCP_SERV, NOSOCK, TCPechod },
  34. { "chargen", TCP_SERV, NOSOCK, TCPchargend },
  35. { "daytime", TCP_SERV, NOSOCK, TCPdaytimed },
  36. { "time", TCP_SERV, NOSOCK, TCPtimed },
  37. { 0, 0, 0, 0 },
  38. };
  39. #ifndef MAX
  40. #define MAX(x, y) ((x) > (y) ? (x) : (y))
  41. #endif /* MAX */
  42. #define QLEN  32
  43. #define LINELEN 128
  44. extern unsigned short portbase; /* from passivesock() */
  45. /*------------------------------------------------------------------------
  46.  * main - Super-server main program
  47.  *------------------------------------------------------------------------
  48.  */
  49. int
  50. main(int argc, char *argv[])
  51. {
  52. struct service *psv, /* service table pointer */
  53. *fd2sv[NOFILE]; /* map fd to service pointer */
  54. int fd, nfds;
  55. fd_set afds, rfds; /* readable file descriptors */
  56. switch (argc) {
  57. case 1:
  58. break;
  59. case 2:
  60. portbase = (unsigned short) atoi(argv[1]);
  61. break;
  62. default:
  63. errexit("usage: superd [portbase]n");
  64. }
  65. nfds = 0;
  66. FD_ZERO(&afds);
  67. for (psv = &svent[0]; psv->sv_name; ++psv) {
  68. if (psv->sv_useTCP)
  69. psv->sv_sock = passiveTCP(psv->sv_name, QLEN);
  70. else
  71. psv->sv_sock = passiveUDP(psv->sv_name);
  72. fd2sv[psv->sv_sock] = psv;
  73. nfds = MAX(psv->sv_sock+1, nfds);
  74. FD_SET(psv->sv_sock, &afds);
  75. }
  76. (void) signal(SIGCHLD, reaper);
  77. while (1) {
  78. memcpy(&rfds, &afds, sizeof(rfds));
  79. if (select(nfds, &rfds, (fd_set *)0, (fd_set *)0,
  80. (struct timeval *)0) < 0) {
  81. if (errno == EINTR)
  82. continue;
  83. errexit("select error: %sn", strerror(errno));
  84. }
  85. for (fd=0; fd<nfds; ++fd)
  86. if (FD_ISSET(fd, &rfds)) {
  87. psv = fd2sv[fd];
  88. if (psv->sv_useTCP)
  89. doTCP(psv);
  90. else
  91. psv->sv_func(psv->sv_sock);
  92. }
  93. }
  94. }
  95. /*------------------------------------------------------------------------
  96.  * doTCP - handle a TCP service connection request
  97.  *------------------------------------------------------------------------
  98.  */
  99. void
  100. doTCP(struct service *psv)
  101. {
  102. struct sockaddr_in fsin; /* the request from address */
  103. unsigned int alen; /* from-address length */
  104. int fd, ssock;
  105. alen = sizeof(fsin);
  106. ssock = accept(psv->sv_sock, (struct sockaddr *)&fsin, &alen);
  107. if (ssock < 0)
  108. errexit("accept: %sn", strerror(errno));
  109. switch (fork()) {
  110. case 0:
  111. break;
  112. case -1:
  113. errexit("fork: %sn", strerror(errno));
  114. default:
  115. (void) close(ssock);
  116. return; /* parent */
  117. }
  118. /* child */
  119. for (fd = NOFILE; fd >= 0; --fd)
  120. if (fd != ssock)
  121. (void) close(fd);
  122. psv->sv_func(ssock);
  123. exit(0);
  124. }
  125. /*------------------------------------------------------------------------
  126.  * reaper - clean up zombie children
  127.  *------------------------------------------------------------------------
  128.  */
  129. void
  130. reaper(int sig)
  131. {
  132. int status;
  133. while (wait3(&status, WNOHANG, (struct rusage *)0) >= 0)
  134. /* empty */;
  135. }