+ int conn=-1;
+ int pid=-1;
+ int pipe_fd[2];
+ struct tid_process tp = {0};
+
+ if (0 > (conn = tr_sock_accept(listen))) {
+ tr_debug("tids_accept: Error accepting connection");
+ return 1;
+ }
+
+ if (0 > pipe(pipe_fd)) {
+ perror("Error on pipe()");
+ return 1;
+ }
+ /* pipe_fd[0] is for reading, pipe_fd[1] is for writing */
+
+ if (0 > (pid = fork())) {
+ perror("Error on fork()");
+ return 1;
+ }
+
+ if (pid == 0) {
+ /* Only the child process gets here */
+ close(pipe_fd[0]); /* close the read end of the pipe, the child only writes */
+ close(listen); /* close the child process's handle on the listen port */
+
+ tids_handle_proc(tids, conn, pipe_fd[1]); /* never returns */
+ }
+
+ /* Only the parent process gets here */
+ close(pipe_fd[1]); /* close the write end of the pipe, the parent only listens */
+ close(conn); /* connection belongs to the child, so close parent's handle */
+
+ /* remember the PID of our child process */
+ tr_info("tids_accept: Spawned TID process %d to handle incoming connection.", pid);
+ tp.pid = pid;
+ tp.read_fd = pipe_fd[0];
+ g_array_append_val(tids->pids, tp);
+
+ /* clean up any processes that have completed */
+ tids_sweep_procs(tids);
+ return 0;
+}
+
+/**
+ * Clean up any finished TID request processes
+ *
+ * This is called by the main process after forking each TID request. If you want to be
+ * sure finished processes are cleaned up promptly even during a lull in TID requests,
+ * this can be called from the main thread of the main process. It is not thread-safe,
+ * so should not be used from sub-threads. It should not be called by child processes -
+ * this would probably be harmless but ineffective.
+ *
+ * @param tids
+ */
+void tids_sweep_procs(TIDS_INSTANCE *tids)
+{
+ guint ii;
+ struct tid_process tp = {0};
+ char result[TIDS_MAX_MESSAGE_LEN] = {0};
+ ssize_t result_len;
+ int status;
+ int wait_rc;
+
+ /* loop backwards over the array so we can remove elements as we go */
+ for (ii=tids->pids->len; ii > 0; ii--) {
+ /* ii-1 is the current index - get our own copy, we may destroy the list's copy */
+ tp = g_array_index(tids->pids, struct tid_process, ii-1);
+
+ wait_rc = waitpid(tp.pid, &status, WNOHANG);
+ if (wait_rc == 0)
+ continue; /* process still running */
+
+ if (wait_rc < 0) {
+ /* invalid options will probably keep being invalid, report that condition */
+ if(errno == EINVAL)
+ tr_crit("tids_sweep_procs: waitpid called with invalid options");
+
+ /* If we got ECHILD, that means the PID was invalid; we'll assume the process was
+ * terminated and we missed it. For all other errors, move on
+ * to the next PID to check. */
+ if (errno != ECHILD)
+ continue;
+
+ tr_warning("tid_sweep_procs: TID process %d disappeared", tp.pid);
+ }