Fixed resource leakage during connection accept(2)
[middleman.git] / src / main.c
index f188421..d9f8cb8 100644 (file)
@@ -27,6 +27,7 @@
 #include <fcntl.h>
 #include <pwd.h>
 #include <grp.h>
+#include <sys/wait.h>
 #include "proto.h"
 
 #ifdef USE_SYSLOG
@@ -498,11 +499,9 @@ void mainloop()
                if (connection != NULL) {
                        if (access_check(access_list, connection, NULL, NULL)) {
                                x = process_new(connection);
-                               if (x != 0) {
+                               if (x != 0)
                                        putlog(MMLOG_ERROR, "failed to create thread for %s", connection->ip);
-
-                                       net_close(connection);
-                               }
+                               net_close(connection);
                        } else {
                                putlog(MMLOG_NETWORK, "refused connect from %s on port %d", connection->ip, connection->port);
 
@@ -512,15 +511,27 @@ void mainloop()
        }
 }
 
+static void sigchld(int signo)
+{
+       while (waitpid(-1,NULL,WNOHANG)>0);
+}
+
 /*
 create new thread
 */
 int process_new(CONNECTION * connection)
 {
        int perr, thread = -1, i;
-       pthread_t thread_id;
        pthread_attr_t thread_attr;
 
+       /* fork() before enqueue to threads[] */
+       signal(SIGCHLD,sigchld);
+       perr=fork();
+       if (perr>0)
+               return 0;
+       if (perr<0)
+               return perr;
+
        for (i = 0; i < MAXTHREADS && thread == -1; i++) {
                pthread_mutex_lock(&threads[i].lock);
                if (threads[i].flags & THREAD_UNUSED) {
@@ -548,11 +559,11 @@ int process_new(CONNECTION * connection)
        if (getuid() == 0)
                pthread_attr_setschedpolicy(&thread_attr, SCHED_FIFO);
 
-       perr = pthread_create(&thread_id, &thread_attr, (void *) process_entry, (void *) connection);
+       process_entry(connection);
 
        pthread_attr_destroy(&thread_attr);
 
-       return perr;
+       _exit(0);
 }
 
 /*