+ 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);
+ saveerrno = errno;
+
+ if (gotsigchld) {
+ gotsigchld = 0;
+ child_handler();
+ continue;
+ }
+
+ if (reloadconfig) {
+ nologin++;
+ auth_unload();
+ fd_reset_listening_sockets(&obj);
+
+ LOG(log_info, logtype_afpd, "re-reading configuration file");
+
+ configfree(&obj, NULL);
+ if (configinit(&obj) != 0) {
+ LOG(log_error, logtype_afpd, "config re-read: no servers configured");
+ afp_exit(EXITERR_CONF);
+ }
+
+ fd_set_listening_sockets(&obj);
+
+ nologin = 0;
+ reloadconfig = 0;
+ errno = saveerrno;
+ continue;
+ }
+
+ 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 | POLLERR | POLLHUP | POLLNVAL)) {
+ switch (polldata[i].fdtype) {
+
+ case LISTEN_FD:
+ if (child = dsi_start(&obj, (DSI *)polldata[i].data, server_children)) {
+ /* Add IPC fd to select fd set */
+ fdset_add_fd(obj.options.connections + AFP_LISTENERS + FDSET_SAFETY,
+ &fdset,
+ &polldata,
+ &fdset_used,
+ &fdset_size,
+ child->ipc_fd,
+ 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 (ipc_server_read(server_children, child->ipc_fd) != 0) {
+ fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, child->ipc_fd);
+ close(child->ipc_fd);
+ child->ipc_fd = -1;
+ if ((obj.options.flags & OPTION_KEEPSESSIONS) && child->disasociated) {
+ LOG(log_note, logtype_afpd, "main: removing reattached child[%u]", child->pid);
+ server_child_remove(server_children, CHILD_DSIFORK, child->pid);
+ }
+ }
+ break;
+
+ case DISASOCIATED_IPC_FD:
+ LOG(log_debug, logtype_afpd, "main: IPC reconnect request");
+ if ((recon_ipc_fd = accept(disasociated_ipc_fd, NULL, NULL)) == -1) {
+ LOG(log_error, logtype_afpd, "main: accept: %s", strerror(errno));
+ break;
+ }
+ if (readt(recon_ipc_fd, &pid, sizeof(pid_t), 0, 1) != sizeof(pid_t)) {
+ LOG(log_error, logtype_afpd, "main: readt: %s", strerror(errno));
+ close(recon_ipc_fd);
+ break;
+ }
+ LOG(log_note, logtype_afpd, "main: IPC reconnect from pid [%u]", pid);
+
+ if ((child = server_child_add(server_children, CHILD_DSIFORK, pid, recon_ipc_fd)) == NULL) {
+ LOG(log_error, logtype_afpd, "main: server_child_add");
+ close(recon_ipc_fd);
+ break;
+ }
+ child->disasociated = 1;
+ fdset_add_fd(obj.options.connections + AFP_LISTENERS + FDSET_SAFETY,
+ &fdset,
+ &polldata,
+ &fdset_used,
+ &fdset_size,
+ recon_ipc_fd,
+ IPC_FD,
+ child);
+ break;
+
+ default:
+ LOG(log_debug, logtype_afpd, "main: IPC request for unknown type");
+ break;
+ } /* switch */
+ } /* if */
+ } /* for (i)*/
+ } /* while (1) */