This would make it possible to use Fossil with Inetd like servers on Windows, for example

The following patch against Fossil version [0eb08b860c] implements this functionality:

<verbatim>
diff -Naur
--- 2009-09-13 09:37:48 +0000
+++ 2009-09-17 11:25:47 +0000
@@ -29,10 +29,11 @@
 */
 #include "config.h"
 #ifdef __MINGW32__
-#  include <windows.h>           /* for Sleep once server works again */
-#  include <winsock2.h>          /* socket operations */
-#  define sleep Sleep            /* windows does not have sleep, but Sleep */
-#  include <ws2tcpip.h>
+#  include <windows.h>           /* Windows specific declarations */
+#  include <winsock2.h>          /* Windows socket operations */
+#  include <ws2tcpip.h>          /* for socklen_t */
+#  include <fcntl.h>
+#  include <io.h>
 #else
 #  include <sys/socket.h>
 #  include <netinet/in.h>
@@ -1076,6 +1077,95 @@
   return zResult;
 }

+#ifdef __MINGW32__
+/*
+** Data structure related to all variables for the windows socket environment.
+*/
+typedef struct WinSocketData {
+  int     fWSAInit;       /* True, if Windows sockets initialized */
+  SOCKET  hSocket;        /* Handle to the socket */
+} WinSocketData;
+
+static WinSocketData wsd;
+
+/*
+** Exit handler routine. Make sure any remaining output gets flushed to the
+** output stream. If the standard handles are redirected to a socket then
+** make shure the socket gets closed properly and clean up the windows socket
+** environment.
+*/
+static void cgi_handle_http_request_exit(void)
+{
+  fflush(g.httpOut);
+
+  if( wsd.hSocket != INVALID_SOCKET ){
+    shutdown(wsd.hSocket, SD_BOTH);
+    closesocket(wsd.hSocket);
+  }
+  if (wsd.fWSAInit) {
+    WSACleanup();
+  }
+  return;
+}
+
+/*
+** This routine initalizes the environment on windows for the
+** cgi_handle_http_request routine. It sets the standard input and ouput
+** handles to binary mode, initalizes the windows socket environment and tries
+** to get the socket handle from the standard handles. It also establishs a
+** exit routine to clean up on program exit.
+*/
+void cgi_handle_http_request_init(void)
+{
+  WSADATA wd;
+  SOCKET hSock;
+  int socket_type;
+  int socket_type_len = sizeof(socket_type);
+
+  /*
+  ** Initialize the windows socket data structure.
+  */
+  wsd.fWSAInit = 0;
+  wsd.hSocket = INVALID_SOCKET;
+
+  /*
+  ** Register the exit function.
+  */
+  atexit(cgi_handle_http_request_exit);
+
+  /*
+  ** Set the mode of the http input and output streams to binary.
+  */
+  _setmode(_fileno(g.httpIn),  _O_BINARY);
+  _setmode(_fileno(g.httpOut), _O_BINARY);
+
+  /*
+  ** Initialize the windows socket API. This is required if we need to
+  ** call any other Windows Socket function.
+  */
+  if( WSAStartup(MAKEWORD(2,2), &wd) == 0 ) wsd.fWSAInit = 1;
+
+  /*
+  ** Windows Socket handles must be handled differently than file handles.
+  ** There is no function to detect if a file handle is a socket or not, so
+  ** lets call a socket function with the handle from stdin, and if there is
+  ** no error, assume it is a socket!
+  */
+  if( wsd.fWSAInit ){
+    hSock = (SOCKET)_get_osfhandle(_fileno(stdin));
+    if( getsockopt (hSock, SOL_SOCKET, SO_TYPE,
+                    (char *)&socket_type, &socket_type_len) == 0 ){
+      wsd.hSocket = hSock;
+    }
+  }
+  return;
+}
+
+#  define CGI_SOCKET wsd.hSocket
+#else
+#  define CGI_SOCKET fileno(g.httpIn)
+#endif /* __MINGW32__ */
+
 /*
 ** This routine handles a single HTTP request which is coming in on
 ** standard input and which replies on standard output.
@@ -1092,6 +1182,9 @@
   size_t size = sizeof(struct sockaddr_in);
   char zLine[2000];     /* A single line of input. */

+#ifdef __MINGW32__
+  cgi_handle_http_request_init();
+#endif
   g.fullHttpReply = 1;
   if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){
     malformed_request();
@@ -1116,7 +1209,7 @@
   cgi_setenv("PATH_INFO", zToken);
   cgi_setenv("QUERY_STRING", &zToken[i]);
   if( zIpAddr==0 &&
-        getpeername(fileno(g.httpIn), (struct sockaddr*)&remoteName,
+        getpeername(CGI_SOCKET, (struct sockaddr*)&remoteName,
                                 (socklen_t*)&size)>=0
   ){
     zIpAddr = inet_ntoa(remoteName.sin_addr);
</verbatim>

--tsbg