aboutsummaryrefslogtreecommitdiff
path: root/src/os_unix.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2014-12-31 14:27:29 +0000
committerdrh <drh@noemail.net>2014-12-31 14:27:29 +0000
commitc8ae34dc6a0d3a04ef127696c2fb8ac39a618271 (patch)
tree91ae19b962455a896523281097dd7570db83fb38 /src/os_unix.c
parentb5a438709746a4f5e0a583df8ec173ac1f490549 (diff)
parent542d55865cb1ec11421783060212b4b13e9f96e4 (diff)
downloadsqlite-c8ae34dc6a0d3a04ef127696c2fb8ac39a618271.tar.gz
sqlite-c8ae34dc6a0d3a04ef127696c2fb8ac39a618271.zip
Merge the fix to PRAGMA data_version and testing improvements from trunk.
FossilOrigin-Name: 86e39123c1bca457672bc63eff00a823745077e5
Diffstat (limited to 'src/os_unix.c')
-rw-r--r--src/os_unix.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/src/os_unix.c b/src/os_unix.c
index a9344ee83..f802d9cd1 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -3709,24 +3709,27 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
}while( err==EINTR );
if( err ) return SQLITE_IOERR_WRITE;
#else
- /* If the OS does not have posix_fallocate(), fake it. First use
- ** ftruncate() to set the file size, then write a single byte to
- ** the last byte in each block within the extended region. This
- ** is the same technique used by glibc to implement posix_fallocate()
- ** on systems that do not have a real fallocate() system call.
+ /* If the OS does not have posix_fallocate(), fake it. Write a
+ ** single byte to the last byte in each block that falls entirely
+ ** within the extended region. Then, if required, a single byte
+ ** at offset (nSize-1), to set the size of the file correctly.
+ ** This is a similar technique to that used by glibc on systems
+ ** that do not have a real fallocate() call.
*/
int nBlk = buf.st_blksize; /* File-system block size */
i64 iWrite; /* Next offset to write to */
- if( robust_ftruncate(pFile->h, nSize) ){
- pFile->lastErrno = errno;
- return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
- }
iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1;
- while( iWrite<nSize ){
+ assert( iWrite>=buf.st_size );
+ assert( (iWrite/nBlk)==((buf.st_size+nBlk-1)/nBlk) );
+ assert( ((iWrite+1)%nBlk)==0 );
+ for(/*no-op*/; iWrite<nSize; iWrite+=nBlk ){
int nWrite = seekAndWrite(pFile, iWrite, "", 1);
if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
- iWrite += nBlk;
+ }
+ if( nSize%nBlk ){
+ int nWrite = seekAndWrite(pFile, nSize-1, "", 1);
+ if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
}
#endif
}