/* receive any incoming data, send any pending data */ static void process_data(struct telnet_session_s *t, int wait_flag) { fd_set readfds; fd_set writefds; fd_set exceptfds; struct timeval tv_zero; struct timeval *tv; /* set up our select() variables */ FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); if (wait_flag) { tv = NULL; } else { tv_zero.tv_sec = 0; tv_zero.tv_usec = 0; tv = &tv_zero; } /* only check for input if we can accept input */ if ((t->in_errno == 0) && (t->in_eof == 0) && (max_input_read(t) > 0)) { FD_SET(t->in_fd, &readfds); FD_SET(t->in_fd, &exceptfds); } /* only check for output if we have pending output */ if ((t->out_errno == 0) && (t->out_eof == 0) && (t->out_buflen > 0)) { FD_SET(t->out_fd, &writefds); FD_SET(t->out_fd, &exceptfds); } /* see if there's anything to do */ if (select(FD_SETSIZE, &readfds, &writefds, &exceptfds, tv) > 0) { if (FD_ISSET(t->in_fd, &exceptfds)) { t->in_eof = 1; } else if (FD_ISSET(t->in_fd, &readfds)) { read_incoming_data(t); } if (FD_ISSET(t->out_fd, &exceptfds)) { t->out_eof = 1; } else if (FD_ISSET(t->out_fd, &writefds)) { write_outgoing_data(t); } } }
int handle_connections(int portnum) { int listenfd; int acceptfd; pid_t childpid; listenfd = create_listener(portnum); if (listenfd < 0) { fprintf(stderr, "Warning: Exiting main network event loop\n"); return -1; } while (1) { fprintf(stderr, "Notice: Waiting for a connection...\n"); acceptfd = wait_for_connection(listenfd); if (acceptfd < 0) { fprintf(stderr, "Warning: Exiting main network event loop\n"); return -1; } childpid = fork(); if (childpid > 0) { close(acceptfd); fprintf(stderr, "Notice: Child process id=%d forked to handle incoming connection\n", childpid); } else if (childpid == 0) { close(listenfd); fprintf(stderr, "Notice: Processing request in child process\n"); read_incoming_data(acceptfd); exit(0); } else { perror("fork"); fprintf(stderr, "Error: Unable to create child process to handle new connection\n"); } } } /* handle_connections() */