Fossil

Check-in [d8ceb4ad47]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
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.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d8ceb4ad476342bedd30559eb679a7118a8833a2
User & Date: drh 2008-11-10 01:13:35.000
Context
2008-11-10
19:54
Add missing comma in CREATE TABLE vfile ... ... (check-in: c66ffba6da user: eric tags: trunk)
01:13
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. ... (check-in: d8ceb4ad47 user: drh tags: trunk)
00:40
Update to the latest SQLite. Add a Rebuild button on the Shun webpage. Add the test-detach CLI method. ... (check-in: 3f6edbc779 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/cgi.c.
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200

1201

1202
1203
1204
1205
1206
1207
1208

1209
1210
1211
1212
1213
1214
1215



1216
1217









1218




1219

1220
1221
1222
1223
1224
1225
1226
** As new connections arrive, fork a child and let child return
** out of this procedure call.  The child will handle the request.
** 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){
#ifdef __MINGW32__
  fprintf(stderr,"server not yet available in windows version of fossil\n");
  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() */
  size_t lenaddr;              /* Length of the inaddr structure */
  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 */



  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( bind(listener, (struct sockaddr*)&inaddr, sizeof(inaddr))<0 ){
    close(listener);



    return 1;
  }









  listen(listener,10);




  if( zBrowser ){

    system(zBrowser);
  }
  while( 1 ){
    if( nchildren>MAX_PARALLEL ){
      /* Slow down if connections are arriving too fast */
      sleep( nchildren-MAX_PARALLEL );
    }







|

|











>

>
|
|
|
|
|
|
|
>
|

|
|

|
|
>
>
>
|

>
>
>
>
>
>
>
>
>

>
>
>
>

>







1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
** As new connections arrive, fork a child and let child return
** out of this procedure call.  The child will handle the request.
** 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 mnPort, int mxPort, char *zBrowser){
#ifdef __MINGW32__
  /* 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() */
  size_t lenaddr;              /* Length of the inaddr structure */
  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;
    }

    /* 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);
      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 */
      sleep( nchildren-MAX_PARALLEL );
    }
Changes to src/main.c.
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728

729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
** The repository argument may be omitted if the working directory is
** within an open checkout.
**
** The "ui" command automatically starts a web browser after initializing
** the web server.
*/
void cmd_webserver(void){
  int iPort;
  const char *zPort;
  char *zBrowser;
  char *zBrowserCmd = 0;

  g.thTrace = find_option("th-trace", 0, 0)!=0;
  if( g.thTrace ){
    blob_zero(&g.thLog);
  }
  zPort = find_option("port", "P", 1);
  if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?");
  if( g.argc==2 ){
    db_must_be_within_tree();
  }else{
    db_open_repository(g.argv[2]);
  }
  if( zPort ){
    iPort = atoi(zPort);
  }else{
    iPort = db_get_int("http-port", 8080);

  }
#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);
  }
  db_close();
  if( cgi_http_server(iPort, zBrowserCmd) ){
    fossil_fatal("unable to listen on TCP socket %d", iPort);
  }
  g.httpIn = stdin;
  g.httpOut = stdout;
  if( g.fHttpTrace ){
    fprintf(stderr, "====== SERVER pid %d =======\n", getpid());
  }
  g.cgiPanic = 1;
  if( g.argc==2 ){
    db_must_be_within_tree();
  }else{
    db_open_repository(g.argv[2]);
  }
  cgi_handle_http_request(0);
  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);
  }
  db_close();
  win32_http_server(iPort, zBrowserCmd);
#endif
}







|
















|


>









|


|



















|


|


702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
** The repository argument may be omitted if the working directory is
** within an open checkout.
**
** The "ui" command automatically starts a web browser after initializing
** the web server.
*/
void cmd_webserver(void){
  int iPort, mxPort;
  const char *zPort;
  char *zBrowser;
  char *zBrowserCmd = 0;

  g.thTrace = find_option("th-trace", 0, 0)!=0;
  if( g.thTrace ){
    blob_zero(&g.thLog);
  }
  zPort = find_option("port", "P", 1);
  if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?");
  if( g.argc==2 ){
    db_must_be_within_tree();
  }else{
    db_open_repository(g.argv[2]);
  }
  if( 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);
  }
  db_close();
  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 ){
    fprintf(stderr, "====== SERVER pid %d =======\n", getpid());
  }
  g.cgiPanic = 1;
  if( g.argc==2 ){
    db_must_be_within_tree();
  }else{
    db_open_repository(g.argv[2]);
  }
  cgi_handle_http_request(0);
  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);
  }
  db_close();
  win32_http_server(iPort, mxPort, zBrowserCmd);
#endif
}
Changes to src/winhttp.c.
132
133
134
135
136
137
138
139
140
141
142
143

144
145
146
147
148
149
150
151
152
153
154
155
156
157

158
159
160
161









162

163


164
165

166
167
168
169
170
171
172
  free(p);
}

/*
** Start a listening socket and process incoming HTTP requests on
** that socket.
*/
void win32_http_server(int iPort, char *zBrowser){
  WSADATA wd;
  SOCKET s;
  SOCKADDR_IN addr;
  int idCnt = 0;


  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");
  }
  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( listen(s, SOMAXCONN)==SOCKET_ERROR ){
    closesocket(s);









    fossil_fatal("unable to listen");

  }


  printf("Listening for HTTP requests on TCP port %d\n", iPort);
  if( zBrowser ){

    printf("Launch webbrowser: %s\n", zBrowser);
    system(zBrowser);
  }
  printf("Type Ctrl-C to stop the HTTP server\n");
  for(;;){
    SOCKET client;
    SOCKADDR_IN client_addr;







|




>




|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
>
>
>
>
>
>
>
>
>
|
>
|
>
>


>







132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
  free(p);
}

/*
** Start a listening socket and process incoming HTTP requests on
** that socket.
*/
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");
  }
  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;
  }
  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);
    }
  }
  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(;;){
    SOCKET client;
    SOCKADDR_IN client_addr;