- /* listen on sock_fd, new connection on new_fd */
- int sockfd, new_fd;
- struct sockaddr_in their_addr;
- int i, max_fileno, ret;
- pid_t chld_pid;
- fd_set rfds, wfds;
- struct timeval *timeout;
-
- valid_fd_012();
- sockfd = do_inits(argc, argv);
-repeat:
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
- max_fileno = -1;
- /* check socket and signal pipe in any case */
- para_fd_set(sockfd, &rfds, &max_fileno);
- para_fd_set(signal_pipe, &rfds, &max_fileno);
- timeout = vss_preselect(&rfds, &wfds, &max_fileno);
- status_refresh();
- for (i = 0; senders[i].name; i++) {
- if (senders[i].status != SENDER_ON)
- continue;
- if (!senders[i].pre_select)
- continue;
- senders[i].pre_select(&max_fileno, &rfds, &wfds);
- }
- mmd_unlock();
- ret = para_select(max_fileno + 1, &rfds, &wfds, timeout);
- mmd_lock();
- vss_post_select(&rfds, &wfds);
- if (ret < 0)
- goto repeat;
- for (i = 0; senders[i].name; i++) {
- if (senders[i].status != SENDER_ON)
- continue;
- if (!senders[i].post_select)
- continue;
- senders[i].post_select(&rfds, &wfds);
- }
- vss_send_chunk();
- status_refresh();
- if (FD_ISSET(signal_pipe, &rfds)) {
- int sig;
- pid_t pid;
- sig = para_next_signal();
- switch (sig) {
- case SIGHUP:
- handle_sighup();
- break;
- case SIGCHLD:
- for (;;) {
- ret = para_reap_child(&pid);
- if (ret <= 0)
- break;
- if (pid != afs_pid)
- continue;
- PARA_EMERG_LOG("fatal: afs died\n");
- goto genocide;
- }
- break;
- /* die on sigint/sigterm. Kill all children too. */
- case SIGINT:
- case SIGTERM:
- PARA_EMERG_LOG("terminating on signal %d\n", sig);
-genocide:
- kill(0, SIGTERM);
- mutex_destroy(mmd_mutex);
- shm_detach(mmd);
- shm_destroy(mmd_shm_id);
-
- exit(EXIT_FAILURE);
- }
- }
- if (mmd->sender_cmd_data.cmd_num >= 0) {
- int num = mmd->sender_cmd_data.cmd_num,
- s = mmd->sender_cmd_data.sender_num;
-
- if (senders[s].client_cmds[num])
- senders[s].client_cmds[num](&mmd->sender_cmd_data);
- mmd->sender_cmd_data.cmd_num = -1;
- }
- if (!FD_ISSET(sockfd, &rfds))
- goto repeat;
-
- new_fd = para_accept(sockfd, &their_addr, sizeof(struct sockaddr_in));
- if (new_fd < 0)
- goto repeat;
- PARA_INFO_LOG("got connection from %s, forking\n",
- inet_ntoa(their_addr.sin_addr));
- mmd->num_connects++;
- mmd->active_connections++;
- random();
- chld_pid = fork();
- if (chld_pid < 0) {
- PARA_CRIT_LOG("%s", "fork failed\n");
- goto repeat;
- }
- if (chld_pid) {
- close(new_fd);
- /* parent keeps accepting connections */
- goto repeat;