OLD | NEW |
1 /* | 1 /* |
2 ** 2005 December 14 | 2 ** 2005 December 14 |
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 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 ** This method holds the mutex from start to finish. | 660 ** This method holds the mutex from start to finish. |
661 */ | 661 */ |
662 static int asyncRead( | 662 static int asyncRead( |
663 sqlite3_file *pFile, | 663 sqlite3_file *pFile, |
664 void *zOut, | 664 void *zOut, |
665 int iAmt, | 665 int iAmt, |
666 sqlite3_int64 iOffset | 666 sqlite3_int64 iOffset |
667 ){ | 667 ){ |
668 AsyncFileData *p = ((AsyncFile *)pFile)->pData; | 668 AsyncFileData *p = ((AsyncFile *)pFile)->pData; |
669 int rc = SQLITE_OK; | 669 int rc = SQLITE_OK; |
670 sqlite3_int64 filesize; | 670 sqlite3_int64 filesize = 0; |
671 int nRead; | |
672 sqlite3_file *pBase = p->pBaseRead; | 671 sqlite3_file *pBase = p->pBaseRead; |
| 672 sqlite3_int64 iAmt64 = (sqlite3_int64)iAmt; |
673 | 673 |
674 /* Grab the write queue mutex for the duration of the call */ | 674 /* Grab the write queue mutex for the duration of the call */ |
675 async_mutex_enter(ASYNC_MUTEX_QUEUE); | 675 async_mutex_enter(ASYNC_MUTEX_QUEUE); |
676 | 676 |
677 /* If an I/O error has previously occurred in this virtual file | 677 /* If an I/O error has previously occurred in this virtual file |
678 ** system, then all subsequent operations fail. | 678 ** system, then all subsequent operations fail. |
679 */ | 679 */ |
680 if( async.ioError!=SQLITE_OK ){ | 680 if( async.ioError!=SQLITE_OK ){ |
681 rc = async.ioError; | 681 rc = async.ioError; |
682 goto asyncread_out; | 682 goto asyncread_out; |
683 } | 683 } |
684 | 684 |
685 if( pBase->pMethods ){ | 685 if( pBase->pMethods ){ |
| 686 sqlite3_int64 nRead; |
686 rc = pBase->pMethods->xFileSize(pBase, &filesize); | 687 rc = pBase->pMethods->xFileSize(pBase, &filesize); |
687 if( rc!=SQLITE_OK ){ | 688 if( rc!=SQLITE_OK ){ |
688 goto asyncread_out; | 689 goto asyncread_out; |
689 } | 690 } |
690 nRead = (int)MIN(filesize - iOffset, iAmt); | 691 nRead = MIN(filesize - iOffset, iAmt64); |
691 if( nRead>0 ){ | 692 if( nRead>0 ){ |
692 rc = pBase->pMethods->xRead(pBase, zOut, nRead, iOffset); | 693 rc = pBase->pMethods->xRead(pBase, zOut, (int)nRead, iOffset); |
693 ASYNC_TRACE(("READ %s %d bytes at %d\n", p->zName, nRead, iOffset)); | 694 ASYNC_TRACE(("READ %s %d bytes at %d\n", p->zName, nRead, iOffset)); |
694 } | 695 } |
695 } | 696 } |
696 | 697 |
697 if( rc==SQLITE_OK ){ | 698 if( rc==SQLITE_OK ){ |
698 AsyncWrite *pWrite; | 699 AsyncWrite *pWrite; |
699 char *zName = p->zName; | 700 char *zName = p->zName; |
700 | 701 |
701 for(pWrite=async.pQueueFirst; pWrite; pWrite = pWrite->pNext){ | 702 for(pWrite=async.pQueueFirst; pWrite; pWrite = pWrite->pNext){ |
702 if( pWrite->op==ASYNC_WRITE && ( | 703 if( pWrite->op==ASYNC_WRITE && ( |
703 (pWrite->pFileData==p) || | 704 (pWrite->pFileData==p) || |
704 (zName && pWrite->pFileData->zName==zName) | 705 (zName && pWrite->pFileData->zName==zName) |
705 )){ | 706 )){ |
| 707 sqlite3_int64 nCopy; |
| 708 sqlite3_int64 nByte64 = (sqlite3_int64)pWrite->nByte; |
| 709 |
| 710 /* Set variable iBeginIn to the offset in buffer pWrite->zBuf[] from |
| 711 ** which data should be copied. Set iBeginOut to the offset within |
| 712 ** the output buffer to which data should be copied. If either of |
| 713 ** these offsets is a negative number, set them to 0. |
| 714 */ |
706 sqlite3_int64 iBeginOut = (pWrite->iOffset-iOffset); | 715 sqlite3_int64 iBeginOut = (pWrite->iOffset-iOffset); |
707 sqlite3_int64 iBeginIn = -iBeginOut; | 716 sqlite3_int64 iBeginIn = -iBeginOut; |
708 int nCopy; | |
709 | |
710 if( iBeginIn<0 ) iBeginIn = 0; | 717 if( iBeginIn<0 ) iBeginIn = 0; |
711 if( iBeginOut<0 ) iBeginOut = 0; | 718 if( iBeginOut<0 ) iBeginOut = 0; |
712 nCopy = (int)MIN(pWrite->nByte-iBeginIn, iAmt-iBeginOut); | |
713 | 719 |
| 720 filesize = MAX(filesize, pWrite->iOffset+nByte64); |
| 721 |
| 722 nCopy = MIN(nByte64-iBeginIn, iAmt64-iBeginOut); |
714 if( nCopy>0 ){ | 723 if( nCopy>0 ){ |
715 memcpy(&((char *)zOut)[iBeginOut], &pWrite->zBuf[iBeginIn], nCopy); | 724 memcpy(&((char *)zOut)[iBeginOut], &pWrite->zBuf[iBeginIn], (size_t)nC
opy); |
716 ASYNC_TRACE(("OVERREAD %d bytes at %d\n", nCopy, iBeginOut+iOffset)); | 725 ASYNC_TRACE(("OVERREAD %d bytes at %d\n", nCopy, iBeginOut+iOffset)); |
717 } | 726 } |
718 } | 727 } |
719 } | 728 } |
720 } | 729 } |
721 | 730 |
722 asyncread_out: | 731 asyncread_out: |
723 async_mutex_leave(ASYNC_MUTEX_QUEUE); | 732 async_mutex_leave(ASYNC_MUTEX_QUEUE); |
| 733 if( rc==SQLITE_OK && filesize<(iOffset+iAmt) ){ |
| 734 rc = SQLITE_IOERR_SHORT_READ; |
| 735 } |
724 return rc; | 736 return rc; |
725 } | 737 } |
726 | 738 |
727 /* | 739 /* |
728 ** Truncate the file to nByte bytes in length. This just adds an entry to | 740 ** Truncate the file to nByte bytes in length. This just adds an entry to |
729 ** the write-op list, no IO actually takes place. | 741 ** the write-op list, no IO actually takes place. |
730 */ | 742 */ |
731 static int asyncTruncate(sqlite3_file *pFile, sqlite3_int64 nByte){ | 743 static int asyncTruncate(sqlite3_file *pFile, sqlite3_int64 nByte){ |
732 AsyncFileData *p = ((AsyncFile *)pFile)->pData; | 744 AsyncFileData *p = ((AsyncFile *)pFile)->pData; |
733 return addNewAsyncWrite(p, ASYNC_TRUNCATE, nByte, 0, 0); | 745 return addNewAsyncWrite(p, ASYNC_TRUNCATE, nByte, 0, 0); |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1124 } | 1136 } |
1125 if( pData->pBaseWrite->pMethods ){ | 1137 if( pData->pBaseWrite->pMethods ){ |
1126 pData->pBaseWrite->pMethods->xClose(pData->pBaseWrite); | 1138 pData->pBaseWrite->pMethods->xClose(pData->pBaseWrite); |
1127 } | 1139 } |
1128 sqlite3_free(pData); | 1140 sqlite3_free(pData); |
1129 } | 1141 } |
1130 | 1142 |
1131 async_mutex_leave(ASYNC_MUTEX_LOCK); | 1143 async_mutex_leave(ASYNC_MUTEX_LOCK); |
1132 | 1144 |
1133 if( rc==SQLITE_OK ){ | 1145 if( rc==SQLITE_OK ){ |
1134 incrOpenFileCount(); | |
1135 pData->pLock = pLock; | 1146 pData->pLock = pLock; |
1136 } | 1147 } |
1137 | 1148 |
1138 if( rc==SQLITE_OK && isAsyncOpen ){ | 1149 if( rc==SQLITE_OK && isAsyncOpen ){ |
1139 rc = addNewAsyncWrite(pData, ASYNC_OPENEXCLUSIVE, (sqlite3_int64)flags,0,0); | 1150 rc = addNewAsyncWrite(pData, ASYNC_OPENEXCLUSIVE, (sqlite3_int64)flags,0,0); |
1140 if( rc==SQLITE_OK ){ | 1151 if( rc==SQLITE_OK ){ |
1141 if( pOutFlags ) *pOutFlags = flags; | 1152 if( pOutFlags ) *pOutFlags = flags; |
1142 }else{ | 1153 }else{ |
1143 async_mutex_enter(ASYNC_MUTEX_LOCK); | 1154 async_mutex_enter(ASYNC_MUTEX_LOCK); |
1144 unlinkAsyncFile(pData); | 1155 unlinkAsyncFile(pData); |
1145 async_mutex_leave(ASYNC_MUTEX_LOCK); | 1156 async_mutex_leave(ASYNC_MUTEX_LOCK); |
1146 sqlite3_free(pData); | 1157 sqlite3_free(pData); |
1147 } | 1158 } |
1148 } | 1159 } |
1149 if( rc!=SQLITE_OK ){ | 1160 if( rc!=SQLITE_OK ){ |
1150 p->pMethod = 0; | 1161 p->pMethod = 0; |
| 1162 }else{ |
| 1163 incrOpenFileCount(); |
1151 } | 1164 } |
| 1165 |
1152 return rc; | 1166 return rc; |
1153 } | 1167 } |
1154 | 1168 |
1155 /* | 1169 /* |
1156 ** Implementation of sqlite3OsDelete. Add an entry to the end of the | 1170 ** Implementation of sqlite3OsDelete. Add an entry to the end of the |
1157 ** write-op queue to perform the delete. | 1171 ** write-op queue to perform the delete. |
1158 */ | 1172 */ |
1159 static int asyncDelete(sqlite3_vfs *pAsyncVfs, const char *z, int syncDir){ | 1173 static int asyncDelete(sqlite3_vfs *pAsyncVfs, const char *z, int syncDir){ |
1160 UNUSED_PARAMETER(pAsyncVfs); | 1174 UNUSED_PARAMETER(pAsyncVfs); |
1161 return addNewAsyncWrite(0, ASYNC_DELETE, syncDir, (int)strlen(z)+1, z); | 1175 return addNewAsyncWrite(0, ASYNC_DELETE, syncDir, (int)strlen(z)+1, z); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1217 int rc; | 1231 int rc; |
1218 sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData; | 1232 sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData; |
1219 rc = pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut); | 1233 rc = pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut); |
1220 | 1234 |
1221 /* Because of the way intra-process file locking works, this backend | 1235 /* Because of the way intra-process file locking works, this backend |
1222 ** needs to return a canonical path. The following block assumes the | 1236 ** needs to return a canonical path. The following block assumes the |
1223 ** file-system uses unix style paths. | 1237 ** file-system uses unix style paths. |
1224 */ | 1238 */ |
1225 if( rc==SQLITE_OK ){ | 1239 if( rc==SQLITE_OK ){ |
1226 int i, j; | 1240 int i, j; |
1227 int n = nPathOut; | |
1228 char *z = zPathOut; | 1241 char *z = zPathOut; |
| 1242 int n = (int)strlen(z); |
1229 while( n>1 && z[n-1]=='/' ){ n--; } | 1243 while( n>1 && z[n-1]=='/' ){ n--; } |
1230 for(i=j=0; i<n; i++){ | 1244 for(i=j=0; i<n; i++){ |
1231 if( z[i]=='/' ){ | 1245 if( z[i]=='/' ){ |
1232 if( z[i+1]=='/' ) continue; | 1246 if( z[i+1]=='/' ) continue; |
1233 if( z[i+1]=='.' && i+2<n && z[i+2]=='/' ){ | 1247 if( z[i+1]=='.' && i+2<n && z[i+2]=='/' ){ |
1234 i += 1; | 1248 i += 1; |
1235 continue; | 1249 continue; |
1236 } | 1250 } |
1237 if( z[i+1]=='.' && i+3<n && z[i+2]=='.' && z[i+3]=='/' ){ | 1251 if( z[i+1]=='.' && i+3<n && z[i+2]=='.' && z[i+3]=='/' ){ |
1238 while( j>0 && z[j-1]!='/' ){ j--; } | 1252 while( j>0 && z[j-1]!='/' ){ j--; } |
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1674 } | 1688 } |
1675 | 1689 |
1676 default: | 1690 default: |
1677 return SQLITE_ERROR; | 1691 return SQLITE_ERROR; |
1678 } | 1692 } |
1679 return SQLITE_OK; | 1693 return SQLITE_OK; |
1680 } | 1694 } |
1681 | 1695 |
1682 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ASYNCIO) */ | 1696 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ASYNCIO) */ |
1683 | 1697 |
OLD | NEW |