Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix an infinite recursion on db_err() that might occur if SQLite is unable to create the WAL file for a database due to lack of write permission on the containing directory. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
421fe24138cd443b0059bb51baec08f4 |
User & Date: | drh 2017-12-13 19:16:52.254 |
Context
2017-12-13
| ||
20:36 | Improved error reporting when trying to write to a repository that is in a read-only directory. ... (check-in: 500b0a2a user: drh tags: trunk) | |
19:16 | Fix an infinite recursion on db_err() that might occur if SQLite is unable to create the WAL file for a database due to lack of write permission on the containing directory. ... (check-in: 421fe241 user: drh tags: trunk) | |
17:17 | Always generate timeline-data for a timeline even if the table has no check-ins and thus no graph. This causes the timeline-data scanner to continue looking for subsequent timelines. ... (check-in: 3f316764 user: drh tags: trunk) | |
Changes
Changes to src/db.c.
︙ | ︙ | |||
52 53 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 83 | ** structure. */ struct Stmt { Blob sql; /* The SQL for this statement */ sqlite3_stmt *pStmt; /* The results of sqlite3_prepare_v2() */ Stmt *pNext, *pPrev; /* List of all unfinalized statements */ int nStep; /* Number of sqlite3_step() calls */ }; /* ** Copy this to initialize a Stmt object to a clean/empty state. This ** is useful to help avoid assertions when performing cleanup in some ** error handling cases. */ #define empty_Stmt_m {BLOB_INITIALIZER,NULL, NULL, NULL, 0} #endif /* INTERFACE */ const struct Stmt empty_Stmt = empty_Stmt_m; /* ** Call this routine when a database error occurs. */ static void db_err(const char *zFormat, ...){ va_list ap; char *z; int rc = 1; va_start(ap, zFormat); z = vmprintf(zFormat, ap); va_end(ap); #ifdef FOSSIL_ENABLE_JSON if( g.json.isJsonMode ){ json_err( 0, z, 1 ); if( g.isHTTP ){ | > > > | 52 53 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 83 84 85 86 | ** structure. */ struct Stmt { Blob sql; /* The SQL for this statement */ sqlite3_stmt *pStmt; /* The results of sqlite3_prepare_v2() */ Stmt *pNext, *pPrev; /* List of all unfinalized statements */ int nStep; /* Number of sqlite3_step() calls */ int rc; /* Error from db_vprepare() */ }; /* ** Copy this to initialize a Stmt object to a clean/empty state. This ** is useful to help avoid assertions when performing cleanup in some ** error handling cases. */ #define empty_Stmt_m {BLOB_INITIALIZER,NULL, NULL, NULL, 0} #endif /* INTERFACE */ const struct Stmt empty_Stmt = empty_Stmt_m; /* ** Call this routine when a database error occurs. */ static void db_err(const char *zFormat, ...){ static int rcLooping = 0; va_list ap; char *z; int rc = 1; if( rcLooping ) exit(rcLooping); va_start(ap, zFormat); z = vmprintf(zFormat, ap); va_end(ap); #ifdef FOSSIL_ENABLE_JSON if( g.json.isJsonMode ){ json_err( 0, z, 1 ); if( g.isHTTP ){ |
︙ | ︙ | |||
95 96 97 98 99 100 101 102 103 104 105 106 107 108 | g.cgiOutput = 0; cgi_printf("<h1>Database Error</h1>\n<p>%h</p>\n", z); cgi_reply(); }else{ fprintf(stderr, "%s: %s\n", g.argv[0], z); } free(z); db_force_rollback(); fossil_exit(rc); } /* ** All static variable that a used by only this file are gathered into ** the following structure. | > | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | g.cgiOutput = 0; cgi_printf("<h1>Database Error</h1>\n<p>%h</p>\n", z); cgi_reply(); }else{ fprintf(stderr, "%s: %s\n", g.argv[0], z); } free(z); rcLooping = rc; db_force_rollback(); fossil_exit(rc); } /* ** All static variable that a used by only this file are gathered into ** the following structure. |
︙ | ︙ | |||
271 272 273 274 275 276 277 278 279 280 281 282 283 284 | } rc = sqlite3_prepare_v3(g.db, zSql, -1, prepFlags, &pStmt->pStmt, 0); if( rc!=0 && (flags & DB_PREPARE_IGNORE_ERROR)!=0 ){ db_err("%s\n%s", sqlite3_errmsg(g.db), zSql); } pStmt->pNext = pStmt->pPrev = 0; pStmt->nStep = 0; return rc; } int db_prepare(Stmt *pStmt, const char *zFormat, ...){ int rc; va_list ap; va_start(ap, zFormat); rc = db_vprepare(pStmt, 0, zFormat, ap); | > | 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 | } rc = sqlite3_prepare_v3(g.db, zSql, -1, prepFlags, &pStmt->pStmt, 0); if( rc!=0 && (flags & DB_PREPARE_IGNORE_ERROR)!=0 ){ db_err("%s\n%s", sqlite3_errmsg(g.db), zSql); } pStmt->pNext = pStmt->pPrev = 0; pStmt->nStep = 0; pStmt->rc = rc; return rc; } int db_prepare(Stmt *pStmt, const char *zFormat, ...){ int rc; va_list ap; va_start(ap, zFormat); rc = db_vprepare(pStmt, 0, zFormat, ap); |
︙ | ︙ | |||
357 358 359 360 361 362 363 364 365 366 367 368 369 370 | /* ** Step the SQL statement. Return either SQLITE_ROW or an error code ** or SQLITE_OK if the statement finishes successfully. */ int db_step(Stmt *pStmt){ int rc; rc = sqlite3_step(pStmt->pStmt); pStmt->nStep++; return rc; } /* ** Print warnings if a query is inefficient. | > | 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 | /* ** Step the SQL statement. Return either SQLITE_ROW or an error code ** or SQLITE_OK if the statement finishes successfully. */ int db_step(Stmt *pStmt){ int rc; if( pStmt->pStmt==0 ) return pStmt->rc; rc = sqlite3_step(pStmt->pStmt); pStmt->nStep++; return rc; } /* ** Print warnings if a query is inefficient. |
︙ | ︙ |