mirror of https://github.com/sqlite/sqlite
Add the sqlite3_system_errno() interface.
FossilOrigin-Name: 4bd12b57ea177cfb1f44d54bfa7aedfb8a8c0c64
This commit is contained in:
commit
d260dd3534
39
manifest
39
manifest
|
@ -1,5 +1,5 @@
|
|||
C Change\sthe\sway\sfts5\sinternally\sallocates\ssegment\sids\sin\sorder\sto\seliminated\snon-determinism\sfrom\sthe\smodule.
|
||||
D 2016-03-21T09:56:19.361
|
||||
C Add\sthe\ssqlite3_system_errno()\sinterface.
|
||||
D 2016-03-21T14:46:37.265
|
||||
F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66
|
||||
|
@ -315,8 +315,8 @@ F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
|
|||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||
F src/insert.c 723d5d708cdb61bdd47c00b9f07c75be45aefc09
|
||||
F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e
|
||||
F src/loadext.c 9e2a41adcaff16ebc1ebff1f336cbf33de55396f
|
||||
F src/main.c 29ea8ebb23ceb5159da167e18d5c807fbb1545c4
|
||||
F src/loadext.c e70f8f9e97624a232870ea5486e682c813ac3002
|
||||
F src/main.c f6c6e61bfd4cc9306a737d0c5c3f1e0eaf6086e0
|
||||
F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
|
||||
|
@ -331,12 +331,12 @@ F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
|
|||
F src/mutex_unix.c 27bb6cc49485ee46711a6580ab7b3f1402211d23
|
||||
F src/mutex_w32.c 5e6fe1c298fb5a8a15aaed4161d5759311431c17
|
||||
F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7
|
||||
F src/os.c f89e3ca1c2e3d5015b847aec60371c474acbac82
|
||||
F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf
|
||||
F src/os.c ca10edb445ad2c5fdc7285b49d72bcdf261fa23e
|
||||
F src/os.h 91ff889115ecd01f436d3611f7f5ea4dc12d92f1
|
||||
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
|
||||
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
||||
F src/os_unix.c 4bde11921a2bebcf2167efc8540ddabc814189dc
|
||||
F src/os_win.c cbf8c442a0d818d05bcf40b093cb3ebad435b9be
|
||||
F src/os_unix.c 50103f69121bca969761b821e2b0e393b55fe869
|
||||
F src/os_win.c 551d973ada67127430e41d9e514e53f6beb6c5a7
|
||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||
F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d
|
||||
F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56
|
||||
|
@ -353,15 +353,15 @@ F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20
|
|||
F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e
|
||||
F src/select.c 6dd2097bb158efe3b8d68683dcc3b4a49e907a34
|
||||
F src/shell.c 5e0ab1e708dc294330ccd8230536e1801f60822e
|
||||
F src/sqlite.h.in 0235586b3fb639e85998d495c90f007657fd82af
|
||||
F src/sqlite.h.in e877f141b15ef68ef28f84714e69d7234f9a071e
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d
|
||||
F src/sqliteInt.h 751ced73be8c449a75e075e0545cdd832ed3591e
|
||||
F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2
|
||||
F src/sqliteInt.h 4eb80a9b9a512180a9739f99d754915e03d8091a
|
||||
F src/sqliteLimit.h 7b28cf72cbd52f178bfc97ea266445e351f2cd24
|
||||
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
|
||||
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
|
||||
F src/tclsqlite.c 4bf3bea9b03aeac176ac114700f35f76a1de4c8a
|
||||
F src/test1.c 941f1cb50a601c30fd426a381e783b863c9d7d13
|
||||
F src/test1.c 7187b7e924bfc97780e6fd2a40dad94a32bddca0
|
||||
F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b
|
||||
F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f
|
||||
F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
|
||||
|
@ -415,9 +415,9 @@ F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373
|
|||
F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280
|
||||
F src/update.c 56b3db7edff0110360a12b76af97c39ebe3ea8b8
|
||||
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
|
||||
F src/util.c 34ef7be420f82415ec48131404995ddb6ee7502f
|
||||
F src/util.c cf7dce85ab9af5280b8a45985df2591efbfefe56
|
||||
F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52
|
||||
F src/vdbe.c 3b542ffd5b6aaab55255ec3801fc86dcbfaea543
|
||||
F src/vdbe.c f19741f2d8b33e8f09cd2219570b6c9ed924c3f1
|
||||
F src/vdbe.h 6f44193e7be52fd5f7c308175a936555b1e6b101
|
||||
F src/vdbeInt.h f88d3115e9bde33b01d81f0dd26d8dd51f995991
|
||||
F src/vdbeapi.c 95b1f8e527240a18a9aea41a655b013bf07a7009
|
||||
|
@ -521,7 +521,7 @@ F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
|
|||
F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
|
||||
F test/cacheflush.test af25bb1509df04c1da10e38d8f322d66eceedf61
|
||||
F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738
|
||||
F test/capi3.test db0731f6e2a94f96c6d4c478fedef4e0c077026c
|
||||
F test/capi3.test 860dafdc04f651a67781018cb1a0b179d22d7d15
|
||||
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
|
||||
F test/capi3c.test b28ec47692f0fc50eb61b2d464d8d52e816b3732
|
||||
F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82
|
||||
|
@ -1457,7 +1457,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P c39081e878faccc8552141afa5732a2bf2f77570
|
||||
R b7f851b6f7c0c6dc2d06642c2058dff4
|
||||
U dan
|
||||
Z 052aba56922a1e224a7195cfbf595d27
|
||||
P d6e2637df16764aa9723a30ea2eb8a631d28cb2b b4a1114f730c62e93623f889bc0e4fd8d0b31efa
|
||||
R 6870e1f7d1e452978a882de2dd2b0506
|
||||
T +closed b4a1114f730c62e93623f889bc0e4fd8d0b31efa
|
||||
U drh
|
||||
Z c933d47fc520e2ff9b51b35972ce646c
|
||||
|
|
|
@ -1 +1 @@
|
|||
d6e2637df16764aa9723a30ea2eb8a631d28cb2b
|
||||
4bd12b57ea177cfb1f44d54bfa7aedfb8a8c0c64
|
|
@ -414,7 +414,9 @@ static const sqlite3_api_routines sqlite3Apis = {
|
|||
/* Version 3.10.0 and later */
|
||||
sqlite3_status64,
|
||||
sqlite3_strlike,
|
||||
sqlite3_db_cacheflush
|
||||
sqlite3_db_cacheflush,
|
||||
/* Version 3.12.0 and later */
|
||||
sqlite3_system_errno
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -2240,6 +2240,9 @@ int sqlite3_extended_errcode(sqlite3 *db){
|
|||
}
|
||||
return db->errCode;
|
||||
}
|
||||
int sqlite3_system_errno(sqlite3 *db){
|
||||
return db ? db->iSysErrno : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return a string that describes the kind of error specified in the
|
||||
|
|
3
src/os.c
3
src/os.c
|
@ -262,6 +262,9 @@ int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
|
|||
int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
|
||||
return pVfs->xSleep(pVfs, nMicro);
|
||||
}
|
||||
int sqlite3OsGetLastError(sqlite3_vfs *pVfs){
|
||||
return pVfs->xGetLastError ? pVfs->xGetLastError(pVfs, 0, 0) : 0;
|
||||
}
|
||||
int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
|
||||
int rc;
|
||||
/* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64()
|
||||
|
|
1
src/os.h
1
src/os.h
|
@ -197,6 +197,7 @@ void sqlite3OsDlClose(sqlite3_vfs *, void *);
|
|||
#endif /* SQLITE_OMIT_LOAD_EXTENSION */
|
||||
int sqlite3OsRandomness(sqlite3_vfs *, int, char *);
|
||||
int sqlite3OsSleep(sqlite3_vfs *, int);
|
||||
int sqlite3OsGetLastError(sqlite3_vfs*);
|
||||
int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*);
|
||||
|
||||
/*
|
||||
|
|
|
@ -6264,23 +6264,18 @@ static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){
|
|||
# define unixCurrentTime 0
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
/*
|
||||
** We added the xGetLastError() method with the intention of providing
|
||||
** better low-level error messages when operating-system problems come up
|
||||
** during SQLite operation. But so far, none of that has been implemented
|
||||
** in the core. So this routine is never called. For now, it is merely
|
||||
** a place-holder.
|
||||
** The xGetLastError() method is designed to return a better
|
||||
** low-level error message when operating-system problems come up
|
||||
** during SQLite operation. Only the integer return code is currently
|
||||
** used.
|
||||
*/
|
||||
static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
|
||||
UNUSED_PARAMETER(NotUsed);
|
||||
UNUSED_PARAMETER(NotUsed2);
|
||||
UNUSED_PARAMETER(NotUsed3);
|
||||
return 0;
|
||||
return errno;
|
||||
}
|
||||
#else
|
||||
# define unixGetLastError 0
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -5584,8 +5584,10 @@ static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
|
|||
** sqlite3_errmsg(), possibly making IO errors easier to debug.
|
||||
*/
|
||||
static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
|
||||
DWORD e = osGetLastError();
|
||||
UNUSED_PARAMETER(pVfs);
|
||||
return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf);
|
||||
if( nBuf>0 ) winGetLastErrorMsg(e, nBuf, zBuf);
|
||||
return e;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -7915,6 +7915,18 @@ void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
|
|||
*/
|
||||
int sqlite3_db_cacheflush(sqlite3*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Low-level system error code
|
||||
**
|
||||
** ^Attempt to return the underlying operating system error code or error
|
||||
** number that caused the most reason I/O error or failure to open a file.
|
||||
** The return value is OS-dependent. For example, on unix systems, after
|
||||
** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be
|
||||
** called to get back the underlying "errno" that caused the problem, such
|
||||
** as ENOSPC, EAUTH, EISDIR, and so forth.
|
||||
*/
|
||||
int sqlite3_system_errno(sqlite3*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Database Snapshot
|
||||
** KEYWORDS: {snapshot}
|
||||
|
|
|
@ -279,6 +279,8 @@ struct sqlite3_api_routines {
|
|||
int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
|
||||
int (*strlike)(const char*,const char*,unsigned int);
|
||||
int (*db_cacheflush)(sqlite3*);
|
||||
/* Version 3.12.0 and later */
|
||||
int (*system_errno)(sqlite3*);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -522,6 +524,8 @@ struct sqlite3_api_routines {
|
|||
#define sqlite3_status64 sqlite3_api->status64
|
||||
#define sqlite3_strlike sqlite3_api->strlike
|
||||
#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
|
||||
/* Version 3.12.0 and later */
|
||||
#define sqlite3_system_errno sqlite3_api->system_errno
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
|
|
|
@ -1220,6 +1220,7 @@ struct sqlite3 {
|
|||
unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */
|
||||
int errCode; /* Most recent error code (SQLITE_*) */
|
||||
int errMask; /* & result codes with this before returning */
|
||||
int iSysErrno; /* Errno value from last system error */
|
||||
u16 dbOptFlags; /* Flags to enable/disable optimizations */
|
||||
u8 enc; /* Text encoding */
|
||||
u8 autoCommit; /* The auto-commit flag. */
|
||||
|
@ -3766,6 +3767,7 @@ int sqlite3Atoi64(const char*, i64*, int, u8);
|
|||
int sqlite3DecOrHexToI64(const char*, i64*);
|
||||
void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...);
|
||||
void sqlite3Error(sqlite3*,int);
|
||||
void sqlite3SystemError(sqlite3*,int);
|
||||
void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
|
||||
u8 sqlite3HexToInt(int h);
|
||||
int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
|
||||
|
|
24
src/test1.c
24
src/test1.c
|
@ -4849,6 +4849,29 @@ static int test_db_cacheflush(
|
|||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_system_errno DB
|
||||
**
|
||||
** Return the low-level system errno value.
|
||||
*/
|
||||
static int test_system_errno(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3 *db;
|
||||
int iErrno;
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "DB");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
|
||||
iErrno = sqlite3_system_errno(db);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(iErrno));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_db_filename DB DBNAME
|
||||
**
|
||||
|
@ -7086,6 +7109,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
|||
{ "sqlite3_release_memory", test_release_memory, 0},
|
||||
{ "sqlite3_db_release_memory", test_db_release_memory, 0},
|
||||
{ "sqlite3_db_cacheflush", test_db_cacheflush, 0},
|
||||
{ "sqlite3_system_errno", test_system_errno, 0},
|
||||
{ "sqlite3_db_filename", test_db_filename, 0},
|
||||
{ "sqlite3_db_readonly", test_db_readonly, 0},
|
||||
{ "sqlite3_soft_heap_limit", test_soft_heap_limit, 0},
|
||||
|
|
27
src/util.c
27
src/util.c
|
@ -117,13 +117,37 @@ const char *sqlite3StrNext(const char *z){
|
|||
return z + strlen(z) + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Helper function for sqlite3Error() - called rarely. Broken out into
|
||||
** a separate routine to avoid unnecessary register saves on entry to
|
||||
** sqlite3Error().
|
||||
*/
|
||||
static SQLITE_NOINLINE void sqlite3ErrorFinish(sqlite3 *db, int err_code){
|
||||
if( db->pErr ) sqlite3ValueSetNull(db->pErr);
|
||||
sqlite3SystemError(db, err_code);
|
||||
}
|
||||
|
||||
/*
|
||||
** Set the current error code to err_code and clear any prior error message.
|
||||
** Also set iSysErrno (by calling sqlite3System) if the err_code indicates
|
||||
** that would be appropriate.
|
||||
*/
|
||||
void sqlite3Error(sqlite3 *db, int err_code){
|
||||
assert( db!=0 );
|
||||
db->errCode = err_code;
|
||||
if( db->pErr ) sqlite3ValueSetNull(db->pErr);
|
||||
if( err_code || db->pErr ) sqlite3ErrorFinish(db, err_code);
|
||||
}
|
||||
|
||||
/*
|
||||
** Load the sqlite3.iSysErrno field if that is an appropriate thing
|
||||
** to do based on the SQLite error code in rc.
|
||||
*/
|
||||
void sqlite3SystemError(sqlite3 *db, int rc){
|
||||
if( rc==SQLITE_IOERR_NOMEM ) return;
|
||||
rc &= 0xff;
|
||||
if( rc==SQLITE_CANTOPEN || rc==SQLITE_IOERR ){
|
||||
db->iSysErrno = sqlite3OsGetLastError(db->pVfs);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -150,6 +174,7 @@ void sqlite3Error(sqlite3 *db, int err_code){
|
|||
void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *zFormat, ...){
|
||||
assert( db!=0 );
|
||||
db->errCode = err_code;
|
||||
sqlite3SystemError(db, err_code);
|
||||
if( zFormat==0 ){
|
||||
sqlite3Error(db, err_code);
|
||||
}else if( db->pErr || (db->pErr = sqlite3ValueNew(db))!=0 ){
|
||||
|
|
|
@ -6826,6 +6826,7 @@ abort_due_to_error:
|
|||
sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
|
||||
}
|
||||
p->rc = rc;
|
||||
sqlite3SystemError(db, rc);
|
||||
testcase( sqlite3GlobalConfig.xLog!=0 );
|
||||
sqlite3_log(rc, "statement aborts at %d: [%s] %s",
|
||||
(int)(pOp - aOp), p->zSql, p->zErrMsg);
|
||||
|
|
|
@ -172,14 +172,15 @@ do_test capi3-3.3 {
|
|||
catch {
|
||||
set db2 [sqlite3_open /bogus/path/test.db {}]
|
||||
}
|
||||
sqlite3_extended_errcode $db2
|
||||
} {SQLITE_CANTOPEN}
|
||||
set ::capi3_errno [sqlite3_system_errno $db2]
|
||||
list [sqlite3_extended_errcode $db2] [expr {$::capi3_errno!=0}]
|
||||
} {SQLITE_CANTOPEN 1}
|
||||
do_test capi3-3.4 {
|
||||
sqlite3_errmsg $db2
|
||||
} {unable to open database file}
|
||||
do_test capi3-3.5 {
|
||||
sqlite3_close $db2
|
||||
} {SQLITE_OK}
|
||||
list [sqlite3_system_errno $db2] [sqlite3_close $db2]
|
||||
} [list $::capi3_errno SQLITE_OK]
|
||||
if {[clang_sanitize_address]==0} {
|
||||
do_test capi3-3.6.1-misuse {
|
||||
sqlite3_close $db2
|
||||
|
|
Loading…
Reference in New Issue