📄 loadext.c
字号:
sqlite3_mutex_leave, sqlite3_mutex_try,#endif sqlite3_open_v2, sqlite3_release_memory, sqlite3_result_error_nomem, sqlite3_result_error_toobig, sqlite3_sleep, sqlite3_soft_heap_limit, sqlite3_vfs_find, sqlite3_vfs_register, sqlite3_vfs_unregister, /* ** Added for 3.5.8 */ sqlite3_threadsafe, sqlite3_result_zeroblob, sqlite3_result_error_code, sqlite3_test_control, sqlite3_randomness, sqlite3_context_db_handle, /* ** Added for 3.6.0 */ sqlite3_extended_result_codes, sqlite3_limit, sqlite3_next_stmt, sqlite3_sql, sqlite3_status,};/*** Attempt to load an SQLite extension library contained in the file** zFile. The entry point is zProc. zProc may be 0 in which case a** default entry point name (sqlite3_extension_init) is used. Use** of the default name is recommended.**** Return SQLITE_OK on success and SQLITE_ERROR if something goes wrong.**** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with ** error message text. The calling function should free this memory** by calling sqlite3DbFree(db, ).*/static int sqlite3LoadExtension( sqlite3 *db, /* Load the extension into this database connection */ const char *zFile, /* Name of the shared library containing extension */ const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */ char **pzErrMsg /* Put error message here if not 0 */){ sqlite3_vfs *pVfs = db->pVfs; void *handle; int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); char *zErrmsg = 0; void **aHandle; /* Ticket #1863. To avoid a creating security problems for older ** applications that relink against newer versions of SQLite, the ** ability to run load_extension is turned off by default. One ** must call sqlite3_enable_load_extension() to turn on extension ** loading. Otherwise you get the following error. */ if( (db->flags & SQLITE_LoadExtension)==0 ){ if( pzErrMsg ){ *pzErrMsg = sqlite3_mprintf("not authorized"); } return SQLITE_ERROR; } if( zProc==0 ){ zProc = "sqlite3_extension_init"; } handle = sqlite3OsDlOpen(pVfs, zFile); if( handle==0 ){ if( pzErrMsg ){ char zErr[256]; zErr[sizeof(zErr)-1] = '\0'; sqlite3_snprintf(sizeof(zErr)-1, zErr, "unable to open shared library [%s]", zFile); sqlite3OsDlError(pVfs, sizeof(zErr)-1, zErr); *pzErrMsg = sqlite3DbStrDup(0, zErr); } return SQLITE_ERROR; } xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*)) sqlite3OsDlSym(pVfs, handle, zProc); if( xInit==0 ){ if( pzErrMsg ){ char zErr[256]; zErr[sizeof(zErr)-1] = '\0'; sqlite3_snprintf(sizeof(zErr)-1, zErr, "no entry point [%s] in shared library [%s]", zProc,zFile); sqlite3OsDlError(pVfs, sizeof(zErr)-1, zErr); *pzErrMsg = sqlite3DbStrDup(0, zErr); sqlite3OsDlClose(pVfs, handle); } return SQLITE_ERROR; }else if( xInit(db, &zErrmsg, &sqlite3Apis) ){ if( pzErrMsg ){ *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg); } sqlite3_free(zErrmsg); sqlite3OsDlClose(pVfs, handle); return SQLITE_ERROR; } /* Append the new shared library handle to the db->aExtension array. */ aHandle = sqlite3DbMallocZero(db, sizeof(handle)*(db->nExtension+1)); if( aHandle==0 ){ return SQLITE_NOMEM; } if( db->nExtension>0 ){ memcpy(aHandle, db->aExtension, sizeof(handle)*db->nExtension); } sqlite3DbFree(db, db->aExtension); db->aExtension = aHandle; db->aExtension[db->nExtension++] = handle; return SQLITE_OK;}int sqlite3_load_extension( sqlite3 *db, /* Load the extension into this database connection */ const char *zFile, /* Name of the shared library containing extension */ const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */ char **pzErrMsg /* Put error message here if not 0 */){ int rc; sqlite3_mutex_enter(db->mutex); rc = sqlite3LoadExtension(db, zFile, zProc, pzErrMsg); sqlite3_mutex_leave(db->mutex); return rc;}/*** Call this routine when the database connection is closing in order** to clean up loaded extensions*/void sqlite3CloseExtensions(sqlite3 *db){ int i; assert( sqlite3_mutex_held(db->mutex) ); for(i=0; i<db->nExtension; i++){ sqlite3OsDlClose(db->pVfs, db->aExtension[i]); } sqlite3DbFree(db, db->aExtension);}/*** Enable or disable extension loading. Extension loading is disabled by** default so as not to open security holes in older applications.*/int sqlite3_enable_load_extension(sqlite3 *db, int onoff){ sqlite3_mutex_enter(db->mutex); if( onoff ){ db->flags |= SQLITE_LoadExtension; }else{ db->flags &= ~SQLITE_LoadExtension; } sqlite3_mutex_leave(db->mutex); return SQLITE_OK;}#endif /* SQLITE_OMIT_LOAD_EXTENSION *//*** The auto-extension code added regardless of whether or not extension** loading is supported. We need a dummy sqlite3Apis pointer for that** code if regular extension loading is not available. This is that** dummy pointer.*/#ifdef SQLITE_OMIT_LOAD_EXTENSIONstatic const sqlite3_api_routines sqlite3Apis = { 0 };#endif/*** The following object holds the list of automatically loaded** extensions.**** This list is shared across threads. The SQLITE_MUTEX_STATIC_MASTER** mutex must be held while accessing this list.*/static struct { int nExt; /* Number of entries in aExt[] */ void **aExt; /* Pointers to the extension init functions */} autoext = { 0, 0 };/*** Register a statically linked extension that is automatically** loaded by every new database connection.*/int sqlite3_auto_extension(void *xInit){ int rc = SQLITE_OK;#ifndef SQLITE_OMIT_AUTOINIT rc = sqlite3_initialize(); if( rc ){ return rc; }else#endif { int i;#ifndef SQLITE_MUTEX_NOOP sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);#endif sqlite3_mutex_enter(mutex); for(i=0; i<autoext.nExt; i++){ if( autoext.aExt[i]==xInit ) break; } if( i==autoext.nExt ){ int nByte = (autoext.nExt+1)*sizeof(autoext.aExt[0]); void **aNew; aNew = sqlite3_realloc(autoext.aExt, nByte); if( aNew==0 ){ rc = SQLITE_NOMEM; }else{ autoext.aExt = aNew; autoext.aExt[autoext.nExt] = xInit; autoext.nExt++; } } sqlite3_mutex_leave(mutex); assert( (rc&0xff)==rc ); return rc; }}/*** Reset the automatic extension loading mechanism.*/void sqlite3_reset_auto_extension(void){#ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize()==SQLITE_OK )#endif {#ifndef SQLITE_MUTEX_NOOP sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);#endif sqlite3_mutex_enter(mutex); sqlite3_free(autoext.aExt); autoext.aExt = 0; autoext.nExt = 0; sqlite3_mutex_leave(mutex); }}/*** Load all automatic extensions.*/int sqlite3AutoLoadExtensions(sqlite3 *db){ int i; int go = 1; int rc = SQLITE_OK; int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); if( autoext.nExt==0 ){ /* Common case: early out without every having to acquire a mutex */ return SQLITE_OK; } for(i=0; go; i++){ char *zErrmsg = 0;#ifndef SQLITE_MUTEX_NOOP sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);#endif sqlite3_mutex_enter(mutex); if( i>=autoext.nExt ){ xInit = 0; go = 0; }else{ xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*)) autoext.aExt[i]; } sqlite3_mutex_leave(mutex); if( xInit && xInit(db, &zErrmsg, &sqlite3Apis) ){ sqlite3Error(db, SQLITE_ERROR, "automatic extension loading failed: %s", zErrmsg); go = 0; rc = SQLITE_ERROR; sqlite3_free(zErrmsg); } } return rc;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -