| OLD | NEW |
| 1 /* | 1 /* |
| 2 ** 2004 May 22 | 2 ** 2004 May 22 |
| 3 ** | 3 ** |
| 4 ** The author disclaims copyright to this source code. In place of | 4 ** The author disclaims copyright to this source code. In place of |
| 5 ** a legal notice, here is a blessing: | 5 ** a legal notice, here is a blessing: |
| 6 ** | 6 ** |
| 7 ** May you do good and not evil. | 7 ** May you do good and not evil. |
| 8 ** May you find forgiveness for yourself and forgive others. | 8 ** May you find forgiveness for yourself and forgive others. |
| 9 ** May you share freely, never taking more than you give. | 9 ** May you share freely, never taking more than you give. |
| 10 ** | 10 ** |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 ** | 80 ** |
| 81 ** Device Characteristic flag handling: | 81 ** Device Characteristic flag handling: |
| 82 ** | 82 ** |
| 83 ** If the IOCAP_ATOMIC flag is set, then option (3) above is | 83 ** If the IOCAP_ATOMIC flag is set, then option (3) above is |
| 84 ** never selected. | 84 ** never selected. |
| 85 ** | 85 ** |
| 86 ** If the IOCAP_ATOMIC512 flag is set, and the WriteBuffer represents | 86 ** If the IOCAP_ATOMIC512 flag is set, and the WriteBuffer represents |
| 87 ** an aligned write() of an integer number of 512 byte regions, then | 87 ** an aligned write() of an integer number of 512 byte regions, then |
| 88 ** option (3) above is never selected. Instead, each 512 byte region | 88 ** option (3) above is never selected. Instead, each 512 byte region |
| 89 ** is either correctly written or left completely untouched. Similar | 89 ** is either correctly written or left completely untouched. Similar |
| 90 ** logic governs the behaviour if any of the other ATOMICXXX flags | 90 ** logic governs the behavior if any of the other ATOMICXXX flags |
| 91 ** is set. | 91 ** is set. |
| 92 ** | 92 ** |
| 93 ** If either the IOCAP_SAFEAPPEND or IOCAP_SEQUENTIAL flags are set | 93 ** If either the IOCAP_SAFEAPPEND or IOCAP_SEQUENTIAL flags are set |
| 94 ** and a crash is being simulated, then an entry of the write-list is | 94 ** and a crash is being simulated, then an entry of the write-list is |
| 95 ** selected at random. Everything in the list after the selected entry | 95 ** selected at random. Everything in the list after the selected entry |
| 96 ** is discarded before processing begins. | 96 ** is discarded before processing begins. |
| 97 ** | 97 ** |
| 98 ** If IOCAP_SEQUENTIAL is set and a crash is being simulated, option | 98 ** If IOCAP_SEQUENTIAL is set and a crash is being simulated, option |
| 99 ** (1) is selected for all write-list entries except the last. If a | 99 ** (1) is selected for all write-list entries except the last. If a |
| 100 ** crash is not being simulated, then all entries in the write-list | 100 ** crash is not being simulated, then all entries in the write-list |
| (...skipping 25 matching lines...) Expand all Loading... |
| 126 struct CrashFile { | 126 struct CrashFile { |
| 127 const sqlite3_io_methods *pMethod; /* Must be first */ | 127 const sqlite3_io_methods *pMethod; /* Must be first */ |
| 128 sqlite3_file *pRealFile; /* Underlying "real" file handle */ | 128 sqlite3_file *pRealFile; /* Underlying "real" file handle */ |
| 129 char *zName; | 129 char *zName; |
| 130 int flags; /* Flags the file was opened with */ | 130 int flags; /* Flags the file was opened with */ |
| 131 | 131 |
| 132 /* Cache of the entire file. This is used to speed up OsRead() and | 132 /* Cache of the entire file. This is used to speed up OsRead() and |
| 133 ** OsFileSize() calls. Although both could be done by traversing the | 133 ** OsFileSize() calls. Although both could be done by traversing the |
| 134 ** write-list, in practice this is impractically slow. | 134 ** write-list, in practice this is impractically slow. |
| 135 */ | 135 */ |
| 136 int iSize; /* Size of file in bytes */ | 136 u8 *zData; /* Buffer containing file contents */ |
| 137 int nData; /* Size of buffer allocated at zData */ | 137 int nData; /* Size of buffer allocated at zData */ |
| 138 u8 *zData; /* Buffer containing file contents */ | 138 i64 iSize; /* Size of file in bytes */ |
| 139 }; | 139 }; |
| 140 | 140 |
| 141 struct CrashGlobal { | 141 struct CrashGlobal { |
| 142 WriteBuffer *pWriteList; /* Head of write-list */ | 142 WriteBuffer *pWriteList; /* Head of write-list */ |
| 143 WriteBuffer *pWriteListEnd; /* End of write-list */ | 143 WriteBuffer *pWriteListEnd; /* End of write-list */ |
| 144 | 144 |
| 145 int iSectorSize; /* Value of simulated sector size */ | 145 int iSectorSize; /* Value of simulated sector size */ |
| 146 int iDeviceCharacteristics; /* Value of simulated device characteristics */ | 146 int iDeviceCharacteristics; /* Value of simulated device characteristics */ |
| 147 | 147 |
| 148 int iCrash; /* Crash on the iCrash'th call to xSync() */ | 148 int iCrash; /* Crash on the iCrash'th call to xSync() */ |
| (...skipping 17 matching lines...) Expand all Loading... |
| 166 return (void *)Tcl_Realloc(p, (size_t)n); | 166 return (void *)Tcl_Realloc(p, (size_t)n); |
| 167 } | 167 } |
| 168 | 168 |
| 169 /* | 169 /* |
| 170 ** Wrapper around the sqlite3OsWrite() function that avoids writing to the | 170 ** Wrapper around the sqlite3OsWrite() function that avoids writing to the |
| 171 ** 512 byte block begining at offset PENDING_BYTE. | 171 ** 512 byte block begining at offset PENDING_BYTE. |
| 172 */ | 172 */ |
| 173 static int writeDbFile(CrashFile *p, u8 *z, i64 iAmt, i64 iOff){ | 173 static int writeDbFile(CrashFile *p, u8 *z, i64 iAmt, i64 iOff){ |
| 174 int rc = SQLITE_OK; | 174 int rc = SQLITE_OK; |
| 175 int iSkip = 0; | 175 int iSkip = 0; |
| 176 if( iOff==PENDING_BYTE && (p->flags&SQLITE_OPEN_MAIN_DB) ){ | |
| 177 iSkip = 512; | |
| 178 } | |
| 179 if( (iAmt-iSkip)>0 ){ | 176 if( (iAmt-iSkip)>0 ){ |
| 180 rc = sqlite3OsWrite(p->pRealFile, &z[iSkip], iAmt-iSkip, iOff+iSkip); | 177 rc = sqlite3OsWrite(p->pRealFile, &z[iSkip], (int)(iAmt-iSkip), iOff+iSkip); |
| 181 } | 178 } |
| 182 return rc; | 179 return rc; |
| 183 } | 180 } |
| 184 | 181 |
| 185 /* | 182 /* |
| 186 ** Flush the write-list as if xSync() had been called on file handle | 183 ** Flush the write-list as if xSync() had been called on file handle |
| 187 ** pFile. If isCrash is true, simulate a crash. | 184 ** pFile. If isCrash is true, simulate a crash. |
| 188 */ | 185 */ |
| 189 static int writeListSync(CrashFile *pFile, int isCrash){ | 186 static int writeListSync(CrashFile *pFile, int isCrash){ |
| 190 int rc = SQLITE_OK; | 187 int rc = SQLITE_OK; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 if( isCrash ){ | 296 if( isCrash ){ |
| 300 printf("Omiting %d bytes @ %d (%s)\n", | 297 printf("Omiting %d bytes @ %d (%s)\n", |
| 301 pWrite->nBuf, (int)pWrite->iOffset, pWrite->pFile->zName | 298 pWrite->nBuf, (int)pWrite->iOffset, pWrite->pFile->zName |
| 302 ); | 299 ); |
| 303 } | 300 } |
| 304 #endif | 301 #endif |
| 305 break; | 302 break; |
| 306 } | 303 } |
| 307 case 3: { /* Trash sectors */ | 304 case 3: { /* Trash sectors */ |
| 308 u8 *zGarbage; | 305 u8 *zGarbage; |
| 309 int iFirst = (pWrite->iOffset/g.iSectorSize); | 306 int iFirst = (int)(pWrite->iOffset/g.iSectorSize); |
| 310 int iLast = (pWrite->iOffset+pWrite->nBuf-1)/g.iSectorSize; | 307 int iLast = (int)((pWrite->iOffset+pWrite->nBuf-1)/g.iSectorSize); |
| 311 | 308 |
| 312 assert(pWrite->zBuf); | 309 assert(pWrite->zBuf); |
| 313 | 310 |
| 314 #ifdef TRACE_CRASHTEST | 311 #ifdef TRACE_CRASHTEST |
| 315 printf("Trashing %d sectors @ sector %d (%s)\n", | 312 printf("Trashing %d sectors @ %lld (sector %d) (%s)\n", |
| 316 1+iLast-iFirst, iFirst, pWrite->pFile->zName | 313 1+iLast-iFirst, pWrite->iOffset, iFirst, pWrite->pFile->zName |
| 317 ); | 314 ); |
| 318 #endif | 315 #endif |
| 319 | 316 |
| 320 zGarbage = crash_malloc(g.iSectorSize); | 317 zGarbage = crash_malloc(g.iSectorSize); |
| 321 if( zGarbage ){ | 318 if( zGarbage ){ |
| 322 sqlite3_int64 i; | 319 sqlite3_int64 i; |
| 323 for(i=iFirst; rc==SQLITE_OK && i<=iLast; i++){ | 320 for(i=iFirst; rc==SQLITE_OK && i<=iLast; i++){ |
| 324 sqlite3_randomness(g.iSectorSize, zGarbage); | 321 sqlite3_randomness(g.iSectorSize, zGarbage); |
| 325 rc = writeDbFile( | 322 rc = writeDbFile( |
| 326 pWrite->pFile, zGarbage, g.iSectorSize, i*g.iSectorSize | 323 pWrite->pFile, zGarbage, g.iSectorSize, i*g.iSectorSize |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 /* | 399 /* |
| 403 ** Read data from a crash-file. | 400 ** Read data from a crash-file. |
| 404 */ | 401 */ |
| 405 static int cfRead( | 402 static int cfRead( |
| 406 sqlite3_file *pFile, | 403 sqlite3_file *pFile, |
| 407 void *zBuf, | 404 void *zBuf, |
| 408 int iAmt, | 405 int iAmt, |
| 409 sqlite_int64 iOfst | 406 sqlite_int64 iOfst |
| 410 ){ | 407 ){ |
| 411 CrashFile *pCrash = (CrashFile *)pFile; | 408 CrashFile *pCrash = (CrashFile *)pFile; |
| 409 int nCopy = (int)MIN((i64)iAmt, (pCrash->iSize - iOfst)); |
| 410 |
| 411 if( nCopy>0 ){ |
| 412 memcpy(zBuf, &pCrash->zData[iOfst], nCopy); |
| 413 } |
| 412 | 414 |
| 413 /* Check the file-size to see if this is a short-read */ | 415 /* Check the file-size to see if this is a short-read */ |
| 414 if( pCrash->iSize<(iOfst+iAmt) ){ | 416 if( nCopy<iAmt ){ |
| 415 return SQLITE_IOERR_SHORT_READ; | 417 return SQLITE_IOERR_SHORT_READ; |
| 416 } | 418 } |
| 417 | 419 |
| 418 memcpy(zBuf, &pCrash->zData[iOfst], iAmt); | |
| 419 return SQLITE_OK; | 420 return SQLITE_OK; |
| 420 } | 421 } |
| 421 | 422 |
| 422 /* | 423 /* |
| 423 ** Write data to a crash-file. | 424 ** Write data to a crash-file. |
| 424 */ | 425 */ |
| 425 static int cfWrite( | 426 static int cfWrite( |
| 426 sqlite3_file *pFile, | 427 sqlite3_file *pFile, |
| 427 const void *zBuf, | 428 const void *zBuf, |
| 428 int iAmt, | 429 int iAmt, |
| 429 sqlite_int64 iOfst | 430 sqlite_int64 iOfst |
| 430 ){ | 431 ){ |
| 431 CrashFile *pCrash = (CrashFile *)pFile; | 432 CrashFile *pCrash = (CrashFile *)pFile; |
| 432 if( iAmt+iOfst>pCrash->iSize ){ | 433 if( iAmt+iOfst>pCrash->iSize ){ |
| 433 pCrash->iSize = iAmt+iOfst; | 434 pCrash->iSize = (int)(iAmt+iOfst); |
| 434 } | 435 } |
| 435 while( pCrash->iSize>pCrash->nData ){ | 436 while( pCrash->iSize>pCrash->nData ){ |
| 436 u8 *zNew; | 437 u8 *zNew; |
| 437 int nNew = (pCrash->nData*2) + 4096; | 438 int nNew = (pCrash->nData*2) + 4096; |
| 438 zNew = crash_realloc(pCrash->zData, nNew); | 439 zNew = crash_realloc(pCrash->zData, nNew); |
| 439 if( !zNew ){ | 440 if( !zNew ){ |
| 440 return SQLITE_NOMEM; | 441 return SQLITE_NOMEM; |
| 441 } | 442 } |
| 442 memset(&zNew[pCrash->nData], 0, nNew-pCrash->nData); | 443 memset(&zNew[pCrash->nData], 0, nNew-pCrash->nData); |
| 443 pCrash->nData = nNew; | 444 pCrash->nData = nNew; |
| 444 pCrash->zData = zNew; | 445 pCrash->zData = zNew; |
| 445 } | 446 } |
| 446 memcpy(&pCrash->zData[iOfst], zBuf, iAmt); | 447 memcpy(&pCrash->zData[iOfst], zBuf, iAmt); |
| 447 return writeListAppend(pFile, iOfst, zBuf, iAmt); | 448 return writeListAppend(pFile, iOfst, zBuf, iAmt); |
| 448 } | 449 } |
| 449 | 450 |
| 450 /* | 451 /* |
| 451 ** Truncate a crash-file. | 452 ** Truncate a crash-file. |
| 452 */ | 453 */ |
| 453 static int cfTruncate(sqlite3_file *pFile, sqlite_int64 size){ | 454 static int cfTruncate(sqlite3_file *pFile, sqlite_int64 size){ |
| 454 CrashFile *pCrash = (CrashFile *)pFile; | 455 CrashFile *pCrash = (CrashFile *)pFile; |
| 455 assert(size>=0); | 456 assert(size>=0); |
| 456 if( pCrash->iSize>size ){ | 457 if( pCrash->iSize>size ){ |
| 457 pCrash->iSize = size; | 458 pCrash->iSize = (int)size; |
| 458 } | 459 } |
| 459 return writeListAppend(pFile, size, 0, 0); | 460 return writeListAppend(pFile, size, 0, 0); |
| 460 } | 461 } |
| 461 | 462 |
| 462 /* | 463 /* |
| 463 ** Sync a crash-file. | 464 ** Sync a crash-file. |
| 464 */ | 465 */ |
| 465 static int cfSync(sqlite3_file *pFile, int flags){ | 466 static int cfSync(sqlite3_file *pFile, int flags){ |
| 466 CrashFile *pCrash = (CrashFile *)pFile; | 467 CrashFile *pCrash = (CrashFile *)pFile; |
| 467 int isCrash = 0; | 468 int isCrash = 0; |
| 468 | 469 |
| 469 const char *zName = pCrash->zName; | 470 const char *zName = pCrash->zName; |
| 470 const char *zCrashFile = g.zCrashFile; | 471 const char *zCrashFile = g.zCrashFile; |
| 471 int nName = strlen(zName); | 472 int nName = (int)strlen(zName); |
| 472 int nCrashFile = strlen(zCrashFile); | 473 int nCrashFile = (int)strlen(zCrashFile); |
| 473 | 474 |
| 474 if( nCrashFile>0 && zCrashFile[nCrashFile-1]=='*' ){ | 475 if( nCrashFile>0 && zCrashFile[nCrashFile-1]=='*' ){ |
| 475 nCrashFile--; | 476 nCrashFile--; |
| 476 if( nName>nCrashFile ) nName = nCrashFile; | 477 if( nName>nCrashFile ) nName = nCrashFile; |
| 477 } | 478 } |
| 478 | 479 |
| 480 #ifdef TRACE_CRASHTEST |
| 481 printf("cfSync(): nName = %d, nCrashFile = %d, zName = %s, zCrashFile = %s\n", |
| 482 nName, nCrashFile, zName, zCrashFile); |
| 483 #endif |
| 484 |
| 479 if( nName==nCrashFile && 0==memcmp(zName, zCrashFile, nName) ){ | 485 if( nName==nCrashFile && 0==memcmp(zName, zCrashFile, nName) ){ |
| 486 #ifdef TRACE_CRASHTEST |
| 487 printf("cfSync(): name matched, g.iCrash = %d\n", g.iCrash); |
| 488 #endif |
| 480 if( (--g.iCrash)==0 ) isCrash = 1; | 489 if( (--g.iCrash)==0 ) isCrash = 1; |
| 481 } | 490 } |
| 482 | 491 |
| 483 return writeListSync(pCrash, isCrash); | 492 return writeListSync(pCrash, isCrash); |
| 484 } | 493 } |
| 485 | 494 |
| 486 /* | 495 /* |
| 487 ** Return the current file-size of the crash-file. | 496 ** Return the current file-size of the crash-file. |
| 488 */ | 497 */ |
| 489 static int cfFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ | 498 static int cfFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ |
| 490 CrashFile *pCrash = (CrashFile *)pFile; | 499 CrashFile *pCrash = (CrashFile *)pFile; |
| 491 *pSize = (i64)pCrash->iSize; | 500 *pSize = (i64)pCrash->iSize; |
| 492 return SQLITE_OK; | 501 return SQLITE_OK; |
| 493 } | 502 } |
| 494 | 503 |
| 495 /* | 504 /* |
| 496 ** Calls related to file-locks are passed on to the real file handle. | 505 ** Calls related to file-locks are passed on to the real file handle. |
| 497 */ | 506 */ |
| 498 static int cfLock(sqlite3_file *pFile, int eLock){ | 507 static int cfLock(sqlite3_file *pFile, int eLock){ |
| 499 return sqlite3OsLock(((CrashFile *)pFile)->pRealFile, eLock); | 508 return sqlite3OsLock(((CrashFile *)pFile)->pRealFile, eLock); |
| 500 } | 509 } |
| 501 static int cfUnlock(sqlite3_file *pFile, int eLock){ | 510 static int cfUnlock(sqlite3_file *pFile, int eLock){ |
| 502 return sqlite3OsUnlock(((CrashFile *)pFile)->pRealFile, eLock); | 511 return sqlite3OsUnlock(((CrashFile *)pFile)->pRealFile, eLock); |
| 503 } | 512 } |
| 504 static int cfCheckReservedLock(sqlite3_file *pFile, int *pResOut){ | 513 static int cfCheckReservedLock(sqlite3_file *pFile, int *pResOut){ |
| 505 return sqlite3OsCheckReservedLock(((CrashFile *)pFile)->pRealFile, pResOut); | 514 return sqlite3OsCheckReservedLock(((CrashFile *)pFile)->pRealFile, pResOut); |
| 506 } | 515 } |
| 507 static int cfFileControl(sqlite3_file *pFile, int op, void *pArg){ | 516 static int cfFileControl(sqlite3_file *pFile, int op, void *pArg){ |
| 517 if( op==SQLITE_FCNTL_SIZE_HINT ){ |
| 518 CrashFile *pCrash = (CrashFile *)pFile; |
| 519 i64 nByte = *(i64 *)pArg; |
| 520 if( nByte>pCrash->iSize ){ |
| 521 if( SQLITE_OK==writeListAppend(pFile, nByte, 0, 0) ){ |
| 522 pCrash->iSize = (int)nByte; |
| 523 } |
| 524 } |
| 525 return SQLITE_OK; |
| 526 } |
| 508 return sqlite3OsFileControl(((CrashFile *)pFile)->pRealFile, op, pArg); | 527 return sqlite3OsFileControl(((CrashFile *)pFile)->pRealFile, op, pArg); |
| 509 } | 528 } |
| 510 | 529 |
| 511 /* | 530 /* |
| 512 ** The xSectorSize() and xDeviceCharacteristics() functions return | 531 ** The xSectorSize() and xDeviceCharacteristics() functions return |
| 513 ** the global values configured by the [sqlite_crashparams] tcl | 532 ** the global values configured by the [sqlite_crashparams] tcl |
| 514 * interface. | 533 * interface. |
| 515 */ | 534 */ |
| 516 static int cfSectorSize(sqlite3_file *pFile){ | 535 static int cfSectorSize(sqlite3_file *pFile){ |
| 517 return g.iSectorSize; | 536 return g.iSectorSize; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 596 if( rc==SQLITE_OK ){ | 615 if( rc==SQLITE_OK ){ |
| 597 i64 iSize; | 616 i64 iSize; |
| 598 pWrapper->pMethod = &CrashFileVtab; | 617 pWrapper->pMethod = &CrashFileVtab; |
| 599 pWrapper->zName = (char *)zName; | 618 pWrapper->zName = (char *)zName; |
| 600 pWrapper->pRealFile = pReal; | 619 pWrapper->pRealFile = pReal; |
| 601 rc = sqlite3OsFileSize(pReal, &iSize); | 620 rc = sqlite3OsFileSize(pReal, &iSize); |
| 602 pWrapper->iSize = (int)iSize; | 621 pWrapper->iSize = (int)iSize; |
| 603 pWrapper->flags = flags; | 622 pWrapper->flags = flags; |
| 604 } | 623 } |
| 605 if( rc==SQLITE_OK ){ | 624 if( rc==SQLITE_OK ){ |
| 606 pWrapper->nData = (4096 + pWrapper->iSize); | 625 pWrapper->nData = (int)(4096 + pWrapper->iSize); |
| 607 pWrapper->zData = crash_malloc(pWrapper->nData); | 626 pWrapper->zData = crash_malloc(pWrapper->nData); |
| 608 if( pWrapper->zData ){ | 627 if( pWrapper->zData ){ |
| 609 /* os_unix.c contains an assert() that fails if the caller attempts | 628 /* os_unix.c contains an assert() that fails if the caller attempts |
| 610 ** to read data from the 512-byte locking region of a file opened | 629 ** to read data from the 512-byte locking region of a file opened |
| 611 ** with the SQLITE_OPEN_MAIN_DB flag. This region of a database file | 630 ** with the SQLITE_OPEN_MAIN_DB flag. This region of a database file |
| 612 ** never contains valid data anyhow. So avoid doing such a read here. | 631 ** never contains valid data anyhow. So avoid doing such a read here. |
| 632 ** |
| 633 ** UPDATE: It also contains an assert() verifying that each call |
| 634 ** to the xRead() method reads less than 128KB of data. |
| 613 */ | 635 */ |
| 614 const int isDb = (flags&SQLITE_OPEN_MAIN_DB); | 636 i64 iOff; |
| 615 i64 iChunk = pWrapper->iSize; | 637 |
| 616 if( iChunk>PENDING_BYTE && isDb ){ | |
| 617 iChunk = PENDING_BYTE; | |
| 618 } | |
| 619 memset(pWrapper->zData, 0, pWrapper->nData); | 638 memset(pWrapper->zData, 0, pWrapper->nData); |
| 620 rc = sqlite3OsRead(pReal, pWrapper->zData, iChunk, 0); | 639 for(iOff=0; iOff<pWrapper->iSize; iOff += 512){ |
| 621 if( SQLITE_OK==rc && pWrapper->iSize>(PENDING_BYTE+512) && isDb ){ | 640 int nRead = (int)(pWrapper->iSize - iOff); |
| 622 i64 iOff = PENDING_BYTE+512; | 641 if( nRead>512 ) nRead = 512; |
| 623 iChunk = pWrapper->iSize - iOff; | 642 rc = sqlite3OsRead(pReal, &pWrapper->zData[iOff], nRead, iOff); |
| 624 rc = sqlite3OsRead(pReal, &pWrapper->zData[iOff], iChunk, iOff); | |
| 625 } | 643 } |
| 626 }else{ | 644 }else{ |
| 627 rc = SQLITE_NOMEM; | 645 rc = SQLITE_NOMEM; |
| 628 } | 646 } |
| 629 } | 647 } |
| 630 if( rc!=SQLITE_OK && pWrapper->pMethod ){ | 648 if( rc!=SQLITE_OK && pWrapper->pMethod ){ |
| 631 sqlite3OsClose(pFile); | 649 sqlite3OsClose(pFile); |
| 632 } | 650 } |
| 633 return rc; | 651 return rc; |
| 634 } | 652 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 Tcl_Interp *interp, | 706 Tcl_Interp *interp, |
| 689 int objc, | 707 int objc, |
| 690 Tcl_Obj *CONST objv[], | 708 Tcl_Obj *CONST objv[], |
| 691 int *piDeviceChar, | 709 int *piDeviceChar, |
| 692 int *piSectorSize | 710 int *piSectorSize |
| 693 ){ | 711 ){ |
| 694 struct DeviceFlag { | 712 struct DeviceFlag { |
| 695 char *zName; | 713 char *zName; |
| 696 int iValue; | 714 int iValue; |
| 697 } aFlag[] = { | 715 } aFlag[] = { |
| 698 { "atomic", SQLITE_IOCAP_ATOMIC }, | 716 { "atomic", SQLITE_IOCAP_ATOMIC }, |
| 699 { "atomic512", SQLITE_IOCAP_ATOMIC512 }, | 717 { "atomic512", SQLITE_IOCAP_ATOMIC512 }, |
| 700 { "atomic1k", SQLITE_IOCAP_ATOMIC1K }, | 718 { "atomic1k", SQLITE_IOCAP_ATOMIC1K }, |
| 701 { "atomic2k", SQLITE_IOCAP_ATOMIC2K }, | 719 { "atomic2k", SQLITE_IOCAP_ATOMIC2K }, |
| 702 { "atomic4k", SQLITE_IOCAP_ATOMIC4K }, | 720 { "atomic4k", SQLITE_IOCAP_ATOMIC4K }, |
| 703 { "atomic8k", SQLITE_IOCAP_ATOMIC8K }, | 721 { "atomic8k", SQLITE_IOCAP_ATOMIC8K }, |
| 704 { "atomic16k", SQLITE_IOCAP_ATOMIC16K }, | 722 { "atomic16k", SQLITE_IOCAP_ATOMIC16K }, |
| 705 { "atomic32k", SQLITE_IOCAP_ATOMIC32K }, | 723 { "atomic32k", SQLITE_IOCAP_ATOMIC32K }, |
| 706 { "atomic64k", SQLITE_IOCAP_ATOMIC64K }, | 724 { "atomic64k", SQLITE_IOCAP_ATOMIC64K }, |
| 707 { "sequential", SQLITE_IOCAP_SEQUENTIAL }, | 725 { "sequential", SQLITE_IOCAP_SEQUENTIAL }, |
| 708 { "safe_append", SQLITE_IOCAP_SAFE_APPEND }, | 726 { "safe_append", SQLITE_IOCAP_SAFE_APPEND }, |
| 727 { "powersafe_overwrite", SQLITE_IOCAP_POWERSAFE_OVERWRITE }, |
| 709 { 0, 0 } | 728 { 0, 0 } |
| 710 }; | 729 }; |
| 711 | 730 |
| 712 int i; | 731 int i; |
| 713 int iDc = 0; | 732 int iDc = 0; |
| 714 int iSectorSize = 0; | 733 int iSectorSize = 0; |
| 715 int setSectorsize = 0; | 734 int setSectorsize = 0; |
| 716 int setDeviceChar = 0; | 735 int setDeviceChar = 0; |
| 717 | 736 |
| 718 for(i=0; i<objc; i+=2){ | 737 for(i=0; i<objc; i+=2){ |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 991 Tcl_CreateObjCommand(interp, "sqlite3_crash_enable", crashEnableCmd, 0, 0); | 1010 Tcl_CreateObjCommand(interp, "sqlite3_crash_enable", crashEnableCmd, 0, 0); |
| 992 Tcl_CreateObjCommand(interp, "sqlite3_crashparams", crashParamsObjCmd, 0, 0); | 1011 Tcl_CreateObjCommand(interp, "sqlite3_crashparams", crashParamsObjCmd, 0, 0); |
| 993 Tcl_CreateObjCommand(interp, "sqlite3_simulate_device", devSymObjCmd, 0, 0); | 1012 Tcl_CreateObjCommand(interp, "sqlite3_simulate_device", devSymObjCmd, 0, 0); |
| 994 Tcl_CreateObjCommand(interp, "register_jt_vfs", jtObjCmd, 0, 0); | 1013 Tcl_CreateObjCommand(interp, "register_jt_vfs", jtObjCmd, 0, 0); |
| 995 Tcl_CreateObjCommand(interp, "unregister_jt_vfs", jtUnregisterObjCmd, 0, 0); | 1014 Tcl_CreateObjCommand(interp, "unregister_jt_vfs", jtUnregisterObjCmd, 0, 0); |
| 996 #endif | 1015 #endif |
| 997 return TCL_OK; | 1016 return TCL_OK; |
| 998 } | 1017 } |
| 999 | 1018 |
| 1000 #endif /* SQLITE_TEST */ | 1019 #endif /* SQLITE_TEST */ |
| OLD | NEW |