Overview
SHA1 Hash: | d8ceb4ad476342bedd30559eb679a7118a8833a2 |
---|---|
Date: | 2008-11-10 01:13:35 |
User: | drh |
Comment: | The "ui" and "server" commands no longer quit if they cannot open TCP port 8080. They keep trying with consecutive ports until they find one that works - up to 100 ports. |
Timelines: | ancestors | descendants | both | trunk |
Other Links: | files | ZIP archive | manifest |
Tags And Properties
- branch=trunk inherited from [a28c83647d]
- sym-trunk inherited from [a28c83647d]
Changes
[hide diffs]Modified src/cgi.c from [ec3c5c4267] to [40d3404d8c].
@@ -1182,13 +1182,13 @@ ** The parent never returns from this procedure. ** ** Return 0 to each child as it runs. If unable to establish a ** listening socket, return non-zero. */ -int cgi_http_server(int iPort, char *zBrowser){ +int cgi_http_server(int mnPort, int mxPort, char *zBrowser){ #ifdef __MINGW32__ - fprintf(stderr,"server not yet available in windows version of fossil\n"); + /* Use win32_http_server() instead */ exit(1); #else int listener; /* The server socket */ int connection; /* A socket for each individual connection */ fd_set readfds; /* Set of file descriptors for select() */ @@ -1196,29 +1196,49 @@ int child; /* PID of the child process */ int nchildren = 0; /* Number of child processes */ struct timeval delay; /* How long to wait inside select() */ struct sockaddr_in inaddr; /* The socket address */ int opt = 1; /* setsockopt flag */ + int iPort = mnPort; + + while( iPort<mxPort ){ + memset(&inaddr, 0, sizeof(inaddr)); + inaddr.sin_family = AF_INET; + inaddr.sin_addr.s_addr = INADDR_ANY; + inaddr.sin_port = htons(iPort); + listener = socket(AF_INET, SOCK_STREAM, 0); + if( listener<0 ){ + iPort++; + continue; + } - memset(&inaddr, 0, sizeof(inaddr)); - inaddr.sin_family = AF_INET; - inaddr.sin_addr.s_addr = INADDR_ANY; - inaddr.sin_port = htons(iPort); - listener = socket(AF_INET, SOCK_STREAM, 0); - if( listener<0 ){ - return 1; - } + /* if we can't terminate nicely, at least allow the socket to be reused */ + setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); - /* if we can't terminate nicely, at least allow the socket to be reused */ - setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); - - if( bind(listener, (struct sockaddr*)&inaddr, sizeof(inaddr))<0 ){ - close(listener); - return 1; + if( bind(listener, (struct sockaddr*)&inaddr, sizeof(inaddr))<0 ){ + close(listener); + iPort++; + continue; + } + break; + } + if( iPort>mxPort ){ + if( mnPort==mxPort ){ + fossil_fatal("unable to open listening socket on ports %d", mnPort); + }else{ + fossil_fatal("unable to open listening socket on any" + " ports %d..%d", mnPort, mxPort); + } } + if( iPort>mxPort ) return 1; listen(listener,10); + if( iPort>mnPort ){ + printf("Listening for HTTP requests on TCP port %d\n", iPort); + fflush(stdout); + } if( zBrowser ){ + zBrowser = mprintf(zBrowser, iPort); system(zBrowser); } while( 1 ){ if( nchildren>MAX_PARALLEL ){ /* Slow down if connections are arriving too fast */
Modified src/main.c from [7ce5037b83] to [936fc223a3].
@@ -704,11 +704,11 @@ ** ** The "ui" command automatically starts a web browser after initializing ** the web server. */ void cmd_webserver(void){ - int iPort; + int iPort, mxPort; const char *zPort; char *zBrowser; char *zBrowserCmd = 0; g.thTrace = find_option("th-trace", 0, 0)!=0; @@ -721,26 +721,27 @@ db_must_be_within_tree(); }else{ db_open_repository(g.argv[2]); } if( zPort ){ - iPort = atoi(zPort); + iPort = mxPort = atoi(zPort); }else{ iPort = db_get_int("http-port", 8080); + mxPort = iPort+100; } #ifndef __MINGW32__ /* Unix implementation */ if( g.argv[1][0]=='u' ){ #if !defined(__DARWIN__) && !defined(__APPLE__) zBrowser = db_get("web-browser", "firefox"); #else zBrowser = db_get("web-browser", "open"); #endif - zBrowserCmd = mprintf("%s http://localhost:%d/ &", zBrowser, iPort); + zBrowserCmd = mprintf("%s http://localhost:%%d/ &", zBrowser); } db_close(); - if( cgi_http_server(iPort, zBrowserCmd) ){ + if( cgi_http_server(iPort, mxPort, zBrowserCmd) ){ fossil_fatal("unable to listen on TCP socket %d", iPort); } g.httpIn = stdin; g.httpOut = stdout; if( g.fHttpTrace ){ @@ -756,11 +757,11 @@ process_one_web_page(); #else /* Win32 implementation */ if( g.argv[1][0]=='u' ){ zBrowser = db_get("web-browser", "start"); - zBrowserCmd = mprintf("%s http://127.0.0.1:%d/", zBrowser, iPort); + zBrowserCmd = mprintf("%s http://127.0.0.1:%%d/", zBrowser); } db_close(); - win32_http_server(iPort, zBrowserCmd); + win32_http_server(iPort, mxPort, zBrowserCmd); #endif }
Modified src/winhttp.c from [572742e69b] to [dafbf1595e].
@@ -134,37 +134,52 @@ /* ** Start a listening socket and process incoming HTTP requests on ** that socket. */ -void win32_http_server(int iPort, char *zBrowser){ +void win32_http_server(int mnPort, int mxPort, char *zBrowser){ WSADATA wd; SOCKET s; SOCKADDR_IN addr; int idCnt = 0; + int iPort = mnPort; if( WSAStartup(MAKEWORD(1,1), &wd) ){ fossil_fatal("unable to initialize winsock"); } - zTempPrefix = mprintf("fossil_server_P%d_", iPort); - s = socket(AF_INET, SOCK_STREAM, 0); - if( s==INVALID_SOCKET ){ - fossil_fatal("unable to create a socket"); + while( iPort<mxPort ){ + s = socket(AF_INET, SOCK_STREAM, 0); + if( s==INVALID_SOCKET ){ + fossil_fatal("unable to create a socket"); + } + addr.sin_family = AF_INET; + addr.sin_port = htons(iPort); + addr.sin_addr.s_addr = htonl(INADDR_ANY); + if( bind(s, (struct sockaddr*)&addr, sizeof(addr))==SOCKET_ERROR ){ + closesocket(s); + iPort++; + continue; + } + if( listen(s, SOMAXCONN)==SOCKET_ERROR ){ + closesocket(s); + iPort++; + continue; + } + break; } - addr.sin_family = AF_INET; - addr.sin_port = htons(iPort); - addr.sin_addr.s_addr = htonl(INADDR_ANY); - if( bind(s, (struct sockaddr*)&addr, sizeof(addr))==SOCKET_ERROR ){ - closesocket(s); - fossil_fatal("unable to bind"); + if( iPort>mxPort ){ + if( mnPort==mxPort ){ + fossil_fatal("unable to open listening socket on ports %d", mnPort); + }else{ + fossil_fatal("unable to open listening socket on any" + " ports %d..%d", mnPort, mxPort); + } } - if( listen(s, SOMAXCONN)==SOCKET_ERROR ){ - closesocket(s); - fossil_fatal("unable to listen"); - } + zTempPrefix = mprintf("fossil_server_P%d_", iPort); printf("Listening for HTTP requests on TCP port %d\n", iPort); if( zBrowser ){ + zBrowser = mprintf(zBrowser, iPort); printf("Launch webbrowser: %s\n", zBrowser); system(zBrowser); } printf("Type Ctrl-C to stop the HTTP server\n"); for(;;){