Ticket Change Details
Not logged in

Changes to ticket 2384764107

By anonymous on 2009-09-17 14:08:24. See also: artifact content, and ticket history

    1. Change comment to "This would make it possible to use Fossil with Inetd like servers on Windows, for example [http://www.xmailserver.org/wininetd.html]. The following patch against Fossil version [0eb08b860c] implements this functionality: <verbatim> diff -Naur fossil-src/src/cgi.c fossil-src-mod/src/cgi.c --- fossil-src/src/cgi.c 2009-09-13 09:37:48 +0000 +++ fossil-src-mod/src/cgi.c 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"
    2. Change foundin to "0eb08b860c"
    3. Change private_contact to "76518fb407f147a1d053c00b5b993281a339c0e3"
    4. Change severity to "Important"
    5. Change status to "Open"
    6. Change title to "Make the http command working on Windows."
    7. Change type to "Feature_Request"