Index: cherokee/handler_uwsgi.c
===================================================================
--- cherokee/handler_uwsgi.c	(revision 6364)
+++ cherokee/handler_uwsgi.c	(working copy)
@@ -76,6 +76,7 @@
 		n->modifier2 = 0 ;
 		n->pass_wsgi_vars = true;
 		n->pass_request_body = true;
+		n->pass_fd = false;
 
 		*_props = MODULE_PROPS(n);
 	}
@@ -103,6 +104,9 @@
 		else if (equal_buf_str (&subconf->key, "pass_request_body")) {
 			props->pass_request_body = !! atoi (subconf->val.buf);
 		}
+		else if (equal_buf_str (&subconf->key, "pass_fd")) {
+                        props->pass_fd = !! atoi(subconf->val.buf);
+		}
 	}
 
 	/* Init base class
@@ -328,8 +332,15 @@
 	ret_t                  ret;
 	size_t                 written = 0;
 	cherokee_connection_t *conn    = HANDLER_CONN(hdl);
+	cherokee_handler_uwsgi_props_t *props    = HANDLER_UWSGI_PROPS(hdl);
 
-	ret = cherokee_socket_bufwrite (&hdl->socket, &hdl->header, &written);
+	if (props->pass_fd && SOCKET_AF(&hdl->socket) == AF_UNIX) {
+		ret = cherokee_socket_bufwrite_pass_fd(&hdl->socket, conn, &hdl->header, &written);
+	}
+	else {
+		ret = cherokee_socket_bufwrite (&hdl->socket, &hdl->header, &written);
+	}
+
 	if (ret != ret_ok) {
 		conn->error_code = http_bad_gateway;
 		return ret;
Index: cherokee/handler_uwsgi.h
===================================================================
--- cherokee/handler_uwsgi.h	(revision 6364)
+++ cherokee/handler_uwsgi.h	(working copy)
@@ -49,6 +49,7 @@
 	uint8_t                      modifier2;
 	cherokee_boolean_t           pass_wsgi_vars;
 	cherokee_boolean_t           pass_request_body;
+	cherokee_boolean_t           pass_fd;
 } cherokee_handler_uwsgi_props_t;
 
 
Index: cherokee/socket.c
===================================================================
--- cherokee/socket.c	(revision 6364)
+++ cherokee/socket.c	(working copy)
@@ -686,7 +686,100 @@
 	return ret_error;
 }
 
+ret_t
+cherokee_socket_write_pass_fd (cherokee_socket_t *socket, cherokee_connection_t *client,
+                       const char        *buf,
+                       int                buf_len,
+                       size_t            *pcnt_written)
+{
+        ret_t   ret;
+        int     err;
+        ssize_t len;
+	
+	struct msghdr msg;
+	union {
+		struct cmsghdr cmsg;
+		char control [CMSG_SPACE (sizeof (int))];
+	} msg_control;
+	struct cmsghdr *cmsg;
+	struct iovec iov;
 
+        *pcnt_written = 0;
+
+        /* There must be something to send, otherwise behaviour is undefined
+         * and as we don't want this case, we have to enforce assertions.
+         */
+        return_if_fail (buf != NULL && buf_len > 0, ret_error);
+
+	iov.iov_base = (void *) buf;
+	iov.iov_len  = buf_len;
+
+	msg.msg_name    = NULL;
+	msg.msg_namelen = 0;
+	msg.msg_iov = &iov;
+	msg.msg_iovlen = 1;
+	msg.msg_flags   = 0;
+	msg.msg_control    = &msg_control;
+	msg.msg_controllen = sizeof (msg_control);
+	
+	cmsg = CMSG_FIRSTHDR (&msg);
+	cmsg->cmsg_len   = CMSG_LEN (sizeof (int));
+	cmsg->cmsg_level = SOL_SOCKET;
+	cmsg->cmsg_type  = SCM_RIGHTS;
+
+	memcpy(CMSG_DATA(cmsg), &client->socket.socket, sizeof(int));
+
+        do {
+        	len = sendmsg (SOCKET_FD(socket), &msg, 0);
+        } while ((len < 0) && (errno == EINTR));
+
+	if (likely (len > 0) ) {
+        	/* Return n. of bytes sent.
+                */
+		*pcnt_written = len;
+		cherokee_socket_close(socket);
+		cherokee_socket_close(&client->socket);
+                return ret_ok_and_sent;
+	}
+
+        if (len == 0) {
+        	/* Very strange, socket is ready but nothing
+                * has been written, retry later.
+                */
+		return ret_eagain;
+	}
+
+                /* Error handling
+                 */
+                err = SOCK_ERRNO();
+
+                switch (err) {
+#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
+                case EWOULDBLOCK:
+#endif
+                case EAGAIN:
+                        return ret_eagain;
+
+                case EPIPE:
+                case ECONNRESET:
+#ifdef ENOTCONN
+                case ENOTCONN:
+#endif
+                        socket->status = socket_closed;
+                case ETIMEDOUT:
+                case EHOSTUNREACH:
+                        return ret_error;
+                }
+
+                LOG_ERRNO (errno, cherokee_err_error,
+                           CHEROKEE_ERROR_SOCKET_WRITE, SOCKET_FD(socket));
+
+	return ret_error;
+
+}
+
+
+
 /* WARNING: all parameters MUST be valid,
  *          NULL pointers lead to a crash.
  */
@@ -1011,7 +1104,20 @@
 	return ret;
 }
 
+ret_t
+cherokee_socket_bufwrite_pass_fd (cherokee_socket_t *socket, cherokee_connection_t *client, cherokee_buffer_t *buf, size_t *pcnt_written)
+{
+        ret_t  ret;
 
+        ret = cherokee_socket_write_pass_fd (socket, client, buf->buf, buf->len, pcnt_written);
+
+        TRACE (ENTRIES",bufwrite", "write_pass_fd fd=%d client_fd=%d len=%d ret=%d written=%u\n", socket->socket, client->socket, buf->len, ret, *pcnt_written);
+
+        return ret;
+}
+
+
+
 /* WARNING: all parameters MUST be valid,
  *          NULL pointers lead to a crash.
  */
Index: cherokee/socket.h
===================================================================
--- cherokee/socket.h	(revision 6364)
+++ cherokee/socket.h	(working copy)
@@ -172,6 +172,7 @@
 ret_t cherokee_socket_listen            (cherokee_socket_t *socket, int backlog);
 
 ret_t cherokee_socket_bufwrite          (cherokee_socket_t *socket, cherokee_buffer_t *buf, size_t *written);
+ret_t cherokee_socket_bufwrite_pass_fd  (cherokee_socket_t *socket, cherokee_connection_t *client, cherokee_buffer_t *buf, size_t *written);
 ret_t cherokee_socket_bufread           (cherokee_socket_t *socket, cherokee_buffer_t *buf, size_t count, size_t *read);
 ret_t cherokee_socket_sendfile          (cherokee_socket_t *socket, int fd, size_t size, off_t *offset, ssize_t *sent);
 ret_t cherokee_socket_connect           (cherokee_socket_t *socket);
@@ -186,6 +187,7 @@
  */
 ret_t cherokee_socket_read   (cherokee_socket_t *socket, char *buf, int buf_size, size_t *pcnt_read);
 ret_t cherokee_socket_write  (cherokee_socket_t *socket, const char *buf, int len, size_t *pcnt_written);
+ret_t cherokee_socket_write_pass_fd (cherokee_socket_t *socket, cherokee_connection_t *client, const char *buf, int len, size_t *pcnt_written);
 ret_t cherokee_socket_writev (cherokee_socket_t *socket, const struct iovec *vector, uint16_t vector_len, size_t *pcnt_written);
 
 /* Extra
Index: admin/plugins/uwsgi.py
===================================================================
--- admin/plugins/uwsgi.py	(revision 6364)
+++ admin/plugins/uwsgi.py	(working copy)
@@ -33,6 +33,8 @@
 
 HELPS = CgiBase.HELPS + [('modules_handlers_uwsgi', "UWSGI")]
 
+NOTE_PASS_FD        = N_('Allow passing of file descriptors via UNIX socket.')
+
 class Plugin_uwsgi (CgiBase.PluginHandlerCGI):
     def __init__ (self, key, **kwargs):
         kwargs['show_script_alias']  = False
@@ -45,9 +47,19 @@
 
         # Balancer
         modul = CTK.PluginSelector('%s!balancer'%(key), trans_options(Cherokee.support.filter_available (BALANCERS)))
+
         table = CTK.PropsTable()
         table.Add (_("Balancer"), modul.selector_widget, _(Balancer.NOTE_BALANCER))
 
         self += CTK.RawHTML ('<h2>%s</h2>' %(_('UWSGI Specific')))
+
+	submit = CTK.Submitter (URL_APPLY)
+	table2 = CTK.PropsTable()
+	table2.Add (_('Pass file descriptor'),     CTK.CheckCfgText('%s!pass_fd'%(key),        False, _('Enabled')), _(NOTE_PASS_FD))
+	submit += CTK.Indenter (table2)
+
+	self += submit
+
         self += CTK.Indenter (table)
         self += modul
+
