Changes On Branch panic-reduction
Not logged in

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

Changes In Branch panic-reduction Excluding Merge-Ins

This is equivalent to a diff from 19f4b064ac to 79be1156a9

2021-03-31
12:42
Merge reduction of fossil_panic() calls, for cleaner abnormal exits. check-in: 31c7bdb80b user: larrybr tags: trunk
10:57
Sync w/trunk. Closed-Leaf check-in: 79be1156a9 user: larrybr tags: panic-reduction
2021-03-28
05:14
Add example of fossil timeline + diff to get changes between specific versions check-in: 19f4b064ac user: danshearer tags: trunk
2021-03-27
16:04
/chat: removed the unused/unnecessary jump-to-top/bottom buttons. check-in: a044fea785 user: stephan tags: trunk
2021-03-26
17:53
Merge from trunk tip. check-in: 6e1cee191d user: larrybr tags: panic-reduction

Changes to src/bundle.c.
58
59
60
61
62
63
64
65

66
67
68
69
70
71
72
73
74
75
76
77
78

79
80
81
82
83
84
85

86
87
88
89
90
91
92
58
59
60
61
62
63
64

65
66
67
68
69
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84

85
86
87
88
89
90
91
92







-
+












-
+






-
+







  char *zErrMsg = 0;
  char *zSql;
  if( !doInit && file_size(zFile, ExtFILE)<0 ){
    fossil_fatal("no such file: %s", zFile);
  }
  assert( g.db );
  zSql = sqlite3_mprintf("ATTACH %Q AS %Q", zFile, zBName);
  if( zSql==0 ) fossil_panic("out of memory");
  if( zSql==0 ) fossil_fatal("out of memory");
  rc = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg);
  sqlite3_free(zSql);
  if( rc!=SQLITE_OK || zErrMsg ){
    if( zErrMsg==0 ) zErrMsg = (char*)sqlite3_errmsg(g.db);
    fossil_fatal("not a valid bundle: %s", zFile);
  }
  if( doInit ){
    db_multi_exec(zBundleInit /*works-like:"%w%w"*/, zBName, zBName);
  }else{
    sqlite3_stmt *pStmt;
    zSql = sqlite3_mprintf("SELECT bcname, bcvalue"
                           "  FROM \"%w\".bconfig", zBName);
    if( zSql==0 ) fossil_panic("out of memory");
    if( zSql==0 ) fossil_fatal("out of memory");
    rc = sqlite3_prepare(g.db, zSql, -1, &pStmt, 0);
    if( rc ) fossil_fatal("not a valid bundle: %s", zFile);
    sqlite3_free(zSql);
    sqlite3_finalize(pStmt);
    zSql = sqlite3_mprintf("SELECT blobid, uuid, sz, delta, notes, data"
                           "  FROM \"%w\".bblob", zBName);
    if( zSql==0 ) fossil_panic("out of memory");
    if( zSql==0 ) fossil_fatal("out of memory");
    rc = sqlite3_prepare(g.db, zSql, -1, &pStmt, 0);
    if( rc ) fossil_fatal("not a valid bundle: %s", zFile);
    sqlite3_free(zSql);
    sqlite3_finalize(pStmt);
  }
}

Changes to src/cgi.c.
1834
1835
1836
1837
1838
1839
1840
1841

1842
1843
1844
1845
1846
1847
1848
1834
1835
1836
1837
1838
1839
1840

1841
1842
1843
1844
1845
1846
1847
1848







-
+







#endif
  if( zIpAddr ){
    if( nCycles==0 ){
      cgi_setenv("REMOTE_ADDR", zIpAddr);
      g.zIpAddr = fossil_strdup(zIpAddr);
    }
  }else{
    fossil_panic("missing SSH IP address");
    fossil_fatal("missing SSH IP address");
  }
  if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){
    malformed_request("missing HTTP header");
  }
  cgi_trace(zLine);
  zToken = extract_token(zLine, &z);
  if( zToken==0 ){
Changes to src/db.c.
454
455
456
457
458
459
460
461

462
463
464
465
466

467
468
469
470
471
472
473
454
455
456
457
458
459
460

461
462
463
464
465

466
467
468
469
470
471
472
473







-
+




-
+







  if( db.nProtect<1 ){
    fossil_panic("too many db_protect_pop() calls");
  }
  db.protectMask = db.aProtect[--db.nProtect];
}

/*
** Verify that the desired database write pertections are in place.
** Verify that the desired database write protections are in place.
** Throw a fatal error if not.
*/
void db_assert_protected(unsigned flags){
  if( (flags & db.protectMask)!=flags ){
    fossil_panic("missing database write protection bits: %02x",
    fossil_fatal("missing database write protection bits: %02x",
                 flags & ~db.protectMask);
  }
}

/*
** Assert that either all protections are off (including PROTECT_BASELINE
** which is usually always enabled), or the setting named in the argument
1832
1833
1834
1835
1836
1837
1838
1839

1840
1841
1842
1843
1844
1845
1846
1832
1833
1834
1835
1836
1837
1838

1839
1840
1841
1842
1843
1844
1845
1846







-
+







    return mprintf("%s/fossil.db", zXdgHome);
  }

  /* The HOME variable is required in order to continue.
  */
  if( zHome==0 ){
    if( isOptional ) return 0;
    fossil_panic("cannot locate home directory - please set one of the "
    fossil_fatal("cannot locate home directory - please set one of the "
                 "FOSSIL_HOME, XDG_CONFIG_HOME, or HOME environment "
                 "variables");
  }

  /* Step 4: If $HOME/.config is a directory -> $HOME/.config/fossil.db
  */
  zXdgHome = mprintf("%s/.config", zHome);
1882
1883
1884
1885
1886
1887
1888
1889

1890
1891
1892
1893
1894
1895

1896
1897
1898
1899
1900
1901
1902
1882
1883
1884
1885
1886
1887
1888

1889
1890
1891
1892
1893
1894

1895
1896
1897
1898
1899
1900
1901
1902







-
+





-
+







    if( file_isdir(zHome, ExtFILE)==0 ){
      file_mkdir(zHome, ExtFILE, 0);
    }
    rc = file_access(zHome, W_OK);
    fossil_free(zHome);
    if( rc ){
      if( isOptional ) return 0;
      fossil_panic("home directory \"%s\" must be writeable", zHome);
      fossil_fatal("home directory \"%s\" must be writeable", zHome);
    }
    db_init_database(zDbName, zConfigSchema, (char*)0);
  }
  if( file_access(zDbName, W_OK) ){
    if( isOptional ) return 0;
    fossil_panic("configuration file %s must be writeable", zDbName);
    fossil_fatal("configuration file %s must be writeable", zDbName);
  }
  if( useAttach ){
    db_open_or_attach(zDbName, "configdb");
    g.dbConfig = 0;
  }else{
    g.dbConfig = db_open(zDbName);
    db_set_main_schemaname(g.dbConfig, "configdb");
Changes to src/file.c.
384
385
386
387
388
389
390
391

392
393
394

395
396
397
398
399
400
401
384
385
386
387
388
389
390

391
392
393

394
395
396
397
398
399
400
401







-
+


-
+







**
** If a problem is found, print a warning message (using fossil_warning())
** and return non-zero.  If everything is ok, return zero.
*/
int file_unsafe_in_tree_path(const char *zFile){
  int n;
  if( !file_is_absolute_path(zFile) ){
    fossil_panic("%s is not an absolute pathname",zFile);
    fossil_fatal("%s is not an absolute pathname",zFile);
  }
  if( fossil_strnicmp(g.zLocalRoot, zFile, (int)strlen(g.zLocalRoot)) ){
    fossil_panic("%s is not a prefix of %s", g.zLocalRoot, zFile);
    fossil_fatal("%s is not a prefix of %s", g.zLocalRoot, zFile);
  }
  n = file_nondir_objects_on_path(g.zLocalRoot, zFile);
  if( n ){
    fossil_warning("cannot write to %s because non-directory object %.*s"
                   " is in the way", zFile, n, zFile);
  }
  return n;
1146
1147
1148
1149
1150
1151
1152
1153

1154
1155

1156
1157
1158
1159
1160
1161
1162
1146
1147
1148
1149
1150
1151
1152

1153
1154

1155
1156
1157
1158
1159
1160
1161
1162







-
+

-
+







    nBuf = sizeof(zTemp);
  }
#ifdef _WIN32
  win32_getcwd(zBuf, nBuf);
#else
  if( getcwd(zBuf, nBuf-1)==0 ){
    if( errno==ERANGE ){
      fossil_panic("pwd too big: max %d", nBuf-1);
      fossil_fatal("pwd too big: max %d", nBuf-1);
    }else{
      fossil_panic("cannot find current working directory; %s",
      fossil_fatal("cannot find current working directory; %s",
                   strerror(errno));
    }
  }
#endif
  return zBuf==zTemp ? fossil_strdup(zBuf) : zBuf;
}

1821
1822
1823
1824
1825
1826
1827
1828

1829
1830
1831
1832
1833
1834
1835
1821
1822
1823
1824
1825
1826
1827

1828
1829
1830
1831
1832
1833
1834
1835







-
+







  }
  if( nBasis==0 ){
    nBasis = 6;
    zBasis = "fossil";
  }
  do{
    blob_zero(pBuf);
    if( cnt++>20 ) fossil_panic("cannot generate a temporary filename");
    if( cnt++>20 ) fossil_fatal("cannot generate a temporary filename");
    if( zTag==0 ){
      sqlite3_randomness(15, zRand);
      for(i=0; i<15; i++){
        zRand[i] = (char)zChars[ ((unsigned char)zRand[i])%(sizeof(zChars)-1) ];
      }
      zRand[15] = 0;
      zTag = zRand;
Changes to src/http_ssl.c.
114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
129
130
131
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
114
115
116
117
118
119
120

121
122
123
124
125
126
127
128
129
130
131
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







-
+













-
+















-
+







    if( zCaSetting==0 || zCaSetting[0]=='\0' ){
      /* CA location not specified, use platform's default certificate store */
      X509_STORE_set_default_paths(SSL_CTX_get_cert_store(sslCtx));
    }else{
      /* User has specified a CA location, make sure it exists and use it */
      switch( file_isdir(zCaSetting, ExtFILE) ){
        case 0: { /* doesn't exist */
          fossil_panic("ssl-ca-location is set to '%s', "
          fossil_fatal("ssl-ca-location is set to '%s', "
              "but is not a file or directory", zCaSetting);
          break;
        }
        case 1: { /* directory */
          zCaDirectory = zCaSetting;
          break;
        }
        case 2: { /* file */
          zCaFile = zCaSetting;
          break;
        }
      }
      if( SSL_CTX_load_verify_locations(sslCtx, zCaFile, zCaDirectory)==0 ){
        fossil_panic("Failed to use CA root certificates from "
        fossil_fatal("Failed to use CA root certificates from "
          "ssl-ca-location '%s'", zCaSetting);
      }
    }

    /* Load client SSL identity, preferring the filename specified on the
    ** command line */
    if( g.zSSLIdentity!=0 ){
      identityFile = g.zSSLIdentity;
    }else{
      identityFile = db_get("ssl-identity", 0);
    }
    if( identityFile!=0 && identityFile[0]!='\0' ){
      if( SSL_CTX_use_certificate_file(sslCtx,identityFile,SSL_FILETYPE_PEM)!=1
       || SSL_CTX_use_PrivateKey_file(sslCtx,identityFile,SSL_FILETYPE_PEM)!=1
      ){
        fossil_panic("Could not load SSL identity from %s", identityFile);
        fossil_fatal("Could not load SSL identity from %s", identityFile);
      }
    }
    /* Register a callback to tell the user what to do when the server asks
    ** for a cert */
    SSL_CTX_set_client_cert_cb(sslCtx, ssl_client_cert_callback);

    sslIsInit = 1;
Changes to src/http_transport.c.
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147







-
+







-
+







    zHost = mprintf("%s@%s", pUrlData->user, pUrlData->name);
    blob_append_escaped_arg(&zCmd, zHost);
    fossil_free(zHost);
  }else{
    blob_append_escaped_arg(&zCmd, pUrlData->name);
  }
  if( !is_safe_fossil_command(pUrlData->fossil) ){
    fossil_panic("the ssh:// URL is asking to run an unsafe command [%s] on "
    fossil_fatal("the ssh:// URL is asking to run an unsafe command [%s] on "
                 "the server.", pUrlData->fossil);
  }
  blob_append_escaped_arg(&zCmd, pUrlData->fossil);
  blob_append(&zCmd, " test-http", 10);
  if( pUrlData->path && pUrlData->path[0] ){
    blob_append_escaped_arg(&zCmd, pUrlData->path);
  }else{
    fossil_panic("ssh:// URI does not specify a path to the repository");
    fossil_fatal("ssh:// URI does not specify a path to the repository");
  }
  if( g.fSshTrace ){
    fossil_print("%s\n", blob_str(&zCmd));  /* Show the whole SSH command */
  }
  popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid, 0);
  if( sshPid==0 ){
    socket_set_errmsg("cannot start ssh tunnel using [%b]", &zCmd);
179
180
181
182
183
184
185
186

187
188
189
190
191
192
193
179
180
181
182
183
184
185

186
187
188
189
190
191
192
193







-
+







      sqlite3_randomness(sizeof(iRandId), &iRandId);
      transport.zOutFile = mprintf("%s-%llu-out.http",
                                       g.zRepositoryName, iRandId);
      transport.zInFile = mprintf("%s-%llu-in.http",
                                       g.zRepositoryName, iRandId);
      transport.pFile = fossil_fopen(transport.zOutFile, "wb");
      if( transport.pFile==0 ){
        fossil_panic("cannot output temporary file: %s", transport.zOutFile);
        fossil_fatal("cannot output temporary file: %s", transport.zOutFile);
      }
      transport.isOpen = 1;
    }else{
      rc = socket_open(pUrlData);
      if( rc==0 ) transport.isOpen = 1;
    }
  }
Changes to src/import.c.
634
635
636
637
638
639
640
641

642
643
644
645
646
647
648
634
635
636
637
638
639
640

641
642
643
644
645
646
647
648







-
+







      fossil_free(gg.aData); gg.aData = 0;
      gg.nData = atoi(&zLine[5]);
      if( gg.nData ){
        int got;
        gg.aData = fossil_malloc( gg.nData+1 );
        got = fread(gg.aData, 1, gg.nData, pIn);
        if( got!=gg.nData ){
          fossil_panic("short read: got %d of %d bytes", got, gg.nData);
          fossil_fatal("short read: got %d of %d bytes", got, gg.nData);
        }
        gg.aData[got] = '\0';
        if( gg.zComment==0 &&
            (gg.xFinish==finish_commit || gg.xFinish==finish_tag) ){
          /* Strip trailing newline, it's appended to the comment. */
          if( gg.aData[got-1] == '\n' )
            gg.aData[got-1] = '\0';
Changes to src/json_status.c.
165
166
167
168
169
170
171
172

173
174
175
176
177
178
165
166
167
168
169
170
171

172
173
174
175
176
177
178







-
+






      case -4:  zLabel = "INTEGRATE  ";  break;
    }
    blob_append(report, zPrefix, nPrefix);
    blob_appendf(report, "%s %s\n", zLabel, db_column_text(&q, 0));
  }
  db_finalize(&q);
  if( nErr ){
    fossil_panic("aborting due to prior errors");
    fossil_fatal("aborting due to prior errors");
  }
#endif
  return cson_object_value( oPay );
}

#endif /* FOSSIL_ENABLE_JSON */
Changes to src/main.c.
1466
1467
1468
1469
1470
1471
1472
1473

1474
1475
1476
1477

1478
1479
1480
1481
1482
1483
1484
1466
1467
1468
1469
1470
1471
1472

1473
1474
1475
1476

1477
1478
1479
1480
1481
1482
1483
1484







-
+



-
+







        if( file_chdir(zDir, 1) ){
          fossil_panic("unable to chroot into %s", zDir);
        }
        g.fJail = 1;
        zRepo = "/";
      }else{
        for(i=strlen(zDir)-1; i>0 && zDir[i]!='/'; i--){}
        if( zDir[i]!='/' ) fossil_panic("bad repository name: %s", zRepo);
        if( zDir[i]!='/' ) fossil_fatal("bad repository name: %s", zRepo);
        if( i>0 ){
          zDir[i] = 0;
          if( file_chdir(zDir, 1) ){
            fossil_panic("unable to chroot into %s", zDir);
            fossil_fatal("unable to chroot into %s", zDir);
          }
          zDir[i] = '/';
        }
        zRepo = &zDir[i];
      }
    }
    if( stat(zRepo, &sStat)!=0 ){
Changes to src/printf.c.
1130
1131
1132
1133
1134
1135
1136
1137

1138
1139

1140

1141
1142
1143







1144
1145
1146
1147
1148
1149


1150
1151
1152
1153
1154
1155
1156
1130
1131
1132
1133
1134
1135
1136

1137
1138

1139
1140
1141



1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153

1154
1155
1156
1157
1158
1159
1160
1161
1162







-
+

-
+

+
-
-
-
+
+
+
+
+
+
+





-
+
+







    fossil_trace("%s\n", z);
  }
  return rc;
}

/*
** Print an error message, rollback all databases, and quit.  These
** routines never return.
** routines never return and produce a non-zero process exit status.
**
** The only different between fossil_fatal() and fossil_panic() is that
** The main difference between fossil_fatal() and fossil_panic() is that
** fossil_panic() makes an entry in the error log whereas fossil_fatal()
** does not. On POSIX platforms, if there is not an error log, then both
** does not.  If there is not error log, then both routines work the
** same.  Hence, the routines are interchangable for commands and only
** make a difference with processing web pages.
** routines work similarly with respect to user-visible effects.  Hence,
** the routines are interchangable for commands and only act differently
** when processing web pages. On the Windows platform, fossil_panic()
** also displays a pop-up stating that an error has occured and allowing
** just-in-time debugging to commence. On all platforms, fossil_panic()
** ends execution with a SIGABRT signal, bypassing atexit processing.
** This signal can also produce a core dump on POSIX platforms.
**
** Use fossil_fatal() for malformed inputs that should be reported back
** to the user, but which do not represent a configuration problem or bug.
**
** Use fossil_panic() for any kind of error that should be brought to the
** attention of the system administrator.
** attention of the system administrator or Fossil developers. It should
** be avoided for ordinary usage, parameter, OOM and I/O errors.
*/
NORETURN void fossil_panic(const char *zFormat, ...){
  va_list ap;
  int rc = 1;
  char z[1000];
  static int once = 0;

Changes to src/sqlcmd.c.
301
302
303
304
305
306
307
308

309
310
311
312
313
314
315
301
302
303
304
305
306
307

308
309
310
311
312
313
314
315







-
+







    *pzKey = zKey;
    if( fossil_getenv("FOSSIL_USE_SEE_TEXTKEY")==0 ){
      *pnKey = (int)strlen(zKey);
    }else{
      *pnKey = -1;
    }
  }else{
    fossil_panic("failed to allocate %u bytes for key", nByte);
    fossil_fatal("failed to allocate %u bytes for key", nByte);
  }
}
#endif

/*
** This routine closes the Fossil databases and/or invalidates the global
** state variables that keep track of them.
Changes to src/undo.c.
267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
267
268
269
270
271
272
273

274
275
276
277
278
279
280
281







-
+







** Save the current content of the file zPathname so that it
** will be undoable.  The name is relative to the root of the
** tree.
*/
void undo_save(const char *zPathname){
  if( undoDisable ) return;
  if( undo_maybe_save(zPathname, -1)!=UNDO_SAVED_OK ){
    fossil_panic("failed to save undo information for path: %s",
    fossil_fatal("failed to save undo information for path: %s",
                 zPathname);
  }
}

/*
** Possibly save the current content of the file zPathname so
** that it will be undoable.  The name is relative to the root
Changes to src/util.c.
54
55
56
57
58
59
60
61

62
63
64
65
66

67
68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
54
55
56
57
58
59
60

61
62
63
64
65

66
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82







-
+




-
+








-
+







}

/*
** Malloc and free routines that cannot fail
*/
void *fossil_malloc(size_t n){
  void *p = malloc(n==0 ? 1 : n);
  if( p==0 ) fossil_panic("out of memory");
  if( p==0 ) fossil_fatal("out of memory");
  return p;
}
void *fossil_malloc_zero(size_t n){
  void *p = malloc(n==0 ? 1 : n);
  if( p==0 ) fossil_panic("out of memory");
  if( p==0 ) fossil_fatal("out of memory");
  memset(p, 0, n);
  return p;
}
void fossil_free(void *p){
  free(p);
}
void *fossil_realloc(void *p, size_t n){
  p = realloc(p, n);
  if( p==0 ) fossil_panic("out of memory");
  if( p==0 ) fossil_fatal("out of memory");
  return p;
}
void fossil_secure_zero(void *p, size_t n){
  volatile unsigned char *vp = (volatile unsigned char *)p;
  size_t i;

  if( p==0 ) return;
103
104
105
106
107
108
109
110

111
112
113

114
115
116
117
118

119
120
121

122
123
124
125
126
127
128
103
104
105
106
107
108
109

110
111
112

113
114
115
116
117

118
119
120

121
122
123
124
125
126
127
128







-
+


-
+




-
+


-
+








  fossil_get_page_size(&pageSize);
  assert( pageSize>0 );
  assert( pageSize%2==0 );
#if defined(_WIN32)
  p = VirtualAlloc(NULL, pageSize, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
  if( p==NULL ){
    fossil_panic("VirtualAlloc failed: %lu\n", GetLastError());
    fossil_fatal("VirtualAlloc failed: %lu\n", GetLastError());
  }
  if( !VirtualLock(p, pageSize) ){
    fossil_panic("VirtualLock failed: %lu\n", GetLastError());
    fossil_fatal("VirtualLock failed: %lu\n", GetLastError());
  }
#elif defined(USE_MMAN_H)
  p = mmap(0, pageSize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
  if( p==MAP_FAILED ){
    fossil_panic("mmap failed: %d\n", errno);
    fossil_fatal("mmap failed: %d\n", errno);
  }
  if( mlock(p, pageSize) ){
    fossil_panic("mlock failed: %d\n", errno);
    fossil_fatal("mlock failed: %d\n", errno);
  }
#else
  p = fossil_malloc(pageSize);
#endif
  fossil_secure_zero(p, pageSize);
  if( pN ) *pN = pageSize;
  return p;
Changes to src/winfile.c.
280
281
282
283
284
285
286
287

288
289
290
291
292
293
294
280
281
282
283
284
285
286

287
288
289
290
291
292
293
294







-
+







** characters are converted to '/'.
*/
void win32_getcwd(char *zBuf, int nBuf){
  int i;
  char *zUtf8;
  wchar_t *zWide = fossil_malloc( sizeof(wchar_t)*nBuf );
  if( GetCurrentDirectoryW(nBuf, zWide)==0 ){
    fossil_panic("cannot find current working directory.");
    fossil_fatal("cannot find current working directory.");
  }
  zUtf8 = fossil_path_to_utf8(zWide);
  fossil_free(zWide);
  for(i=0; zUtf8[i]; i++) if( zUtf8[i]=='\\' ) zUtf8[i] = '/';
  strncpy(zBuf, zUtf8, nBuf);
  fossil_path_free(zUtf8);
}
Changes to src/winhttp.c.
286
287
288
289
290
291
292
293

294
295
296
297
298
299
300
286
287
288
289
290
291
292

293
294
295
296
297
298
299
300







-
+







** Issue a fatal error.
*/
static NORETURN void winhttp_fatal(
  const char *zOp,
  const char *zService,
  const char *zErr
){
  fossil_panic("unable to %s service '%s': %s", zOp, zService, zErr);
  fossil_fatal("unable to %s service '%s': %s", zOp, zService, zErr);
}

/*
** Make sure the server stops as soon as possible after the stopper file
** is found.  If there is no stopper file name, do nothing.
*/
static void win32_server_stopper(void *pAppData){
602
603
604
605
606
607
608

609
610

611
612

613
614
615
616
617
618
619
602
603
604
605
606
607
608
609
610

611
612

613
614
615
616
617
618
619
620







+

-
+

-
+







        iPort++;
        continue;
      }
    }
    break;
  }
  if( iPort>mxPort ){
    /* These exits are merely fatal because firewall settings can cause them. */
    if( mnPort==mxPort ){
      fossil_panic("unable to open listening socket on port %d", mnPort);
      fossil_fatal("unable to open listening socket on port %d", mnPort);
    }else{
      fossil_panic("unable to open listening socket on any"
      fossil_fatal("unable to open listening socket on any"
                   " port in the range %d..%d", mnPort, mxPort);
    }
  }
  if( !GetTempPathW(MAX_PATH, zTmpPath) ){
    fossil_panic("unable to get path to the temporary directory.");
  }
  zTempPrefix = mprintf("%sfossil_server_P%d",
906
907
908
909
910
911
912
913

914
915
916
917
918
919
920
907
908
909
910
911
912
913

914
915
916
917
918
919
920
921







-
+







  if( GetStdHandle(STD_INPUT_HANDLE)!=NULL ){ return 1; }

  /* Try to start the control dispatcher thread for the service. */
  if( !StartServiceCtrlDispatcherW(ServiceTable) ){
    if( GetLastError()==ERROR_FAILED_SERVICE_CONTROLLER_CONNECT ){
      return 1;
    }else{
      fossil_panic("error from StartServiceCtrlDispatcher()");
      fossil_fatal("error from StartServiceCtrlDispatcher()");
    }
  }
  return 0;
}

/* Duplicate #ifdef needed for mkindex */
#ifdef _WIN32