extensions/sqlite/sqlite-source/os.c
author David Anderson <dvander@alliedmods.net>
Sun Aug 30 01:54:45 2009 -0700 (2009-08-30)
changeset 2790 6dd851ba15fd
parent 1952 b7aa2b626807
permissions -rw-r--r--
Fixed extension version reporting.
ds@1952
     1
 /*
ds@1952
     2
** 2005 November 29
ds@1952
     3
**
ds@1952
     4
** The author disclaims copyright to this source code.  In place of
ds@1952
     5
** a legal notice, here is a blessing:
ds@1952
     6
**
ds@1952
     7
**    May you do good and not evil.
ds@1952
     8
**    May you find forgiveness for yourself and forgive others.
ds@1952
     9
**    May you share freely, never taking more than you give.
ds@1952
    10
**
ds@1952
    11
******************************************************************************
ds@1952
    12
**
ds@1952
    13
** This file contains OS interface code that is common to all
ds@1952
    14
** architectures.
ds@1952
    15
*/
ds@1952
    16
#define _SQLITE_OS_C_ 1
ds@1952
    17
#include "sqliteInt.h"
ds@1952
    18
#undef _SQLITE_OS_C_
ds@1952
    19
ds@1952
    20
/*
ds@1952
    21
** The default SQLite sqlite3_vfs implementations do not allocate
ds@1952
    22
** memory (actually, os_unix.c allocates a small amount of memory
ds@1952
    23
** from within OsOpen()), but some third-party implementations may.
ds@1952
    24
** So we test the effects of a malloc() failing and the sqlite3OsXXX()
ds@1952
    25
** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro.
ds@1952
    26
**
ds@1952
    27
** The following functions are instrumented for malloc() failure 
ds@1952
    28
** testing:
ds@1952
    29
**
ds@1952
    30
**     sqlite3OsOpen()
ds@1952
    31
**     sqlite3OsRead()
ds@1952
    32
**     sqlite3OsWrite()
ds@1952
    33
**     sqlite3OsSync()
ds@1952
    34
**     sqlite3OsLock()
ds@1952
    35
**
ds@1952
    36
*/
ds@1952
    37
#ifdef SQLITE_TEST
ds@1952
    38
  #define DO_OS_MALLOC_TEST if (1) {            \
ds@1952
    39
    void *pTstAlloc = sqlite3_malloc(10);       \
ds@1952
    40
    if (!pTstAlloc) return SQLITE_IOERR_NOMEM;  \
ds@1952
    41
    sqlite3_free(pTstAlloc);                    \
ds@1952
    42
  }
ds@1952
    43
#else
ds@1952
    44
  #define DO_OS_MALLOC_TEST
ds@1952
    45
#endif
ds@1952
    46
ds@1952
    47
/*
ds@1952
    48
** The following routines are convenience wrappers around methods
ds@1952
    49
** of the sqlite3_file object.  This is mostly just syntactic sugar. All
ds@1952
    50
** of this would be completely automatic if SQLite were coded using
ds@1952
    51
** C++ instead of plain old C.
ds@1952
    52
*/
ds@1952
    53
int sqlite3OsClose(sqlite3_file *pId){
ds@1952
    54
  int rc = SQLITE_OK;
ds@1952
    55
  if( pId->pMethods ){
ds@1952
    56
    rc = pId->pMethods->xClose(pId);
ds@1952
    57
    pId->pMethods = 0;
ds@1952
    58
  }
ds@1952
    59
  return rc;
ds@1952
    60
}
ds@1952
    61
int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
ds@1952
    62
  DO_OS_MALLOC_TEST;
ds@1952
    63
  return id->pMethods->xRead(id, pBuf, amt, offset);
ds@1952
    64
}
ds@1952
    65
int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
ds@1952
    66
  DO_OS_MALLOC_TEST;
ds@1952
    67
  return id->pMethods->xWrite(id, pBuf, amt, offset);
ds@1952
    68
}
ds@1952
    69
int sqlite3OsTruncate(sqlite3_file *id, i64 size){
ds@1952
    70
  return id->pMethods->xTruncate(id, size);
ds@1952
    71
}
ds@1952
    72
int sqlite3OsSync(sqlite3_file *id, int flags){
ds@1952
    73
  DO_OS_MALLOC_TEST;
ds@1952
    74
  return id->pMethods->xSync(id, flags);
ds@1952
    75
}
ds@1952
    76
int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
ds@1952
    77
  return id->pMethods->xFileSize(id, pSize);
ds@1952
    78
}
ds@1952
    79
int sqlite3OsLock(sqlite3_file *id, int lockType){
ds@1952
    80
  DO_OS_MALLOC_TEST;
ds@1952
    81
  return id->pMethods->xLock(id, lockType);
ds@1952
    82
}
ds@1952
    83
int sqlite3OsUnlock(sqlite3_file *id, int lockType){
ds@1952
    84
  return id->pMethods->xUnlock(id, lockType);
ds@1952
    85
}
ds@1952
    86
int sqlite3OsCheckReservedLock(sqlite3_file *id){
ds@1952
    87
  return id->pMethods->xCheckReservedLock(id);
ds@1952
    88
}
ds@1952
    89
int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
ds@1952
    90
  return id->pMethods->xFileControl(id,op,pArg);
ds@1952
    91
}
ds@1952
    92
ds@1952
    93
#ifdef SQLITE_TEST
ds@1952
    94
  /* The following two variables are used to override the values returned
ds@1952
    95
  ** by the xSectorSize() and xDeviceCharacteristics() vfs methods for
ds@1952
    96
  ** testing purposes. They are usually set by a test command implemented
ds@1952
    97
  ** in test6.c.
ds@1952
    98
  */
ds@1952
    99
  int sqlite3_test_sector_size = 0;
ds@1952
   100
  int sqlite3_test_device_characteristics = 0;
ds@1952
   101
  int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
ds@1952
   102
    int dc = id->pMethods->xDeviceCharacteristics(id);
ds@1952
   103
    return dc | sqlite3_test_device_characteristics;
ds@1952
   104
  }
ds@1952
   105
  int sqlite3OsSectorSize(sqlite3_file *id){
ds@1952
   106
    if( sqlite3_test_sector_size==0 ){
ds@1952
   107
      int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
ds@1952
   108
      return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
ds@1952
   109
    }
ds@1952
   110
    return sqlite3_test_sector_size;
ds@1952
   111
  }
ds@1952
   112
#else
ds@1952
   113
  int sqlite3OsSectorSize(sqlite3_file *id){
ds@1952
   114
    int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
ds@1952
   115
    return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
ds@1952
   116
  }
ds@1952
   117
  int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
ds@1952
   118
    return id->pMethods->xDeviceCharacteristics(id);
ds@1952
   119
  }
ds@1952
   120
#endif
ds@1952
   121
ds@1952
   122
/*
ds@1952
   123
** The next group of routines are convenience wrappers around the
ds@1952
   124
** VFS methods.
ds@1952
   125
*/
ds@1952
   126
int sqlite3OsOpen(
ds@1952
   127
  sqlite3_vfs *pVfs, 
ds@1952
   128
  const char *zPath, 
ds@1952
   129
  sqlite3_file *pFile, 
ds@1952
   130
  int flags, 
ds@1952
   131
  int *pFlagsOut
ds@1952
   132
){
ds@1952
   133
  DO_OS_MALLOC_TEST;
ds@1952
   134
  return pVfs->xOpen(pVfs, zPath, pFile, flags, pFlagsOut);
ds@1952
   135
}
ds@1952
   136
int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
ds@1952
   137
  return pVfs->xDelete(pVfs, zPath, dirSync);
ds@1952
   138
}
ds@1952
   139
int sqlite3OsAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){
ds@1952
   140
  return pVfs->xAccess(pVfs, zPath, flags);
ds@1952
   141
}
ds@1952
   142
int sqlite3OsGetTempname(sqlite3_vfs *pVfs, int nBufOut, char *zBufOut){
ds@1952
   143
  return pVfs->xGetTempname(pVfs, nBufOut, zBufOut);
ds@1952
   144
}
ds@1952
   145
int sqlite3OsFullPathname(
ds@1952
   146
  sqlite3_vfs *pVfs, 
ds@1952
   147
  const char *zPath, 
ds@1952
   148
  int nPathOut, 
ds@1952
   149
  char *zPathOut
ds@1952
   150
){
ds@1952
   151
  return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
ds@1952
   152
}
ds@1952
   153
void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
ds@1952
   154
  return pVfs->xDlOpen(pVfs, zPath);
ds@1952
   155
}
ds@1952
   156
void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
ds@1952
   157
  pVfs->xDlError(pVfs, nByte, zBufOut);
ds@1952
   158
}
ds@1952
   159
void *sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
ds@1952
   160
  return pVfs->xDlSym(pVfs, pHandle, zSymbol);
ds@1952
   161
}
ds@1952
   162
void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
ds@1952
   163
  pVfs->xDlClose(pVfs, pHandle);
ds@1952
   164
}
ds@1952
   165
int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
ds@1952
   166
  return pVfs->xRandomness(pVfs, nByte, zBufOut);
ds@1952
   167
}
ds@1952
   168
int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
ds@1952
   169
  return pVfs->xSleep(pVfs, nMicro);
ds@1952
   170
}
ds@1952
   171
int sqlite3OsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
ds@1952
   172
  return pVfs->xCurrentTime(pVfs, pTimeOut);
ds@1952
   173
}
ds@1952
   174
ds@1952
   175
int sqlite3OsOpenMalloc(
ds@1952
   176
  sqlite3_vfs *pVfs, 
ds@1952
   177
  const char *zFile, 
ds@1952
   178
  sqlite3_file **ppFile, 
ds@1952
   179
  int flags,
ds@1952
   180
  int *pOutFlags
ds@1952
   181
){
ds@1952
   182
  int rc = SQLITE_NOMEM;
ds@1952
   183
  sqlite3_file *pFile;
ds@1952
   184
  pFile = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile);
ds@1952
   185
  if( pFile ){
ds@1952
   186
    rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
ds@1952
   187
    if( rc!=SQLITE_OK ){
ds@1952
   188
      sqlite3_free(pFile);
ds@1952
   189
    }else{
ds@1952
   190
      *ppFile = pFile;
ds@1952
   191
    }
ds@1952
   192
  }
ds@1952
   193
  return rc;
ds@1952
   194
}
ds@1952
   195
int sqlite3OsCloseFree(sqlite3_file *pFile){
ds@1952
   196
  int rc = SQLITE_OK;
ds@1952
   197
  if( pFile ){
ds@1952
   198
    rc = sqlite3OsClose(pFile);
ds@1952
   199
    sqlite3_free(pFile);
ds@1952
   200
  }
ds@1952
   201
  return rc;
ds@1952
   202
}
ds@1952
   203
ds@1952
   204
/*
ds@1952
   205
** The list of all registered VFS implementations.  This list is
ds@1952
   206
** initialized to the single VFS returned by sqlite3OsDefaultVfs()
ds@1952
   207
** upon the first call to sqlite3_vfs_find().
ds@1952
   208
*/
ds@1952
   209
static sqlite3_vfs *vfsList = 0;
ds@1952
   210
ds@1952
   211
/*
ds@1952
   212
** Locate a VFS by name.  If no name is given, simply return the
ds@1952
   213
** first VFS on the list.
ds@1952
   214
*/
ds@1952
   215
sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
ds@1952
   216
  sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
ds@1952
   217
  sqlite3_vfs *pVfs;
ds@1952
   218
  static int isInit = 0;
ds@1952
   219
  sqlite3_mutex_enter(mutex);
ds@1952
   220
  if( !isInit ){
ds@1952
   221
    vfsList = sqlite3OsDefaultVfs();
ds@1952
   222
    isInit = 1;
ds@1952
   223
  }
ds@1952
   224
  for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
ds@1952
   225
    if( zVfs==0 ) break;
ds@1952
   226
    if( strcmp(zVfs, pVfs->zName)==0 ) break;
ds@1952
   227
  }
ds@1952
   228
  sqlite3_mutex_leave(mutex);
ds@1952
   229
  return pVfs;
ds@1952
   230
}
ds@1952
   231
ds@1952
   232
/*
ds@1952
   233
** Unlink a VFS from the linked list
ds@1952
   234
*/
ds@1952
   235
static void vfsUnlink(sqlite3_vfs *pVfs){
ds@1952
   236
  assert( sqlite3_mutex_held(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)) );
ds@1952
   237
  if( vfsList==pVfs ){
ds@1952
   238
    vfsList = pVfs->pNext;
ds@1952
   239
  }else{
ds@1952
   240
    sqlite3_vfs *p = vfsList;
ds@1952
   241
    while( p->pNext && p->pNext!=pVfs ){
ds@1952
   242
      p = p->pNext;
ds@1952
   243
    }
ds@1952
   244
    if( p->pNext==pVfs ){
ds@1952
   245
      p->pNext = pVfs->pNext;
ds@1952
   246
    }
ds@1952
   247
  }
ds@1952
   248
}
ds@1952
   249
ds@1952
   250
/*
ds@1952
   251
** Register a VFS with the system.  It is harmless to register the same
ds@1952
   252
** VFS multiple times.  The new VFS becomes the default if makeDflt is
ds@1952
   253
** true.
ds@1952
   254
*/
ds@1952
   255
int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
ds@1952
   256
  sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
ds@1952
   257
  sqlite3_vfs_find(0);  /* Make sure we are initialized */
ds@1952
   258
  sqlite3_mutex_enter(mutex);
ds@1952
   259
  vfsUnlink(pVfs);
ds@1952
   260
  if( makeDflt || vfsList==0 ){
ds@1952
   261
    pVfs->pNext = vfsList;
ds@1952
   262
    vfsList = pVfs;
ds@1952
   263
  }else{
ds@1952
   264
    pVfs->pNext = vfsList->pNext;
ds@1952
   265
    vfsList->pNext = pVfs;
ds@1952
   266
  }
ds@1952
   267
  assert(vfsList);
ds@1952
   268
  sqlite3_mutex_leave(mutex);
ds@1952
   269
  return SQLITE_OK;
ds@1952
   270
}
ds@1952
   271
ds@1952
   272
/*
ds@1952
   273
** Unregister a VFS so that it is no longer accessible.
ds@1952
   274
*/
ds@1952
   275
int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
ds@1952
   276
  sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
ds@1952
   277
  sqlite3_mutex_enter(mutex);
ds@1952
   278
  vfsUnlink(pVfs);
ds@1952
   279
  assert(vfsList);
ds@1952
   280
  sqlite3_mutex_leave(mutex);
ds@1952
   281
  return SQLITE_OK;
ds@1952
   282
}