- rfds = save_rfds;
- if (select(FD_SETSIZE, &rfds, NULL, NULL, NULL) < 0) {
- if (errno == EINTR)
- continue;
- syslog(LOG_ERR, "main: can't wait for input: %m");
- break;
- }
-
- for (config = configs; config; config = config->next) {
- if (config->fd < 0)
- continue;
- if (FD_ISSET(config->fd, &rfds))
- config->server_start(config, configs, server_children);
- }
- }
+ LOG(log_maxdebug, logtype_afpd, "main: polling %i fds", fdset_used);
+ pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
+ ret = poll(fdset, fdset_used, -1);
+ pthread_sigmask(SIG_BLOCK, &sigs, NULL);
+ int saveerrno = errno;
+
+ if (reloadconfig) {
+ nologin++;
+ auth_unload();
+
+ LOG(log_info, logtype_afpd, "re-reading configuration file");
+ for (config = configs; config; config = config->next)
+ if (config->server_cleanup)
+ config->server_cleanup(config);
+
+ /* configfree close atp socket used for DDP tickle, there's an issue
+ * with atp tid. */
+ configfree(configs, NULL);
+ if (!(configs = configinit(&default_options))) {
+ LOG(log_error, logtype_afpd, "config re-read: no servers configured");
+ exit(EXITERR_CONF);
+ }
+ fd_reset_listening_sockets();
+ nologin = 0;
+ reloadconfig = 0;
+ errno = saveerrno;
+ }
+
+ if (ret == 0)
+ continue;
+
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ LOG(log_error, logtype_afpd, "main: can't wait for input: %s", strerror(errno));
+ break;
+ }
+
+ for (int i = 0; i < fdset_used; i++) {
+ if (fdset[i].revents & POLLIN) {
+ switch (polldata[i].fdtype) {
+ case LISTEN_FD:
+ config = (AFPConfig *)polldata[i].data;
+ /* config->server_start is afp_config.c:dsi_start() for DSI */
+ if (child = config->server_start(config, configs, server_children)) {
+ /* Add IPC fd to select fd set */
+ fdset_add_fd(&fdset, &polldata, &fdset_used, &fdset_size, child->ipc_fds[0], IPC_FD, child);
+ }
+ break;
+ case IPC_FD:
+ child = (afp_child_t *)polldata[i].data;
+ LOG(log_debug, logtype_afpd, "main: IPC request from child[%u]", child->pid);
+ if ((ret = ipc_server_read(server_children, child->ipc_fds[0])) == 0) {
+ fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, child->ipc_fds[0]);
+ close(child->ipc_fds[0]);
+ child->ipc_fds[0] = -1;
+ }
+ break;
+ default:
+ LOG(log_debug, logtype_afpd, "main: IPC request for unknown type");
+ break;
+ } /* switch */
+ } /* if */
+ } /* for (i)*/
+ } /* while (1) */