PARA_EMERG_LOG("terminating on signal %d\n", st->signum);
genocide:
kill(0, SIGTERM);
+ free(mmd->afd.afhi.chunk_table);
+ free(mmd->afd.afhi.info_string);
+ close_listed_fds();
mutex_destroy(mmd_mutex);
shm_detach(mmd);
exit(EXIT_FAILURE);
int new_fd, ret, i;
char *peer_name;
pid_t child_pid;
+ uint32_t *chunk_table;
+ char *info_string;
if (!FD_ISSET(sct->listen_fd, &s->rfds))
return;
mmd->num_connects++;
mmd->active_connections++;
random();
+ /* The chunk table and the info_string are pointers located in the
+ * mmd struct that point to dynamically allocated memory that must be
+ * freed by the parent and the child. However, as the mmd struct is in
+ * a shared memory area, there's no guarantee that after the fork these
+ * pointers are still valid in child context. As these two pointers are
+ * not used in the child anyway, we save them to local variables and
+ * free the memory via that copy in the child.
+ */
+ info_string = mmd->afd.afhi.info_string;
+ chunk_table = mmd->afd.afhi.chunk_table;
child_pid = fork();
if (child_pid < 0) {
ret = -ERRNO_TO_PARA_ERROR(errno);
/* parent keeps accepting connections */
return;
}
+ /* mmd might already have changed at this point */
+ free(info_string);
+ free(chunk_table);
alarm(ALARM_TIMEOUT);
close_listed_fds();
para_signal_shutdown();
return afs_server_socket[0];
}
+__noreturn static void tmp_sigchld_handler(__a_unused int s)
+{
+ PARA_EMERG_LOG("caught early SIGCHLD\n");
+ exit(EXIT_FAILURE);
+}
+
static void server_init(int argc, char **argv)
{
struct server_cmdline_parser_params params = {
PARA_EMERG_LOG("failed to ignore SIGUSR1\n");
exit(EXIT_FAILURE);
}
+ /*
+ * We have to install a SIGCHLD handler before the afs process is being
+ * forked off. Otherwise, para_server does not notice if afs dies before
+ * the SIGCHLD handler has been installed by init_signal_task() below.
+ */
+ if (signal(SIGCHLD, tmp_sigchld_handler) == SIG_ERR) {
+ PARA_EMERG_LOG("failed to install temporary SIGCHLD handler\n");
+ exit(EXIT_FAILURE);
+ }
PARA_NOTICE_LOG("initializing the audio file selector\n");
afs_socket = init_afs();
init_signal_task();