diff -urN user/thttpd/libhttpd.c user/thttpd/libhttpd.c
--- user/thttpd/libhttpd.c	2008-06-11 21:27:34.000000000 -0400
+++ user/thttpd/libhttpd.c	2008-09-30 11:40:37.000000000 -0400
@@ -2748,7 +2748,9 @@
 	    {
 	    /* Child process. */
 	    sub_process = 1;
+#ifndef __uClinux__
 	    httpd_unlisten( hc->hs );
+#endif
 	    send_mime(
 		hc, 200, ok200title, "", "", "text/html; charset=%s",
 		(off_t) -1, hc->sb.st_mtime );
@@ -3342,6 +3344,8 @@
     char** envp;
     char* binary;
     char* directory;
+    int cgi_conn = hc->conn_fd; /* for uClinux(NOMMU), hc->conn_fd should not be 
+                                   changed(shared by child and parent) */
 
     /* Unset close-on-exec flag for this socket.  This actually shouldn't
     ** be necessary, according to POSIX a dup()'d file descriptor does
@@ -3369,9 +3373,9 @@
     */
     if ( hc->conn_fd == STDIN_FILENO || hc->conn_fd == STDOUT_FILENO || hc->conn_fd == STDERR_FILENO )
 	{
-	int newfd = dup2( hc->conn_fd, STDERR_FILENO + 1 );
+	int newfd = dup2( cgi_conn, STDERR_FILENO + 1 );
 	if ( newfd >= 0 )
-	    hc->conn_fd = newfd;
+	    cgi_conn = newfd;
 	/* If the dup2 fails, shrug.  We'll just take our chances.
 	** Shouldn't happen though.
 	*/
@@ -3430,12 +3434,16 @@
 	{
 	/* Otherwise, the request socket is stdin. */
 	if ( hc->conn_fd != STDIN_FILENO )
-	    (void) dup2( hc->conn_fd, STDIN_FILENO );
+	    (void) dup2( cgi_conn, STDIN_FILENO );
 	}
 
     /* Set up stdout/stderr.  If we're doing CGI header parsing,
     ** we need an output interposer too.
     */
+#ifdef __uClinux__ /* cannot run it in another vfork except use pthread*/
+    if ( strncmp( argp[0], "nph-", 4 ) != 0 && hc->mime_flag )
+	(void) write( STDOUT_FILENO, "HTTP/1.0 200 OK\n", 16 );
+#else
     if ( strncmp( argp[0], "nph-", 4 ) != 0 && hc->mime_flag )
 	{
 	int p[2];
@@ -3447,11 +3455,7 @@
 	    httpd_write_response( hc );
 	    exit( 1 );
 	    }
-#ifdef __uClinux__
-	r = vfork( );
-#else
 	r = fork( );
-#endif
 	if ( r < 0 )
 	    {
 	    syslog( LOG_ERR, "fork - %m" );
@@ -3477,12 +3481,13 @@
 	    (void) close( p[1] );
 	}
     else
+#endif
 	{
 	/* Otherwise, the request socket is stdout/stderr. */
-	if ( hc->conn_fd != STDOUT_FILENO )
-	    (void) dup2( hc->conn_fd, STDOUT_FILENO );
-	if ( hc->conn_fd != STDERR_FILENO )
-	    (void) dup2( hc->conn_fd, STDERR_FILENO );
+	if ( cgi_conn != STDOUT_FILENO )
+	    (void) dup2( cgi_conn, STDOUT_FILENO );
+	if ( cgi_conn != STDERR_FILENO )
+	    (void) dup2( cgi_conn, STDERR_FILENO );
 	}
 
     /* At this point we would like to set close-on-exec again for hc->conn_fd
@@ -3536,7 +3541,11 @@
     syslog( LOG_ERR, "execve %.80s - %m", hc->expnfilename );
     httpd_send_err( hc, 500, err500title, "", err500form, hc->encodedurl );
     httpd_write_response( hc );
+#ifdef __uClinux__
+    _exit( 1 );
+#else
     exit( 1 );
+#endif
     }
 
 
@@ -3573,7 +3582,9 @@
 	    {
 	    /* Child process. */
 	    sub_process = 1;
+#ifndef __uClinux__
 	    httpd_unlisten( hc->hs );
+#endif
 	    cgi_child( hc );
 	    }
 
diff -urN user/thttpd/thttpd.c user/thttpd/thttpd.c
--- user/thttpd/thttpd.c	2008-06-11 21:27:34.000000000 -0400
+++ user/thttpd/thttpd.c	2008-09-30 11:37:53.000000000 -0400
@@ -761,7 +761,10 @@
 	    if ( errno == EINTR || errno == EAGAIN )
 		continue;       /* try again */
 	    syslog( LOG_ERR, "fdwatch - %m" );
-	    exit( 1 );
+
+            /* FIXME: why got "Bad file descriptor" */
+	    /* exit( 1 ); */
+	    continue;       /* try again */
 	    }
 	(void) gettimeofday( &tv, (struct timezone*) 0 );
 
