int main (int argc, char *argv[]) { int sd, ci, backlog = MAX_BACKLOG; short port = PORTNUM; if (argc > 1) ncons = atoi (argv[1]); /* decrease stack size, non-privilged operation */ /* shrink_stack (STACK_SIZE); not needed for parent */ /* increase maximum number of file descriptors, must be root! */ /* a few extra, for 0, 1, 2 etc. */ check_and_set_max_fd (ncons + 8); cd = malloc (ncons * sizeof (int)); isopen = malloc (ncons * sizeof (int)); pid = malloc (ncons * sizeof (pid_t)); gethostname (hostname, 128); signal (SIGCHLD, cleanupkids); /* open an internet tcp stream socket */ /* socket, setsockopt for reuse, bind, listen; */ sd = get_socket (port, backlog); for (ci = 0; ci < ncons; ci++) isopen[ci] = 0; for (;;) { /* accept new connection only if less than the maximum is there */ while (nopen == ncons) { /* reap any children; there may be a race condition or signal pileup! */ cleanupkids (SIGCHLD); } /* find the first open one */ ci = accept_one (sd, isopen, cd, ncons); isopen[ci] = 1; nopen++; printf ("connection accepted (cd[%2d] = %2d), nopen = %2d\n", ci, cd[ci], nopen); fflush (stdout); /* fork off a child to handle the connection */ pid[ci] = fork (); if (pid[ci] < 0) DEATH ("Forking"); if (pid[ci] == 0) { /* child */ /* decrease stack size, non-privilged operation */ shrink_stack (STACK_SIZE); /* can set back for kids */ set_max_fd (16); while (!handle_client (cd[ci])) ; terminate_client (ci); } else { /* parent */ printf (" I forked for ci=%d, pid=%d\n", ci, pid[ci]); fflush (stdout); } } close (sd); free (isopen); free (cd); exit (EXIT_SUCCESS); }
int main (int argc, char *argv[]) { int sd, ci, n, backlog = MAX_BACKLOG, timeout = -1, nfds, nconsp1; short port = PORTNUM; struct pollfd *pfd, *pfd0; if (argc > 1) ncons = atoi (argv[1]); nconsp1 = ncons + 1; cd = malloc ((nconsp1 + 8) * sizeof (int)); isopen = malloc ((nconsp1 + 8) * sizeof (int)); ufds = malloc ((nconsp1 + 8) * sizeof (struct pollfd)); memset (ufds, 0, (nconsp1 + 8) * sizeof (struct pollfd)); /* increase maximum number of file descriptors, must be root! */ /* a few extra, for 0, 1, 2 etc. */ check_and_set_max_fd (nconsp1 + 8); gethostname (hostname, 128); /* open an internet tcp stream socket */ /* socket, setsockopt for reuse, bind, listen; */ sd = get_socket (port, backlog); /* for the listening socket */ pfd0 = &ufds[0]; pfd0->fd = sd; pfd0->events = POLLIN; isopen[0] = 0; for (ci = 1; ci < nconsp1 + 8; ci++) { pfd = &ufds[ci]; pfd->fd = -1; pfd->events = 0; isopen[ci] = 0; } for (;;) { /* wait for something to happen on one of the descriptors */ nfds = 1 + nopen; if (sd > fdmax) fdmax = sd; /* to begin with */ /* n = poll (ufds, nconsp1, timeout); */ n = poll (&ufds[0], fdmax + 1, timeout); if (n < 0) DEATH ("poll"); /* if you do a time out you have to deal with n = 0 */ /* accept new connection only if less than the maximum is there */ if ((pfd0->revents && POLLIN) && (nopen < ncons)) { isopen[0] = 1; /* find the first open one */ ci = accept_one (sd, isopen, cd, ncons); isopen[ci] = 1; pfd = &ufds[ci]; pfd->fd = cd[ci]; pfd->events = POLLIN; nopen++; if (cd[ci] > fdmax) fdmax = cd[ci]; printf ("connection accepted (cd[%2d] = %2d), nopen = %2d\n", ci, cd[ci], nopen); } /* service existing connections */ for (ci = 1; ci < nconsp1; ci++) { pfd = &ufds[ci]; if (isopen[ci] && (pfd->revents && POLLIN)) { if (handle_client (cd[ci])) terminate_client (ci); } fflush (stdout); } } close (sd); free (cd); free (isopen); exit (EXIT_SUCCESS); }