Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Enhancements to unix-domain socket support for "fossil server": (1) Change the command-line option to "--socket-name FILENAME" for creating the unix socket. (It was formerly --unix-socket.) (2) Add new command-line options "--socket-mode MODE" and "--socket-owner USER" or "... USER:GROUP" to set permissions and ownership on the new socket. (3) Attempt to unlink the socket from the filesystem upon exit. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
effdadadd0cbef4ef987e87b51d8962f |
User & Date: | drh 2024-08-06 20:39:34.515 |
Context
2024-08-06
| ||
22:35 | The new zebra-striped table styling in the default skin was not targeting /wiki docs, only .wiki embedded docs, leaving them unstyled. ... (check-in: 072a8609 user: wyoung tags: trunk) | |
20:39 | Enhancements to unix-domain socket support for "fossil server": (1) Change the command-line option to "--socket-name FILENAME" for creating the unix socket. (It was formerly --unix-socket.) (2) Add new command-line options "--socket-mode MODE" and "--socket-owner USER" or "... USER:GROUP" to set permissions and ownership on the new socket. (3) Attempt to unlink the socket from the filesystem upon exit. ... (check-in: effdadad user: drh tags: trunk) | |
20:36 | Get the build working on Windows again. ... (Closed-Leaf check-in: d474c95d user: drh tags: unix-sockets) | |
2024-08-05
| ||
20:23 | Add the --unix-socket option to the "fossil server" command. ... (check-in: 7fc29021 user: drh tags: trunk) | |
Changes
Changes to src/cgi.c.
︙ | ︙ | |||
2475 2476 2477 2478 2479 2480 2481 | */ #define HTTP_SERVER_LOCALHOST 0x0001 /* Bind to 127.0.0.1 only */ #define HTTP_SERVER_SCGI 0x0002 /* SCGI instead of HTTP */ #define HTTP_SERVER_HAD_REPOSITORY 0x0004 /* Was the repository open? */ #define HTTP_SERVER_HAD_CHECKOUT 0x0008 /* Was a checkout open? */ #define HTTP_SERVER_REPOLIST 0x0010 /* Allow repo listing */ #define HTTP_SERVER_NOFORK 0x0020 /* Do not call fork() */ | | | 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 | */ #define HTTP_SERVER_LOCALHOST 0x0001 /* Bind to 127.0.0.1 only */ #define HTTP_SERVER_SCGI 0x0002 /* SCGI instead of HTTP */ #define HTTP_SERVER_HAD_REPOSITORY 0x0004 /* Was the repository open? */ #define HTTP_SERVER_HAD_CHECKOUT 0x0008 /* Was a checkout open? */ #define HTTP_SERVER_REPOLIST 0x0010 /* Allow repo listing */ #define HTTP_SERVER_NOFORK 0x0020 /* Do not call fork() */ #define HTTP_SERVER_UNIXSOCKET 0x0040 /* Use a unix-domain socket */ #endif /* INTERFACE */ /* ** Maximum number of child processes that we can have running ** at one time. Set this to 0 for "no limit". */ |
︙ | ︙ | |||
2522 2523 2524 2525 2526 2527 2528 | struct sockaddr_in inaddr; /* The socket address */ struct sockaddr_un uxaddr; /* The address for unix-domain sockets */ int opt = 1; /* setsockopt flag */ int rc; /* Result code from system calls */ int iPort = mnPort; /* Port to try to use */ while( iPort<=mxPort ){ | | > > | | | | > | > > > | > | > > > > > > > > > | > > > > < | | | > | > > > > > > > | | | | | | | 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 | struct sockaddr_in inaddr; /* The socket address */ struct sockaddr_un uxaddr; /* The address for unix-domain sockets */ int opt = 1; /* setsockopt flag */ int rc; /* Result code from system calls */ int iPort = mnPort; /* Port to try to use */ while( iPort<=mxPort ){ if( flags & HTTP_SERVER_UNIXSOCKET ){ /* Initialize a Unix socket named g.zSockName */ assert( g.zSockName!=0 ); memset(&uxaddr, 0, sizeof(uxaddr)); if( strlen(g.zSockName)>sizeof(uxaddr.sun_path) ){ fossil_fatal("name of unix socket too big: %s\nmax size: %d\n", g.zSockName, (int)sizeof(uxaddr.sun_path)); } if( file_isdir(g.zSockName, ExtFILE)!=0 ){ if( !file_issocket(g.zSockName) ){ fossil_fatal("cannot name socket \"%s\" because another object" " with that name already exists", g.zSockName); }else{ unlink(g.zSockName); } } uxaddr.sun_family = AF_UNIX; strncpy(uxaddr.sun_path, g.zSockName, sizeof(uxaddr.sun_path)-1); listener = socket(AF_UNIX, SOCK_STREAM, 0); if( listener<0 ){ fossil_fatal("unable to create a unix socket named %s", g.zSockName); } /* Set the access permission for the new socket. Default to 0660. ** But use an alternative specified by --socket-mode if available. ** Do this before bind() to avoid a race condition. */ if( g.zSockMode ){ file_set_mode(g.zSockName, listener, g.zSockMode, 0); }else{ file_set_mode(g.zSockName, listener, "0660", 1); } }else{ /* Initialize a TCP/IP socket on port iPort */ memset(&inaddr, 0, sizeof(inaddr)); inaddr.sin_family = AF_INET; if( zIpAddr ){ inaddr.sin_addr.s_addr = inet_addr(zIpAddr); if( inaddr.sin_addr.s_addr == INADDR_NONE ){ fossil_fatal("not a valid IP address: %s", zIpAddr); } }else if( flags & HTTP_SERVER_LOCALHOST ){ inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); }else{ inaddr.sin_addr.s_addr = htonl(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( flags & HTTP_SERVER_UNIXSOCKET ){ rc = bind(listener, (struct sockaddr*)&uxaddr, sizeof(uxaddr)); /* Set the owner of the socket if requested by --socket-owner. This ** must wait until after bind(), after the filesystem object has been ** created. See https://lkml.org/lkml/2004/11/1/84 and ** https://fossil-scm.org/forum/forumpost/7517680ef9684c57 */ if( g.zSockOwner ){ file_set_owner(g.zSockName, listener, g.zSockOwner); } }else{ rc = bind(listener, (struct sockaddr*)&inaddr, sizeof(inaddr)); } if( rc<0 ){ close(listener); iPort++; continue; } break; } if( iPort>mxPort ){ if( flags & HTTP_SERVER_UNIXSOCKET ){ fossil_fatal("unable to listen on unix socket %s", zIpAddr); }else if( mnPort==mxPort ){ fossil_fatal("unable to open listening socket on port %d", mnPort); }else{ fossil_fatal("unable to open listening socket on any" " port in the range %d..%d", mnPort, mxPort); } } if( iPort>mxPort ) return 1; listen(listener,10); if( flags & HTTP_SERVER_UNIXSOCKET ){ fossil_print("Listening for %s requests on unix socket %s\n", (flags & HTTP_SERVER_SCGI)!=0 ? "SCGI" : g.httpUseSSL?"TLS-encrypted HTTPS":"HTTP", g.zSockName); }else{ fossil_print("Listening for %s requests on TCP port %d\n", (flags & HTTP_SERVER_SCGI)!=0 ? "SCGI" : g.httpUseSSL?"TLS-encrypted HTTPS":"HTTP", iPort); } fflush(stdout); if( zBrowser && (flags & HTTP_SERVER_UNIXSOCKET)==0 ){ assert( strstr(zBrowser,"%d")!=0 ); zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort); #if defined(__CYGWIN__) /* On Cygwin, we can do better than "echo" */ if( fossil_strncmp(zBrowser, "echo ", 5)==0 ){ wchar_t *wUrl = fossil_utf8_to_unicode(zBrowser+5); wUrl[wcslen(wUrl)-2] = 0; /* Strip terminating " &" */ |
︙ | ︙ |
Changes to src/file.c.
︙ | ︙ | |||
32 33 34 35 36 37 38 39 40 41 42 43 44 45 | */ #ifdef _WIN32 # include <direct.h> # include <windows.h> # include <sys/utime.h> #else # include <sys/time.h> #endif #if INTERFACE /* Many APIs take an eFType argument which must be one of ExtFILE, RepoFILE, ** or SymFILE. ** | > > | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | */ #ifdef _WIN32 # include <direct.h> # include <windows.h> # include <sys/utime.h> #else # include <sys/time.h> # include <pwd.h> # include <grp.h> #endif #if INTERFACE /* Many APIs take an eFType argument which must be one of ExtFILE, RepoFILE, ** or SymFILE. ** |
︙ | ︙ | |||
227 228 229 230 231 232 233 234 235 236 237 238 239 240 | /* ** Return TRUE if the named file is an ordinary file. Return false ** for directories, devices, fifos, symlinks, etc. */ int file_isfile(const char *zFilename, int eFType){ return getStat(zFilename, eFType) ? 0 : S_ISREG(fx.fileStat.st_mode); } /* ** Create a symbolic link named zLinkFile that points to zTargetFile. ** ** If allow-symlinks is off, create an ordinary file named zLinkFile ** with the name of zTargetFile as its content. **/ | > > > > > > > > > > | 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | /* ** Return TRUE if the named file is an ordinary file. Return false ** for directories, devices, fifos, symlinks, etc. */ int file_isfile(const char *zFilename, int eFType){ return getStat(zFilename, eFType) ? 0 : S_ISREG(fx.fileStat.st_mode); } /* ** Return TRUE if zFilename is a socket. */ int file_issocket(const char *zFilename){ if( getStat(zFilename, ExtFILE) ){ return 0; /* stat() failed. Return false. */ } return S_ISSOCK(fx.fileStat.st_mode); } /* ** Create a symbolic link named zLinkFile that points to zTargetFile. ** ** If allow-symlinks is off, create an ordinary file named zLinkFile ** with the name of zTargetFile as its content. **/ |
︙ | ︙ | |||
711 712 713 714 715 716 717 718 719 720 721 722 723 724 | iMTime = db_int64(0, "SELECT strftime('%%s',%Q)", g.argv[3]); zFile = g.argv[2]; file_set_mtime(zFile, iMTime); iMTime = file_mtime(zFile, RepoFILE); zDate = db_text(0, "SELECT datetime(%lld, 'unixepoch')", iMTime); fossil_print("Set mtime of \"%s\" to %s (%lld)\n", zFile, zDate, iMTime); } /* ** Delete a file. ** ** If zFilename is a symbolic link, then it is the link itself that is ** removed, not the object that zFilename points to. ** | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 | iMTime = db_int64(0, "SELECT strftime('%%s',%Q)", g.argv[3]); zFile = g.argv[2]; file_set_mtime(zFile, iMTime); iMTime = file_mtime(zFile, RepoFILE); zDate = db_text(0, "SELECT datetime(%lld, 'unixepoch')", iMTime); fossil_print("Set mtime of \"%s\" to %s (%lld)\n", zFile, zDate, iMTime); } /* ** Change access permissions on a file. */ void file_set_mode(const char *zFN, int fd, const char *zMode, int bNoErr){ #if !defined(_WIN32) mode_t m; char *zEnd = 0; m = strtol(zMode, &zEnd, 0); if( (zEnd[0] || fchmod(fd, m)) && !bNoErr ){ fossil_fatal("cannot change permissions on %s to \"%s\"", zFN, zMode); } #endif } /* Change the owner of a file to zOwner. zOwner can be of the form ** USER:GROUP. */ void file_set_owner(const char *zFN, int fd, const char *zOwner){ #if !defined(_WIN32) const char *zGrp; const char *zUsr = zOwner; struct passwd *pw; struct group *grp; uid_t uid = -1; gid_t gid = -1; zGrp = strchr(zUsr, ':'); if( zGrp ){ int n = (int)(zGrp - zUsr); zUsr = fossil_strndup(zUsr, n); zGrp++; } pw = getpwnam(zUsr); if( pw==0 ){ fossil_fatal("no such user: \"%s\"", zUsr); } uid = pw->pw_uid; if( zGrp ){ grp = getgrnam(zGrp); if( grp==0 ){ fossil_fatal("no such group: \"%s\"", zGrp); } gid = grp->gr_gid; } if( chown(zFN, uid, gid) ){ fossil_fatal("cannot change ownership of %s to %s",zFN, zOwner); } if( zOwner!=zUsr ){ fossil_free((char*)zUsr); } #endif } /* ** Delete a file. ** ** If zFilename is a symbolic link, then it is the link itself that is ** removed, not the object that zFilename points to. ** |
︙ | ︙ | |||
1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 | z = db_text(0, "SELECT datetime(%lld, 'unixepoch')", iMtime); sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld (%s)", iMtime, z); fossil_free(z); fossil_print(" file_mtime(ExtFILE) = %s\n", zBuf); fossil_print(" file_mode(ExtFILE) = 0%o\n", file_mode(zPath,ExtFILE)); fossil_print(" file_isfile(ExtFILE) = %d\n", file_isfile(zPath,ExtFILE)); fossil_print(" file_isdir(ExtFILE) = %d\n", file_isdir(zPath,ExtFILE)); if( reset ) resetStat(); sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_size(zPath,RepoFILE)); fossil_print(" file_size(RepoFILE) = %s\n", zBuf); iMtime = file_mtime(zPath,RepoFILE); z = db_text(0, "SELECT datetime(%lld, 'unixepoch')", iMtime); sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld (%s)", iMtime, z); fossil_free(z); | > | 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 | z = db_text(0, "SELECT datetime(%lld, 'unixepoch')", iMtime); sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld (%s)", iMtime, z); fossil_free(z); fossil_print(" file_mtime(ExtFILE) = %s\n", zBuf); fossil_print(" file_mode(ExtFILE) = 0%o\n", file_mode(zPath,ExtFILE)); fossil_print(" file_isfile(ExtFILE) = %d\n", file_isfile(zPath,ExtFILE)); fossil_print(" file_isdir(ExtFILE) = %d\n", file_isdir(zPath,ExtFILE)); fossil_print(" file_issocket() = %d\n", file_issocket(zPath)); if( reset ) resetStat(); sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_size(zPath,RepoFILE)); fossil_print(" file_size(RepoFILE) = %s\n", zBuf); iMtime = file_mtime(zPath,RepoFILE); z = db_text(0, "SELECT datetime(%lld, 'unixepoch')", iMtime); sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld (%s)", iMtime, z); fossil_free(z); |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
236 237 238 239 240 241 242 243 244 245 246 247 248 249 | #endif int useLocalauth; /* No login required if from 127.0.0.1 */ int noPswd; /* Logged in without password (on 127.0.0.1) */ int userUid; /* Integer user id */ int isHuman; /* True if access by a human, not a spider or bot */ int comFmtFlags; /* Zero or more "COMMENT_PRINT_*" bit flags, should be ** accessed through get_comment_format(). */ /* Information used to populate the RCVFROM table */ int rcvid; /* The rcvid. 0 if not yet defined. */ char *zIpAddr; /* The remote IP address */ char *zNonce; /* The nonce used for login */ /* permissions available to current user */ | > > > | 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | #endif int useLocalauth; /* No login required if from 127.0.0.1 */ int noPswd; /* Logged in without password (on 127.0.0.1) */ int userUid; /* Integer user id */ int isHuman; /* True if access by a human, not a spider or bot */ int comFmtFlags; /* Zero or more "COMMENT_PRINT_*" bit flags, should be ** accessed through get_comment_format(). */ const char *zSockName; /* Name of the unix-domain socket file */ const char *zSockMode; /* File permissions for unix-domain socket */ const char *zSockOwner; /* Owner, or owner:group for unix-domain socket */ /* Information used to populate the RCVFROM table */ int rcvid; /* The rcvid. 0 if not yet defined. */ char *zIpAddr; /* The remote IP address */ char *zNonce; /* The nonce used for login */ /* permissions available to current user */ |
︙ | ︙ | |||
389 390 391 392 393 394 395 396 397 398 399 400 401 402 | ** exiting the process. This issue does not impact 64-bit Windows. */ unloadTcl(g.interp, &g.tcl); #endif #ifdef FOSSIL_ENABLE_JSON cson_value_free(g.json.gc.v); memset(&g.json, 0, sizeof(g.json)); #endif free(g.zErrMsg); if(g.db){ db_close(0); } manifest_clear_cache(); content_clear_cache(1); | > > > > > | 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 | ** exiting the process. This issue does not impact 64-bit Windows. */ unloadTcl(g.interp, &g.tcl); #endif #ifdef FOSSIL_ENABLE_JSON cson_value_free(g.json.gc.v); memset(&g.json, 0, sizeof(g.json)); #endif #if !defined(_WIN32) if( g.zSockName && file_issocket(g.zSockName) ){ unlink(g.zSockName); } #endif free(g.zErrMsg); if(g.db){ db_close(0); } manifest_clear_cache(); content_clear_cache(1); |
︙ | ︙ | |||
1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 | static char *enter_chroot_jail(const char *zRepo, int noJail){ #if !defined(_WIN32) if( getuid()==0 ){ int i; struct stat sStat; Blob dir; char *zDir; if( g.db!=0 ){ db_close(1); } file_canonical_name(zRepo, &dir, 0); zDir = blob_str(&dir); if( !noJail ){ if( file_isdir(zDir, ExtFILE)==1 ){ if( g.zRepositoryName ){ | > > > < | | > > > > > > > > > > > > | 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 | static char *enter_chroot_jail(const char *zRepo, int noJail){ #if !defined(_WIN32) if( getuid()==0 ){ int i; struct stat sStat; Blob dir; char *zDir; size_t nDir; if( g.db!=0 ){ db_close(1); } file_canonical_name(zRepo, &dir, 0); zDir = blob_str(&dir); nDir = blob_size(&dir); if( !noJail ){ if( file_isdir(zDir, ExtFILE)==1 ){ /* Translate the repository name to the new root */ if( g.zRepositoryName ){ Blob repo; file_canonical_name(g.zRepositoryName, &repo, 0); zRepo = blob_str(&repo); if( strncmp(zRepo, zDir, nDir)!=0 ){ fossil_fatal("repo %s not under chroot dir %s", zRepo, zDir); } zRepo += nDir; if( *zRepo == '\0' ) zRepo = "/"; }else { zRepo = "/"; } /* If a unix socket is defined, try to translate its name into ** the new root so that it can be delete by atexit(). If unable, ** just zero out the socket name. */ if( g.zSockName ){ if( strncmp(g.zSockName, zDir, nDir)==0 && g.zSockName[nDir]=='/' ){ g.zSockName += nDir; }else{ g.zSockName = 0; } } if( file_chdir(zDir, 1) ){ fossil_panic("unable to chroot into %s", zDir); } }else{ for(i=strlen(zDir)-1; i>0 && zDir[i]!='/'; i--){} if( zDir[i]!='/' ) fossil_fatal("bad repository name: %s", zRepo); |
︙ | ︙ | |||
3183 3184 3185 3186 3187 3188 3189 | ** -p|--page PAGE Start "ui" on PAGE. ex: --page "timeline?y=ci" ** --pkey FILE Read the private key used for TLS from FILE ** -P|--port [IP:]PORT Listen on the given IP (optional) and port ** --repolist If REPOSITORY is dir, URL "/" lists repos ** --scgi Accept SCGI rather than HTTP ** --skin LABEL Use override skin LABEL, or the site's default skin if ** LABEL is an empty string. | > | | | > > > > | 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 | ** -p|--page PAGE Start "ui" on PAGE. ex: --page "timeline?y=ci" ** --pkey FILE Read the private key used for TLS from FILE ** -P|--port [IP:]PORT Listen on the given IP (optional) and port ** --repolist If REPOSITORY is dir, URL "/" lists repos ** --scgi Accept SCGI rather than HTTP ** --skin LABEL Use override skin LABEL, or the site's default skin if ** LABEL is an empty string. ** --socket-mode MODE File permissions to set for the unix socket created ** by the --socket-name option. ** --socket-name NAME Use a unix-domain socket called NAME instead of a ** TCP/IP socket. ** --socket-owner USR Try to set the owner of the unix socket to USR. ** USR can be of the form USER:GROUP to set both ** user and group. ** --th-trace Trace TH1 execution (for debugging purposes) ** --usepidkey Use saved encryption key from parent process. This is ** only necessary when using SEE on Windows or Linux. ** ** See also: [[cgi]], [[http]], [[winsrv]] */ void cmd_webserver(void){ int iPort, mxPort; /* Range of TCP ports allowed */ |
︙ | ︙ | |||
3283 3284 3285 3286 3287 3288 3289 | } g.zCkoutAlias = find_option("ckout-alias",0,1); g.zMainMenuFile = find_option("mainmenu",0,1); if( g.zMainMenuFile!=0 && file_size(g.zMainMenuFile,ExtFILE)<0 ){ fossil_fatal("Cannot read --mainmenu file %s", g.zMainMenuFile); } if( find_option("acme",0,0)!=0 ) g.fAllowACME = 1; | | > > | | | 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 | } g.zCkoutAlias = find_option("ckout-alias",0,1); g.zMainMenuFile = find_option("mainmenu",0,1); if( g.zMainMenuFile!=0 && file_size(g.zMainMenuFile,ExtFILE)<0 ){ fossil_fatal("Cannot read --mainmenu file %s", g.zMainMenuFile); } if( find_option("acme",0,0)!=0 ) g.fAllowACME = 1; g.zSockMode = find_option("socket-mode",0,1); g.zSockName = find_option("socket-name",0,1); g.zSockOwner = find_option("socket-owner",0,1); if( g.zSockName ){ #if defined(_WIN32) fossil_fatal("unix sockets are not supported on Windows"); #endif if( zPort ){ fossil_fatal("cannot specify a port number for a unix socket"); } if( isUiCmd && !fNoBrowser ){ fossil_fatal("cannot start a web-browser on a unix socket"); } flags |= HTTP_SERVER_UNIXSOCKET; } /* Undocumented option: --debug-nofork ** ** This sets the HTTP_SERVER_NOFORK flag, which causes only the ** very first incoming TCP/IP connection to be processed. Used for ** debugging, since debugging across a fork() can be tricky |
︙ | ︙ | |||
3465 3466 3467 3468 3469 3470 3471 | fossil_free(zBrowserCmd); return; } if( g.repositoryOpen ) flags |= HTTP_SERVER_HAD_REPOSITORY; if( g.localOpen ) flags |= HTTP_SERVER_HAD_CHECKOUT; db_close(1); #if !defined(_WIN32) | | | 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 | fossil_free(zBrowserCmd); return; } if( g.repositoryOpen ) flags |= HTTP_SERVER_HAD_REPOSITORY; if( g.localOpen ) flags |= HTTP_SERVER_HAD_CHECKOUT; db_close(1); #if !defined(_WIN32) if( 1 ){ /* Modern kernels suppress SIGTERM to PID 1 to prevent root from ** rebooting the system by nuking the init system. The only way ** Fossil becomes that PID 1 is when it's running solo in a Linux ** container or similar, so we do want to exit immediately, to ** allow the container to shut down quickly. ** ** This has to happen ahead of the other signal() calls below. |
︙ | ︙ | |||
3488 3489 3490 3491 3492 3493 3494 | /* Start up an HTTP server */ fossil_setenv("SERVER_SOFTWARE", "fossil version " RELEASE_VERSION " " MANIFEST_VERSION " " MANIFEST_DATE); #if !defined(_WIN32) /* Unix implementation */ if( cgi_http_server(iPort, mxPort, zBrowserCmd, zIpAddr, flags) ){ | | | 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 | /* Start up an HTTP server */ fossil_setenv("SERVER_SOFTWARE", "fossil version " RELEASE_VERSION " " MANIFEST_VERSION " " MANIFEST_DATE); #if !defined(_WIN32) /* Unix implementation */ if( cgi_http_server(iPort, mxPort, zBrowserCmd, zIpAddr, flags) ){ fossil_fatal("unable to listen on CGI socket"); } /* For the parent process, the cgi_http_server() command above never ** returns (except in the case of an error). Instead, for each incoming ** client connection, a child process is created, file descriptors 0 ** and 1 are bound to that connection, and the child returns. ** ** So, when control reaches this point, we are running as a |
︙ | ︙ |