- rlim_ofile_cur = OPEN_MAX;
- }
-
- memset ((char *) &sa, 0, sizeof (sa));
- sigemptyset (&sa.sa_mask);
- sigaddset (&sa.sa_mask, SIGALRM);
- sigaddset (&sa.sa_mask, SIGCHLD);
- sigaddset (&sa.sa_mask, SIGHUP);
- sa.sa_handler = retry;
- sigaction (SIGALRM, &sa, NULL);
- /* doconfig(); */
- config (SIGHUP);
- sa.sa_handler = config;
- sigaction (SIGHUP, &sa, NULL);
- sa.sa_handler = reapchild;
- sigaction (SIGCHLD, &sa, NULL);
- sa.sa_handler = goaway;
- sigaction (SIGTERM, &sa, NULL);
- sa.sa_handler = goaway;
- sigaction (SIGINT, &sa, NULL);
- sa.sa_handler = SIG_IGN;
- sigaction (SIGPIPE, &sa, &sapipe);
- memset(&wait_mask, 0, sizeof(wait_mask));
- {
- /* space for daemons to overwrite environment for ps */
-#define DUMMYSIZE 100
- char dummy[DUMMYSIZE];
-
- (void) memset (dummy, 'x', DUMMYSIZE - 1);
- dummy[DUMMYSIZE - 1] = '\0';
-
- (void) setenv ("inetd_dummy", dummy, 1);
- }
-
- for (;;) {
- int n, ctrl = -1;
- fd_set readable;
-
- if (nsock == 0) {
- Block_Using_Signals(omask);
- while (nsock == 0)
- sigsuspend (&wait_mask);
- sigprocmask(SIG_UNBLOCK, &omask, NULL);
- }
-
- readable = allsock;
- if ((n = select (maxsock + 1, &readable, NULL, NULL, NULL)) <= 0) {
- if (n < 0 && errno != EINTR) {
- bb_perror_msg("select");
- sleep (1);
- }
- continue;
- }
- for (sep = servtab; n && sep; sep = sep->se_next)
- if (sep->se_fd != -1 && FD_ISSET (sep->se_fd, &readable)) {
- n--;
- if (!sep->se_wait && sep->se_socktype == SOCK_STREAM) {
- ctrl = accept (sep->se_fd, NULL, NULL);
- if (ctrl < 0) {
- if (errno == EINTR)
- continue;
- bb_perror_msg("accept (for %s)", sep->se_service);
- continue;
- }
- if (sep->se_family == AF_INET && sep->se_socktype == SOCK_STREAM) {
- struct sockaddr_in peer;
- socklen_t plen = sizeof (peer);
-
- if (getpeername (ctrl, (struct sockaddr *) &peer, &plen) < 0) {
- bb_error_msg("could not getpeername");
- close (ctrl);
- continue;
+ rlim_ofile_cur = OPEN_MAX;
+
+ memset(&sa, 0, sizeof(sa));
+ /*sigemptyset(&sa.sa_mask); - memset did it */
+ sigaddset(&sa.sa_mask, SIGALRM);
+ sigaddset(&sa.sa_mask, SIGCHLD);
+ sigaddset(&sa.sa_mask, SIGHUP);
+//FIXME: explain why no SA_RESTART
+//FIXME: retry_network_setup is unsafe to run in signal handler (many reasons)!
+ sa.sa_handler = retry_network_setup;
+ sigaction_set(SIGALRM, &sa);
+//FIXME: reread_config_file is unsafe to run in signal handler(many reasons)!
+ sa.sa_handler = reread_config_file;
+ sigaction_set(SIGHUP, &sa);
+//FIXME: reap_child is unsafe to run in signal handler (uses stdio)!
+ sa.sa_handler = reap_child;
+ sigaction_set(SIGCHLD, &sa);
+//FIXME: clean_up_and_exit is unsafe to run in signal handler (uses stdio)!
+ sa.sa_handler = clean_up_and_exit;
+ sigaction_set(SIGTERM, &sa);
+ sa.sa_handler = clean_up_and_exit;
+ sigaction_set(SIGINT, &sa);
+ sa.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &sa, &saved_pipe_handler);
+
+ reread_config_file(SIGHUP); /* load config from file */
+
+ for (;;) {
+ int ready_fd_cnt;
+ int ctrl, accepted_fd, new_udp_fd;
+ fd_set readable;
+
+ if (maxsock < 0)
+ recalculate_maxsock();
+
+ readable = allsock; /* struct copy */
+ /* if there are no fds to wait on, we will block
+ * until signal wakes us up (maxsock == 0, but readable
+ * never contains fds 0 and 1...) */
+ ready_fd_cnt = select(maxsock + 1, &readable, NULL, NULL, NULL);
+ if (ready_fd_cnt < 0) {
+ if (errno != EINTR) {
+ bb_perror_msg("select");
+ sleep(1);