1 /* 2 ** 2001 September 16 3 ** 4 ** The author disclaims copyright to this source code. In place of 5 ** a legal notice, here is a blessing: 6 ** 7 ** May you do good and not evil. 8 ** May you find forgiveness for yourself and forgive others. 9 ** May you share freely, never taking more than you give. 10 ** 11 ****************************************************************************** 12 ** 13 ** This file contains code that is specific to particular operating 14 ** systems. The purpose of this file is to provide a uniform abstraction 15 ** on which the rest of SQLite can operate. 16 */ 17 #include "os.h" /* Must be first to enable large file support */ 18 #include "sqliteInt.h" 19 20 #if OS_UNIX 21 # include <time.h> 22 # include <errno.h> 23 # include <unistd.h> 24 # ifndef O_LARGEFILE 25 # define O_LARGEFILE 0 26 # endif 27 # ifdef SQLITE_DISABLE_LFS 28 # undef O_LARGEFILE 29 # define O_LARGEFILE 0 30 # endif 31 # ifndef O_NOFOLLOW 32 # define O_NOFOLLOW 0 33 # endif 34 # ifndef O_BINARY 35 # define O_BINARY 0 36 # endif 37 #endif 38 39 40 #if OS_WIN 41 # include <winbase.h> 42 #endif 43 44 #if OS_MAC 45 # include <extras.h> 46 # include <path2fss.h> 47 # include <TextUtils.h> 48 # include <FinderRegistry.h> 49 # include <Folders.h> 50 # include <Timer.h> 51 # include <OSUtils.h> 52 #endif 53 54 /* 55 ** The DJGPP compiler environment looks mostly like Unix, but it 56 ** lacks the fcntl() system call. So redefine fcntl() to be something 57 ** that always succeeds. This means that locking does not occur under 58 ** DJGPP. But its DOS - what did you expect? 59 */ 60 #ifdef __DJGPP__ 61 # define fcntl(A,B,C) 0 62 #endif 63 64 /* 65 ** Macros for performance tracing. Normally turned off 66 */ 67 #if 0 68 static int last_page = 0; 69 __inline__ unsigned long long int hwtime(void){ 70 unsigned long long int x; 71 __asm__("rdtsc\n\t" 72 "mov %%edx, %%ecx\n\t" 73 :"=A" (x)); 74 return x; 75 } 76 static unsigned long long int g_start; 77 static unsigned int elapse; 78 #define TIMER_START g_start=hwtime() 79 #define TIMER_END elapse=hwtime()-g_start 80 #define SEEK(X) last_page=(X) 81 #define TRACE1(X) fprintf(stderr,X) 82 #define TRACE2(X,Y) fprintf(stderr,X,Y) 83 #define TRACE3(X,Y,Z) fprintf(stderr,X,Y,Z) 84 #define TRACE4(X,Y,Z,A) fprintf(stderr,X,Y,Z,A) 85 #define TRACE5(X,Y,Z,A,B) fprintf(stderr,X,Y,Z,A,B) 86 #else 87 #define TIMER_START 88 #define TIMER_END 89 #define SEEK(X) 90 #define TRACE1(X) 91 #define TRACE2(X,Y) 92 #define TRACE3(X,Y,Z) 93 #define TRACE4(X,Y,Z,A) 94 #define TRACE5(X,Y,Z,A,B) 95 #endif 96 97 98 #if OS_UNIX 99 /* 100 ** Here is the dirt on POSIX advisory locks: ANSI STD 1003.1 (1996) 101 ** section 6.5.2.2 lines 483 through 490 specify that when a process 102 ** sets or clears a lock, that operation overrides any prior locks set 103 ** by the same process. It does not explicitly say so, but this implies 104 ** that it overrides locks set by the same process using a different 105 ** file descriptor. Consider this test case: 106 ** 107 ** int fd1 = open("./file1", O_RDWR|O_CREAT, 0644); 108 ** int fd2 = open("./file2", O_RDWR|O_CREAT, 0644); 109 ** 110 ** Suppose ./file1 and ./file2 are really the same file (because 111 ** one is a hard or symbolic link to the other) then if you set 112 ** an exclusive lock on fd1, then try to get an exclusive lock 113 ** on fd2, it works. I would have expected the second lock to 114 ** fail since there was already a lock on the file due to fd1. 115 ** But not so. Since both locks came from the same process, the 116 ** second overrides the first, even though they were on different 117 ** file descriptors opened on different file names. 118 ** 119 ** Bummer. If you ask me, this is broken. Badly broken. It means 120 ** that we cannot use POSIX locks to synchronize file access among 121 ** competing threads of the same process. POSIX locks will work fine 122 ** to synchronize access for threads in separate processes, but not 123 ** threads within the same process. 124 ** 125 ** To work around the problem, SQLite has to manage file locks internally 126 ** on its own. Whenever a new database is opened, we have to find the 127 ** specific inode of the database file (the inode is determined by the 128 ** st_dev and st_ino fields of the stat structure that fstat() fills in) 129 ** and check for locks already existing on that inode. When locks are 130 ** created or removed, we have to look at our own internal record of the 131 ** locks to see if another thread has previously set a lock on that same 132 ** inode. 133 ** 134 ** The OsFile structure for POSIX is no longer just an integer file 135 ** descriptor. It is now a structure that holds the integer file 136 ** descriptor and a pointer to a structure that describes the internal 137 ** locks on the corresponding inode. There is one locking structure 138 ** per inode, so if the same inode is opened twice, both OsFile structures 139 ** point to the same locking structure. The locking structure keeps 140 ** a reference count (so we will know when to delete it) and a "cnt" 141 ** field that tells us its internal lock status. cnt==0 means the 142 ** file is unlocked. cnt==-1 means the file has an exclusive lock. 143 ** cnt>0 means there are cnt shared locks on the file. 144 ** 145 ** Any attempt to lock or unlock a file first checks the locking 146 ** structure. The fcntl() system call is only invoked to set a 147 ** POSIX lock if the internal lock structure transitions between 148 ** a locked and an unlocked state. 149 */ 150 151 /* 152 ** An instance of the following structure serves as the key used 153 ** to locate a particular lockInfo structure given its inode. 154 */ 155 struct inodeKey { 156 dev_t dev; /* Device number */ 157 ino_t ino; /* Inode number */ 158 }; 159 160 /* 161 ** An instance of the following structure is allocated for each inode. 162 ** A single inode can have multiple file descriptors, so each OsFile 163 ** structure contains a pointer to an instance of this object and this 164 ** object keeps a count of the number of OsFiles pointing to it. 165 */ 166 struct lockInfo { 167 struct inodeKey key; /* The lookup key */ 168 int cnt; /* 0: unlocked. -1: write lock. 1...: read lock. */ 169 int nRef; /* Number of pointers to this structure */ 170 }; 171 172 /* 173 ** This hash table maps inodes (in the form of inodeKey structures) into 174 ** pointers to lockInfo structures. 175 */ 176 static Hash lockHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 }; 177 178 /* 179 ** Given a file descriptor, locate a lockInfo structure that describes 180 ** that file descriptor. Create a new one if necessary. NULL might 181 ** be returned if malloc() fails. 182 */ 183 static struct lockInfo *findLockInfo(int fd){ 184 int rc; 185 struct inodeKey key; 186 struct stat statbuf; 187 struct lockInfo *pInfo; 188 rc = fstat(fd, &statbuf); 189 if( rc!=0 ) return 0; 190 memset(&key, 0, sizeof(key)); 191 key.dev = statbuf.st_dev; 192 key.ino = statbuf.st_ino; 193 pInfo = (struct lockInfo*)sqliteHashFind(&lockHash, &key, sizeof(key)); 194 if( pInfo==0 ){ 195 struct lockInfo *pOld; 196 pInfo = sqliteMalloc( sizeof(*pInfo) ); 197 if( pInfo==0 ) return 0; 198 pInfo->key = key; 199 pInfo->nRef = 1; 200 pInfo->cnt = 0; 201 pOld = sqliteHashInsert(&lockHash, &pInfo->key, sizeof(key), pInfo); 202 if( pOld!=0 ){ 203 assert( pOld==pInfo ); 204 sqliteFree(pInfo); 205 pInfo = 0; 206 } 207 }else{ 208 pInfo->nRef++; 209 } 210 return pInfo; 211 } 212 213 /* 214 ** Release a lockInfo structure previously allocated by findLockInfo(). 215 */ 216 static void releaseLockInfo(struct lockInfo *pInfo){ 217 pInfo->nRef--; 218 if( pInfo->nRef==0 ){ 219 sqliteHashInsert(&lockHash, &pInfo->key, sizeof(pInfo->key), 0); 220 sqliteFree(pInfo); 221 } 222 } 223 #endif /** POSIX advisory lock work-around **/ 224 225 /* 226 ** If we compile with the SQLITE_TEST macro set, then the following block 227 ** of code will give us the ability to simulate a disk I/O error. This 228 ** is used for testing the I/O recovery logic. 229 */ 230 #ifdef SQLITE_TEST 231 int sqlite_io_error_pending = 0; 232 #define SimulateIOError(A) \ 233 if( sqlite_io_error_pending ) \ 234 if( sqlite_io_error_pending-- == 1 ){ local_ioerr(); return A; } 235 static void local_ioerr(){ 236 sqlite_io_error_pending = 0; /* Really just a place to set a breakpoint */ 237 } 238 #else 239 #define SimulateIOError(A) 240 #endif 241 242 /* 243 ** When testing, keep a count of the number of open files. 244 */ 245 #ifdef SQLITE_TEST 246 int sqlite_open_file_count = 0; 247 #define OpenCounter(X) sqlite_open_file_count+=(X) 248 #else 249 #define OpenCounter(X) 250 #endif 251 252 253 /* 254 ** Delete the named file 255 */ 256 int sqliteOsDelete(const char *zFilename){ 257 #if OS_UNIX 258 unlink(zFilename); 259 #endif 260 #if OS_WIN 261 DeleteFile(zFilename); 262 #endif 263 #if OS_MAC 264 unlink(zFilename); 265 #endif 266 return SQLITE_OK; 267 } 268 269 /* 270 ** Return TRUE if the named file exists. 271 */ 272 int sqliteOsFileExists(const char *zFilename){ 273 #if OS_UNIX 274 return access(zFilename, 0)==0; 275 #endif 276 #if OS_WIN 277 return GetFileAttributes(zFilename) != 0xffffffff; 278 #endif 279 #if OS_MAC 280 return access(zFilename, 0)==0; 281 #endif 282 } 283 284 285 #if 0 /* NOT USED */ 286 /* 287 ** Change the name of an existing file. 288 */ 289 int sqliteOsFileRename(const char *zOldName, const char *zNewName){ 290 #if OS_UNIX 291 if( link(zOldName, zNewName) ){ 292 return SQLITE_ERROR; 293 } 294 unlink(zOldName); 295 return SQLITE_OK; 296 #endif 297 #if OS_WIN 298 if( !MoveFile(zOldName, zNewName) ){ 299 return SQLITE_ERROR; 300 } 301 return SQLITE_OK; 302 #endif 303 #if OS_MAC 304 /**** FIX ME ***/ 305 return SQLITE_ERROR; 306 #endif 307 } 308 #endif /* NOT USED */ 309 310 /* 311 ** Attempt to open a file for both reading and writing. If that 312 ** fails, try opening it read-only. If the file does not exist, 313 ** try to create it. 314 ** 315 ** On success, a handle for the open file is written to *id 316 ** and *pReadonly is set to 0 if the file was opened for reading and 317 ** writing or 1 if the file was opened read-only. The function returns 318 ** SQLITE_OK. 319 ** 320 ** On failure, the function returns SQLITE_CANTOPEN and leaves 321 ** *id and *pReadonly unchanged. 322 */ 323 int sqliteOsOpenReadWrite( 324 const char *zFilename, 325 OsFile *id, 326 int *pReadonly 327 ){ 328 #if OS_UNIX 329 id->dirfd = -1; 330 id->fd = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY, 0644); 331 if( id->fd<0 ){ 332 id->fd = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY); 333 if( id->fd<0 ){ 334 return SQLITE_CANTOPEN; 335 } 336 *pReadonly = 1; 337 }else{ 338 *pReadonly = 0; 339 } 340 sqliteOsEnterMutex(); 341 id->pLock = findLockInfo(id->fd); 342 sqliteOsLeaveMutex(); 343 if( id->pLock==0 ){ 344 close(id->fd); 345 return SQLITE_NOMEM; 346 } 347 id->locked = 0; 348 TRACE3("OPEN %-3d %s\n", id->fd, zFilename); 349 OpenCounter(+1); 350 return SQLITE_OK; 351 #endif 352 #if OS_WIN 353 HANDLE h = CreateFile(zFilename, 354 GENERIC_READ | GENERIC_WRITE, 355 FILE_SHARE_READ | FILE_SHARE_WRITE, 356 NULL, 357 OPEN_ALWAYS, 358 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, 359 NULL 360 ); 361 if( h==INVALID_HANDLE_VALUE ){ 362 h = CreateFile(zFilename, 363 GENERIC_READ, 364 FILE_SHARE_READ, 365 NULL, 366 OPEN_ALWAYS, 367 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, 368 NULL 369 ); 370 if( h==INVALID_HANDLE_VALUE ){ 371 return SQLITE_CANTOPEN; 372 } 373 *pReadonly = 1; 374 }else{ 375 *pReadonly = 0; 376 } 377 id->h = h; 378 id->locked = 0; 379 OpenCounter(+1); 380 return SQLITE_OK; 381 #endif 382 #if OS_MAC 383 FSSpec fsSpec; 384 # ifdef _LARGE_FILE 385 HFSUniStr255 dfName; 386 FSRef fsRef; 387 if( __path2fss(zFilename, &fsSpec) != noErr ){ 388 if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr ) 389 return SQLITE_CANTOPEN; 390 } 391 if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr ) 392 return SQLITE_CANTOPEN; 393 FSGetDataForkName(&dfName); 394 if( FSOpenFork(&fsRef, dfName.length, dfName.unicode, 395 fsRdWrShPerm, &(id->refNum)) != noErr ){ 396 if( FSOpenFork(&fsRef, dfName.length, dfName.unicode, 397 fsRdWrPerm, &(id->refNum)) != noErr ){ 398 if (FSOpenFork(&fsRef, dfName.length, dfName.unicode, 399 fsRdPerm, &(id->refNum)) != noErr ) 400 return SQLITE_CANTOPEN; 401 else 402 *pReadonly = 1; 403 } else 404 *pReadonly = 0; 405 } else 406 *pReadonly = 0; 407 # else 408 __path2fss(zFilename, &fsSpec); 409 if( !sqliteOsFileExists(zFilename) ){ 410 if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr ) 411 return SQLITE_CANTOPEN; 412 } 413 if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNum)) != noErr ){ 414 if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrPerm, &(id->refNum)) != noErr ){ 415 if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdPerm, &(id->refNum)) != noErr ) 416 return SQLITE_CANTOPEN; 417 else 418 *pReadonly = 1; 419 } else 420 *pReadonly = 0; 421 } else 422 *pReadonly = 0; 423 # endif 424 if( HOpenRF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNumRF)) != noErr){ 425 id->refNumRF = -1; 426 } 427 id->locked = 0; 428 id->delOnClose = 0; 429 OpenCounter(+1); 430 return SQLITE_OK; 431 #endif 432 } 433 434 435 /* 436 ** Attempt to open a new file for exclusive access by this process. 437 ** The file will be opened for both reading and writing. To avoid 438 ** a potential security problem, we do not allow the file to have 439 ** previously existed. Nor do we allow the file to be a symbolic 440 ** link. 441 ** 442 ** If delFlag is true, then make arrangements to automatically delete 443 ** the file when it is closed. 444 ** 445 ** On success, write the file handle into *id and return SQLITE_OK. 446 ** 447 ** On failure, return SQLITE_CANTOPEN. 448 */ 449 int sqliteOsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){ 450 #if OS_UNIX 451 if( access(zFilename, 0)==0 ){ 452 return SQLITE_CANTOPEN; 453 } 454 id->dirfd = -1; 455 id->fd = open(zFilename, 456 O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY, 0600); 457 if( id->fd<0 ){ 458 return SQLITE_CANTOPEN; 459 } 460 sqliteOsEnterMutex(); 461 id->pLock = findLockInfo(id->fd); 462 sqliteOsLeaveMutex(); 463 if( id->pLock==0 ){ 464 close(id->fd); 465 unlink(zFilename); 466 return SQLITE_NOMEM; 467 } 468 id->locked = 0; 469 if( delFlag ){ 470 unlink(zFilename); 471 } 472 TRACE3("OPEN-EX %-3d %s\n", id->fd, zFilename); 473 OpenCounter(+1); 474 return SQLITE_OK; 475 #endif 476 #if OS_WIN 477 HANDLE h; 478 int fileflags; 479 if( delFlag ){ 480 fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS 481 | FILE_FLAG_DELETE_ON_CLOSE; 482 }else{ 483 fileflags = FILE_FLAG_RANDOM_ACCESS; 484 } 485 h = CreateFile(zFilename, 486 GENERIC_READ | GENERIC_WRITE, 487 0, 488 NULL, 489 CREATE_ALWAYS, 490 fileflags, 491 NULL 492 ); 493 if( h==INVALID_HANDLE_VALUE ){ 494 return SQLITE_CANTOPEN; 495 } 496 id->h = h; 497 id->locked = 0; 498 OpenCounter(+1); 499 return SQLITE_OK; 500 #endif 501 #if OS_MAC 502 FSSpec fsSpec; 503 # ifdef _LARGE_FILE 504 HFSUniStr255 dfName; 505 FSRef fsRef; 506 __path2fss(zFilename, &fsSpec); 507 if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr ) 508 return SQLITE_CANTOPEN; 509 if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr ) 510 return SQLITE_CANTOPEN; 511 FSGetDataForkName(&dfName); 512 if( FSOpenFork(&fsRef, dfName.length, dfName.unicode, 513 fsRdWrPerm, &(id->refNum)) != noErr ) 514 return SQLITE_CANTOPEN; 515 # else 516 __path2fss(zFilename, &fsSpec); 517 if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr ) 518 return SQLITE_CANTOPEN; 519 if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrPerm, &(id->refNum)) != noErr ) 520 return SQLITE_CANTOPEN; 521 # endif 522 id->refNumRF = -1; 523 id->locked = 0; 524 id->delOnClose = delFlag; 525 if (delFlag) 526 id->pathToDel = sqliteOsFullPathname(zFilename); 527 OpenCounter(+1); 528 return SQLITE_OK; 529 #endif 530 } 531 532 /* 533 ** Attempt to open a new file for read-only access. 534 ** 535 ** On success, write the file handle into *id and return SQLITE_OK. 536 ** 537 ** On failure, return SQLITE_CANTOPEN. 538 */ 539 int sqliteOsOpenReadOnly(const char *zFilename, OsFile *id){ 540 #if OS_UNIX 541 id->dirfd = -1; 542 id->fd = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY); 543 if( id->fd<0 ){ 544 return SQLITE_CANTOPEN; 545 } 546 sqliteOsEnterMutex(); 547 id->pLock = findLockInfo(id->fd); 548 sqliteOsLeaveMutex(); 549 if( id->pLock==0 ){ 550 close(id->fd); 551 return SQLITE_NOMEM; 552 } 553 id->locked = 0; 554 TRACE3("OPEN-RO %-3d %s\n", id->fd, zFilename); 555 OpenCounter(+1); 556 return SQLITE_OK; 557 #endif 558 #if OS_WIN 559 HANDLE h = CreateFile(zFilename, 560 GENERIC_READ, 561 0, 562 NULL, 563 OPEN_EXISTING, 564 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, 565 NULL 566 ); 567 if( h==INVALID_HANDLE_VALUE ){ 568 return SQLITE_CANTOPEN; 569 } 570 id->h = h; 571 id->locked = 0; 572 OpenCounter(+1); 573 return SQLITE_OK; 574 #endif 575 #if OS_MAC 576 FSSpec fsSpec; 577 # ifdef _LARGE_FILE 578 HFSUniStr255 dfName; 579 FSRef fsRef; 580 if( __path2fss(zFilename, &fsSpec) != noErr ) 581 return SQLITE_CANTOPEN; 582 if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr ) 583 return SQLITE_CANTOPEN; 584 FSGetDataForkName(&dfName); 585 if( FSOpenFork(&fsRef, dfName.length, dfName.unicode, 586 fsRdPerm, &(id->refNum)) != noErr ) 587 return SQLITE_CANTOPEN; 588 # else 589 __path2fss(zFilename, &fsSpec); 590 if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdPerm, &(id->refNum)) != noErr ) 591 return SQLITE_CANTOPEN; 592 # endif 593 if( HOpenRF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNumRF)) != noErr){ 594 id->refNumRF = -1; 595 } 596 id->locked = 0; 597 id->delOnClose = 0; 598 OpenCounter(+1); 599 return SQLITE_OK; 600 #endif 601 } 602 603 /* 604 ** Attempt to open a file descriptor for the directory that contains a 605 ** file. This file descriptor can be used to fsync() the directory 606 ** in order to make sure the creation of a new file is actually written 607 ** to disk. 608 ** 609 ** This routine is only meaningful for Unix. It is a no-op under 610 ** windows since windows does not support hard links. 611 ** 612 ** On success, a handle for a previously open file is at *id is 613 ** updated with the new directory file descriptor and SQLITE_OK is 614 ** returned. 615 ** 616 ** On failure, the function returns SQLITE_CANTOPEN and leaves 617 ** *id unchanged. 618 */ 619 int sqliteOsOpenDirectory( 620 const char *zDirname, 621 OsFile *id 622 ){ 623 #if OS_UNIX 624 if( id->fd<0 ){ 625 /* Do not open the directory if the corresponding file is not already 626 ** open. */ 627 return SQLITE_CANTOPEN; 628 } 629 assert( id->dirfd<0 ); 630 id->dirfd = open(zDirname, O_RDONLY|O_BINARY, 0644); 631 if( id->dirfd<0 ){ 632 return SQLITE_CANTOPEN; 633 } 634 TRACE3("OPENDIR %-3d %s\n", id->dirfd, zDirname); 635 #endif 636 return SQLITE_OK; 637 } 638 639 /* 640 ** Create a temporary file name in zBuf. zBuf must be big enough to 641 ** hold at least SQLITE_TEMPNAME_SIZE characters. 642 */ 643 int sqliteOsTempFileName(char *zBuf){ 644 #if OS_UNIX 645 static const char *azDirs[] = { 646 "/var/tmp", 647 "/usr/tmp", 648 "/tmp", 649 ".", 650 }; 651 static char zChars[] = 652 "abcdefghijklmnopqrstuvwxyz" 653 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 654 "0123456789"; 655 int i, j; 656 struct stat buf; 657 const char *zDir = "."; 658 for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){ 659 if( stat(azDirs[i], &buf) ) continue; 660 if( !S_ISDIR(buf.st_mode) ) continue; 661 if( access(azDirs[i], 07) ) continue; 662 zDir = azDirs[i]; 663 break; 664 } 665 do{ 666 sprintf(zBuf, "%s/"TEMP_FILE_PREFIX, zDir); 667 j = strlen(zBuf); 668 for(i=0; i<15; i++){ 669 int n = sqliteRandomByte() % (sizeof(zChars)-1); 670 zBuf[j++] = zChars[n]; 671 } 672 zBuf[j] = 0; 673 }while( access(zBuf,0)==0 ); 674 #endif 675 #if OS_WIN 676 static char zChars[] = 677 "abcdefghijklmnopqrstuvwxyz" 678 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 679 "0123456789"; 680 int i, j; 681 char zTempPath[SQLITE_TEMPNAME_SIZE]; 682 GetTempPath(SQLITE_TEMPNAME_SIZE-30, zTempPath); 683 for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){} 684 zTempPath[i] = 0; 685 for(;;){ 686 sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath); 687 j = strlen(zBuf); 688 for(i=0; i<15; i++){ 689 int n = sqliteRandomByte() % (sizeof(zChars) - 1); 690 zBuf[j++] = zChars[n]; 691 } 692 zBuf[j] = 0; 693 if( !sqliteOsFileExists(zBuf) ) break; 694 } 695 #endif 696 #if OS_MAC 697 static char zChars[] = 698 "abcdefghijklmnopqrstuvwxyz" 699 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 700 "0123456789"; 701 int i, j; 702 char zTempPath[SQLITE_TEMPNAME_SIZE]; 703 char zdirName[32]; 704 CInfoPBRec infoRec; 705 Str31 dirName; 706 memset(&infoRec, 0, sizeof(infoRec)); 707 memset(zTempPath, 0, SQLITE_TEMPNAME_SIZE); 708 if( FindFolder(kOnSystemDisk, kTemporaryFolderType, kCreateFolder, 709 &(infoRec.dirInfo.ioVRefNum), &(infoRec.dirInfo.ioDrParID)) == noErr ){ 710 infoRec.dirInfo.ioNamePtr = dirName; 711 do{ 712 infoRec.dirInfo.ioFDirIndex = -1; 713 infoRec.dirInfo.ioDrDirID = infoRec.dirInfo.ioDrParID; 714 if( PBGetCatInfoSync(&infoRec) == noErr ){ 715 CopyPascalStringToC(dirName, zdirName); 716 i = strlen(zdirName); 717 memmove(&(zTempPath[i+1]), zTempPath, strlen(zTempPath)); 718 strcpy(zTempPath, zdirName); 719 zTempPath[i] = ':'; 720 }else{ 721 *zTempPath = 0; 722 break; 723 } 724 } while( infoRec.dirInfo.ioDrDirID != fsRtDirID ); 725 } 726 if( *zTempPath == 0 ) 727 getcwd(zTempPath, SQLITE_TEMPNAME_SIZE-24); 728 for(;;){ 729 sprintf(zBuf, "%s"TEMP_FILE_PREFIX, zTempPath); 730 j = strlen(zBuf); 731 for(i=0; i<15; i++){ 732 int n = sqliteRandomByte() % sizeof(zChars); 733 zBuf[j++] = zChars[n]; 734 } 735 zBuf[j] = 0; 736 if( !sqliteOsFileExists(zBuf) ) break; 737 } 738 #endif 739 return SQLITE_OK; 740 } 741 742 /* 743 ** Close a file 744 */ 745 int sqliteOsClose(OsFile *id){ 746 #if OS_UNIX 747 close(id->fd); 748 if( id->dirfd>=0 ) close(id->dirfd); 749 id->dirfd = -1; 750 sqliteOsEnterMutex(); 751 releaseLockInfo(id->pLock); 752 sqliteOsLeaveMutex(); 753 TRACE2("CLOSE %-3d\n", id->fd); 754 OpenCounter(-1); 755 return SQLITE_OK; 756 #endif 757 #if OS_WIN 758 CloseHandle(id->h); 759 OpenCounter(-1); 760 return SQLITE_OK; 761 #endif 762 #if OS_MAC 763 if( id->refNumRF!=-1 ) 764 FSClose(id->refNumRF); 765 # ifdef _LARGE_FILE 766 FSCloseFork(id->refNum); 767 # else 768 FSClose(id->refNum); 769 # endif 770 if( id->delOnClose ){ 771 unlink(id->pathToDel); 772 sqliteFree(id->pathToDel); 773 } 774 OpenCounter(-1); 775 return SQLITE_OK; 776 #endif 777 } 778 779 /* 780 ** Read data from a file into a buffer. Return SQLITE_OK if all 781 ** bytes were read successfully and SQLITE_IOERR if anything goes 782 ** wrong. 783 */ 784 int sqliteOsRead(OsFile *id, void *pBuf, int amt){ 785 #if OS_UNIX 786 int got; 787 SimulateIOError(SQLITE_IOERR); 788 TIMER_START; 789 got = read(id->fd, pBuf, amt); 790 TIMER_END; 791 TRACE4("READ %-3d %7d %d\n", id->fd, last_page, elapse); 792 SEEK(0); 793 /* if( got<0 ) got = 0; */ 794 if( got==amt ){ 795 return SQLITE_OK; 796 }else{ 797 return SQLITE_IOERR; 798 } 799 #endif 800 #if OS_WIN 801 DWORD got; 802 SimulateIOError(SQLITE_IOERR); 803 TRACE2("READ %d\n", last_page); 804 if( !ReadFile(id->h, pBuf, amt, &got, 0) ){ 805 got = 0; 806 } 807 if( got==(DWORD)amt ){ 808 return SQLITE_OK; 809 }else{ 810 return SQLITE_IOERR; 811 } 812 #endif 813 #if OS_MAC 814 int got; 815 SimulateIOError(SQLITE_IOERR); 816 TRACE2("READ %d\n", last_page); 817 # ifdef _LARGE_FILE 818 FSReadFork(id->refNum, fsAtMark, 0, (ByteCount)amt, pBuf, (ByteCount*)&got); 819 # else 820 got = amt; 821 FSRead(id->refNum, &got, pBuf); 822 # endif 823 if( got==amt ){ 824 return SQLITE_OK; 825 }else{ 826 return SQLITE_IOERR; 827 } 828 #endif 829 } 830 831 /* 832 ** Write data from a buffer into a file. Return SQLITE_OK on success 833 ** or some other error code on failure. 834 */ 835 int sqliteOsWrite(OsFile *id, const void *pBuf, int amt){ 836 #if OS_UNIX 837 int wrote = 0; 838 SimulateIOError(SQLITE_IOERR); 839 TIMER_START; 840 while( amt>0 && (wrote = write(id->fd, pBuf, amt))>0 ){ 841 amt -= wrote; 842 pBuf = &((char*)pBuf)[wrote]; 843 } 844 TIMER_END; 845 TRACE4("WRITE %-3d %7d %d\n", id->fd, last_page, elapse); 846 SEEK(0); 847 if( amt>0 ){ 848 return SQLITE_FULL; 849 } 850 return SQLITE_OK; 851 #endif 852 #if OS_WIN 853 int rc; 854 DWORD wrote; 855 SimulateIOError(SQLITE_IOERR); 856 TRACE2("WRITE %d\n", last_page); 857 while( amt>0 && (rc = WriteFile(id->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){ 858 amt -= wrote; 859 pBuf = &((char*)pBuf)[wrote]; 860 } 861 if( !rc || amt>(int)wrote ){ 862 return SQLITE_FULL; 863 } 864 return SQLITE_OK; 865 #endif 866 #if OS_MAC 867 OSErr oserr; 868 int wrote = 0; 869 SimulateIOError(SQLITE_IOERR); 870 TRACE2("WRITE %d\n", last_page); 871 while( amt>0 ){ 872 # ifdef _LARGE_FILE 873 oserr = FSWriteFork(id->refNum, fsAtMark, 0, 874 (ByteCount)amt, pBuf, (ByteCount*)&wrote); 875 # else 876 wrote = amt; 877 oserr = FSWrite(id->refNum, &wrote, pBuf); 878 # endif 879 if( wrote == 0 || oserr != noErr) 880 break; 881 amt -= wrote; 882 pBuf = &((char*)pBuf)[wrote]; 883 } 884 if( oserr != noErr || amt>wrote ){ 885 return SQLITE_FULL; 886 } 887 return SQLITE_OK; 888 #endif 889 } 890 891 /* 892 ** Move the read/write pointer in a file. 893 */ 894 int sqliteOsSeek(OsFile *id, off_t offset){ 895 SEEK(offset/1024 + 1); 896 #if OS_UNIX 897 lseek(id->fd, offset, SEEK_SET); 898 return SQLITE_OK; 899 #endif 900 #if OS_WIN 901 { 902 LONG upperBits = offset>>32; 903 LONG lowerBits = offset & 0xffffffff; 904 DWORD rc; 905 rc = SetFilePointer(id->h, lowerBits, &upperBits, FILE_BEGIN); 906 /* TRACE3("SEEK rc=0x%x upper=0x%x\n", rc, upperBits); */ 907 } 908 return SQLITE_OK; 909 #endif 910 #if OS_MAC 911 { 912 off_t curSize; 913 if( sqliteOsFileSize(id, &curSize) != SQLITE_OK ){ 914 return SQLITE_IOERR; 915 } 916 if( offset >= curSize ){ 917 if( sqliteOsTruncate(id, offset+1) != SQLITE_OK ){ 918 return SQLITE_IOERR; 919 } 920 } 921 # ifdef _LARGE_FILE 922 if( FSSetForkPosition(id->refNum, fsFromStart, offset) != noErr ){ 923 # else 924 if( SetFPos(id->refNum, fsFromStart, offset) != noErr ){ 925 # endif 926 return SQLITE_IOERR; 927 }else{ 928 return SQLITE_OK; 929 } 930 } 931 #endif 932 } 933 934 /* 935 ** Make sure all writes to a particular file are committed to disk. 936 ** 937 ** Under Unix, also make sure that the directory entry for the file 938 ** has been created by fsync-ing the directory that contains the file. 939 ** If we do not do this and we encounter a power failure, the directory 940 ** entry for the journal might not exist after we reboot. The next 941 ** SQLite to access the file will not know that the journal exists (because 942 ** the directory entry for the journal was never created) and the transaction 943 ** will not roll back - possibly leading to database corruption. 944 */ 945 int sqliteOsSync(OsFile *id){ 946 #if OS_UNIX 947 SimulateIOError(SQLITE_IOERR); 948 TRACE2("SYNC %-3d\n", id->fd); 949 if( fsync(id->fd) ){ 950 return SQLITE_IOERR; 951 }else{ 952 if( id->dirfd>=0 ){ 953 TRACE2("DIRSYNC %-3d\n", id->dirfd); 954 fsync(id->dirfd); 955 close(id->dirfd); /* Only need to sync once, so close the directory */ 956 id->dirfd = -1; /* when we are done. */ 957 } 958 return SQLITE_OK; 959 } 960 #endif 961 #if OS_WIN 962 if( FlushFileBuffers(id->h) ){ 963 return SQLITE_OK; 964 }else{ 965 return SQLITE_IOERR; 966 } 967 #endif 968 #if OS_MAC 969 # ifdef _LARGE_FILE 970 if( FSFlushFork(id->refNum) != noErr ){ 971 # else 972 ParamBlockRec params; 973 memset(¶ms, 0, sizeof(ParamBlockRec)); 974 params.ioParam.ioRefNum = id->refNum; 975 if( PBFlushFileSync(¶ms) != noErr ){ 976 # endif 977 return SQLITE_IOERR; 978 }else{ 979 return SQLITE_OK; 980 } 981 #endif 982 } 983 984 /* 985 ** Truncate an open file to a specified size 986 */ 987 int sqliteOsTruncate(OsFile *id, off_t nByte){ 988 SimulateIOError(SQLITE_IOERR); 989 #if OS_UNIX 990 return ftruncate(id->fd, nByte)==0 ? SQLITE_OK : SQLITE_IOERR; 991 #endif 992 #if OS_WIN 993 { 994 LONG upperBits = nByte>>32; 995 SetFilePointer(id->h, nByte, &upperBits, FILE_BEGIN); 996 SetEndOfFile(id->h); 997 } 998 return SQLITE_OK; 999 #endif 1000 #if OS_MAC 1001 # ifdef _LARGE_FILE 1002 if( FSSetForkSize(id->refNum, fsFromStart, nByte) != noErr){ 1003 # else 1004 if( SetEOF(id->refNum, nByte) != noErr ){ 1005 # endif 1006 return SQLITE_IOERR; 1007 }else{ 1008 return SQLITE_OK; 1009 } 1010 #endif 1011 } 1012 1013 /* 1014 ** Determine the current size of a file in bytes 1015 */ 1016 int sqliteOsFileSize(OsFile *id, off_t *pSize){ 1017 #if OS_UNIX 1018 struct stat buf; 1019 SimulateIOError(SQLITE_IOERR); 1020 if( fstat(id->fd, &buf)!=0 ){ 1021 return SQLITE_IOERR; 1022 } 1023 *pSize = buf.st_size; 1024 return SQLITE_OK; 1025 #endif 1026 #if OS_WIN 1027 DWORD upperBits, lowerBits; 1028 SimulateIOError(SQLITE_IOERR); 1029 lowerBits = GetFileSize(id->h, &upperBits); 1030 *pSize = (((off_t)upperBits)<<32) + lowerBits; 1031 return SQLITE_OK; 1032 #endif 1033 #if OS_MAC 1034 # ifdef _LARGE_FILE 1035 if( FSGetForkSize(id->refNum, pSize) != noErr){ 1036 # else 1037 if( GetEOF(id->refNum, pSize) != noErr ){ 1038 # endif 1039 return SQLITE_IOERR; 1040 }else{ 1041 return SQLITE_OK; 1042 } 1043 #endif 1044 } 1045 1046 #if OS_WIN 1047 /* 1048 ** Return true (non-zero) if we are running under WinNT, Win2K or WinXP. 1049 ** Return false (zero) for Win95, Win98, or WinME. 1050 ** 1051 ** Here is an interesting observation: Win95, Win98, and WinME lack 1052 ** the LockFileEx() API. But we can still statically link against that 1053 ** API as long as we don't call it win running Win95/98/ME. A call to 1054 ** this routine is used to determine if the host is Win95/98/ME or 1055 ** WinNT/2K/XP so that we will know whether or not we can safely call 1056 ** the LockFileEx() API. 1057 */ 1058 int isNT(void){ 1059 static osType = 0; /* 0=unknown 1=win95 2=winNT */ 1060 if( osType==0 ){ 1061 OSVERSIONINFO sInfo; 1062 sInfo.dwOSVersionInfoSize = sizeof(sInfo); 1063 GetVersionEx(&sInfo); 1064 osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; 1065 } 1066 return osType==2; 1067 } 1068 #endif 1069 1070 /* 1071 ** Windows file locking notes: [similar issues apply to MacOS] 1072 ** 1073 ** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because 1074 ** those functions are not available. So we use only LockFile() and 1075 ** UnlockFile(). 1076 ** 1077 ** LockFile() prevents not just writing but also reading by other processes. 1078 ** (This is a design error on the part of Windows, but there is nothing 1079 ** we can do about that.) So the region used for locking is at the 1080 ** end of the file where it is unlikely to ever interfere with an 1081 ** actual read attempt. 1082 ** 1083 ** A database read lock is obtained by locking a single randomly-chosen 1084 ** byte out of a specific range of bytes. The lock byte is obtained at 1085 ** random so two separate readers can probably access the file at the 1086 ** same time, unless they are unlucky and choose the same lock byte. 1087 ** A database write lock is obtained by locking all bytes in the range. 1088 ** There can only be one writer. 1089 ** 1090 ** A lock is obtained on the first byte of the lock range before acquiring 1091 ** either a read lock or a write lock. This prevents two processes from 1092 ** attempting to get a lock at a same time. The semantics of 1093 ** sqliteOsReadLock() require that if there is already a write lock, that 1094 ** lock is converted into a read lock atomically. The lock on the first 1095 ** byte allows us to drop the old write lock and get the read lock without 1096 ** another process jumping into the middle and messing us up. The same 1097 ** argument applies to sqliteOsWriteLock(). 1098 ** 1099 ** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available, 1100 ** which means we can use reader/writer locks. When reader writer locks 1101 ** are used, the lock is placed on the same range of bytes that is used 1102 ** for probabilistic locking in Win95/98/ME. Hence, the locking scheme 1103 ** will support two or more Win95 readers or two or more WinNT readers. 1104 ** But a single Win95 reader will lock out all WinNT readers and a single 1105 ** WinNT reader will lock out all other Win95 readers. 1106 ** 1107 ** Note: On MacOS we use the resource fork for locking. 1108 ** 1109 ** The following #defines specify the range of bytes used for locking. 1110 ** N_LOCKBYTE is the number of bytes available for doing the locking. 1111 ** The first byte used to hold the lock while the lock is changing does 1112 ** not count toward this number. FIRST_LOCKBYTE is the address of 1113 ** the first byte in the range of bytes used for locking. 1114 */ 1115 #define N_LOCKBYTE 10239 1116 #if OS_MAC 1117 # define FIRST_LOCKBYTE (0x000fffff - N_LOCKBYTE) 1118 #else 1119 # define FIRST_LOCKBYTE (0xffffffff - N_LOCKBYTE) 1120 #endif 1121 1122 /* 1123 ** Change the status of the lock on the file "id" to be a readlock. 1124 ** If the file was write locked, then this reduces the lock to a read. 1125 ** If the file was read locked, then this acquires a new read lock. 1126 ** 1127 ** Return SQLITE_OK on success and SQLITE_BUSY on failure. If this 1128 ** library was compiled with large file support (LFS) but LFS is not 1129 ** available on the host, then an SQLITE_NOLFS is returned. 1130 */ 1131 int sqliteOsReadLock(OsFile *id){ 1132 #if OS_UNIX 1133 int rc; 1134 sqliteOsEnterMutex(); 1135 if( id->pLock->cnt>0 ){ 1136 if( !id->locked ){ 1137 id->pLock->cnt++; 1138 id->locked = 1; 1139 } 1140 rc = SQLITE_OK; 1141 }else if( id->locked || id->pLock->cnt==0 ){ 1142 struct flock lock; 1143 int s; 1144 lock.l_type = F_RDLCK; 1145 lock.l_whence = SEEK_SET; 1146 lock.l_start = lock.l_len = 0L; 1147 s = fcntl(id->fd, F_SETLK, &lock); 1148 if( s!=0 ){ 1149 rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY; 1150 }else{ 1151 rc = SQLITE_OK; 1152 id->pLock->cnt = 1; 1153 id->locked = 1; 1154 } 1155 }else{ 1156 rc = SQLITE_BUSY; 1157 } 1158 sqliteOsLeaveMutex(); 1159 return rc; 1160 #endif 1161 #if OS_WIN 1162 int rc; 1163 if( id->locked>0 ){ 1164 rc = SQLITE_OK; 1165 }else{ 1166 int lk = (sqliteRandomInteger() & 0x7ffffff)%N_LOCKBYTE+1; 1167 int res; 1168 int cnt = 100; 1169 while( cnt-->0 && (res = LockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0))==0 ){ 1170 Sleep(1); 1171 } 1172 if( res ){ 1173 UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0); 1174 if( isNT() ){ 1175 OVERLAPPED ovlp; 1176 ovlp.Offset = FIRST_LOCKBYTE+1; 1177 ovlp.OffsetHigh = 0; 1178 ovlp.hEvent = 0; 1179 res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY, 1180 0, N_LOCKBYTE, 0, &ovlp); 1181 }else{ 1182 res = LockFile(id->h, FIRST_LOCKBYTE+lk, 0, 1, 0); 1183 } 1184 UnlockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0); 1185 } 1186 if( res ){ 1187 id->locked = lk; 1188 rc = SQLITE_OK; 1189 }else{ 1190 rc = SQLITE_BUSY; 1191 } 1192 } 1193 return rc; 1194 #endif 1195 #if OS_MAC 1196 int rc; 1197 if( id->locked>0 || id->refNumRF == -1 ){ 1198 rc = SQLITE_OK; 1199 }else{ 1200 int lk = (sqliteRandomInteger() & 0x7ffffff)%N_LOCKBYTE+1; 1201 OSErr res; 1202 int cnt = 5; 1203 ParamBlockRec params; 1204 memset(¶ms, 0, sizeof(params)); 1205 params.ioParam.ioRefNum = id->refNumRF; 1206 params.ioParam.ioPosMode = fsFromStart; 1207 params.ioParam.ioPosOffset = FIRST_LOCKBYTE; 1208 params.ioParam.ioReqCount = 1; 1209 while( cnt-->0 && (res = PBLockRangeSync(¶ms))!=noErr ){ 1210 UInt32 finalTicks; 1211 Delay(1, &finalTicks); /* 1/60 sec */ 1212 } 1213 if( res == noErr ){ 1214 params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1; 1215 params.ioParam.ioReqCount = N_LOCKBYTE; 1216 PBUnlockRangeSync(¶ms); 1217 params.ioParam.ioPosOffset = FIRST_LOCKBYTE+lk; 1218 params.ioParam.ioReqCount = 1; 1219 res = PBLockRangeSync(¶ms); 1220 params.ioParam.ioPosOffset = FIRST_LOCKBYTE; 1221 params.ioParam.ioReqCount = 1; 1222 PBUnlockRangeSync(¶ms); 1223 } 1224 if( res == noErr ){ 1225 id->locked = lk; 1226 rc = SQLITE_OK; 1227 }else{ 1228 rc = SQLITE_BUSY; 1229 } 1230 } 1231 return rc; 1232 #endif 1233 } 1234 1235 /* 1236 ** Change the lock status to be an exclusive or write lock. Return 1237 ** SQLITE_OK on success and SQLITE_BUSY on a failure. If this 1238 ** library was compiled with large file support (LFS) but LFS is not 1239 ** available on the host, then an SQLITE_NOLFS is returned. 1240 */ 1241 int sqliteOsWriteLock(OsFile *id){ 1242 #if OS_UNIX 1243 int rc; 1244 sqliteOsEnterMutex(); 1245 if( id->pLock->cnt==0 || (id->pLock->cnt==1 && id->locked==1) ){ 1246 struct flock lock; 1247 int s; 1248 lock.l_type = F_WRLCK; 1249 lock.l_whence = SEEK_SET; 1250 lock.l_start = lock.l_len = 0L; 1251 s = fcntl(id->fd, F_SETLK, &lock); 1252 if( s!=0 ){ 1253 rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY; 1254 }else{ 1255 rc = SQLITE_OK; 1256 id->pLock->cnt = -1; 1257 id->locked = 1; 1258 } 1259 }else{ 1260 rc = SQLITE_BUSY; 1261 } 1262 sqliteOsLeaveMutex(); 1263 return rc; 1264 #endif 1265 #if OS_WIN 1266 int rc; 1267 if( id->locked<0 ){ 1268 rc = SQLITE_OK; 1269 }else{ 1270 int res; 1271 int cnt = 100; 1272 while( cnt-->0 && (res = LockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0))==0 ){ 1273 Sleep(1); 1274 } 1275 if( res ){ 1276 if( id->locked>0 ){ 1277 if( isNT() ){ 1278 UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0); 1279 }else{ 1280 res = UnlockFile(id->h, FIRST_LOCKBYTE + id->locked, 0, 1, 0); 1281 } 1282 } 1283 if( res ){ 1284 res = LockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0); 1285 }else{ 1286 res = 0; 1287 } 1288 UnlockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0); 1289 } 1290 if( res ){ 1291 id->locked = -1; 1292 rc = SQLITE_OK; 1293 }else{ 1294 rc = SQLITE_BUSY; 1295 } 1296 } 1297 return rc; 1298 #endif 1299 #if OS_MAC 1300 int rc; 1301 if( id->locked<0 || id->refNumRF == -1 ){ 1302 rc = SQLITE_OK; 1303 }else{ 1304 OSErr res; 1305 int cnt = 5; 1306 ParamBlockRec params; 1307 memset(¶ms, 0, sizeof(params)); 1308 params.ioParam.ioRefNum = id->refNumRF; 1309 params.ioParam.ioPosMode = fsFromStart; 1310 params.ioParam.ioPosOffset = FIRST_LOCKBYTE; 1311 params.ioParam.ioReqCount = 1; 1312 while( cnt-->0 && (res = PBLockRangeSync(¶ms))!=noErr ){ 1313 UInt32 finalTicks; 1314 Delay(1, &finalTicks); /* 1/60 sec */ 1315 } 1316 if( res == noErr ){ 1317 params.ioParam.ioPosOffset = FIRST_LOCKBYTE + id->locked; 1318 params.ioParam.ioReqCount = 1; 1319 if( id->locked==0 1320 || PBUnlockRangeSync(¶ms)==noErr ){ 1321 params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1; 1322 params.ioParam.ioReqCount = N_LOCKBYTE; 1323 res = PBLockRangeSync(¶ms); 1324 }else{ 1325 res = afpRangeNotLocked; 1326 } 1327 params.ioParam.ioPosOffset = FIRST_LOCKBYTE; 1328 params.ioParam.ioReqCount = 1; 1329 PBUnlockRangeSync(¶ms); 1330 } 1331 if( res == noErr ){ 1332 id->locked = -1; 1333 rc = SQLITE_OK; 1334 }else{ 1335 rc = SQLITE_BUSY; 1336 } 1337 } 1338 return rc; 1339 #endif 1340 } 1341 1342 /* 1343 ** Unlock the given file descriptor. If the file descriptor was 1344 ** not previously locked, then this routine is a no-op. If this 1345 ** library was compiled with large file support (LFS) but LFS is not 1346 ** available on the host, then an SQLITE_NOLFS is returned. 1347 */ 1348 int sqliteOsUnlock(OsFile *id){ 1349 #if OS_UNIX 1350 int rc; 1351 if( !id->locked ) return SQLITE_OK; 1352 sqliteOsEnterMutex(); 1353 assert( id->pLock->cnt!=0 ); 1354 if( id->pLock->cnt>1 ){ 1355 id->pLock->cnt--; 1356 rc = SQLITE_OK; 1357 }else{ 1358 struct flock lock; 1359 int s; 1360 lock.l_type = F_UNLCK; 1361 lock.l_whence = SEEK_SET; 1362 lock.l_start = lock.l_len = 0L; 1363 s = fcntl(id->fd, F_SETLK, &lock); 1364 if( s!=0 ){ 1365 rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY; 1366 }else{ 1367 rc = SQLITE_OK; 1368 id->pLock->cnt = 0; 1369 } 1370 } 1371 sqliteOsLeaveMutex(); 1372 id->locked = 0; 1373 return rc; 1374 #endif 1375 #if OS_WIN 1376 int rc; 1377 if( id->locked==0 ){ 1378 rc = SQLITE_OK; 1379 }else if( isNT() || id->locked<0 ){ 1380 UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0); 1381 rc = SQLITE_OK; 1382 id->locked = 0; 1383 }else{ 1384 UnlockFile(id->h, FIRST_LOCKBYTE+id->locked, 0, 1, 0); 1385 rc = SQLITE_OK; 1386 id->locked = 0; 1387 } 1388 return rc; 1389 #endif 1390 #if OS_MAC 1391 int rc; 1392 ParamBlockRec params; 1393 memset(¶ms, 0, sizeof(params)); 1394 params.ioParam.ioRefNum = id->refNumRF; 1395 params.ioParam.ioPosMode = fsFromStart; 1396 if( id->locked==0 || id->refNumRF == -1 ){ 1397 rc = SQLITE_OK; 1398 }else if( id->locked<0 ){ 1399 params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1; 1400 params.ioParam.ioReqCount = N_LOCKBYTE; 1401 PBUnlockRangeSync(¶ms); 1402 rc = SQLITE_OK; 1403 id->locked = 0; 1404 }else{ 1405 params.ioParam.ioPosOffset = FIRST_LOCKBYTE+id->locked; 1406 params.ioParam.ioReqCount = 1; 1407 PBUnlockRangeSync(¶ms); 1408 rc = SQLITE_OK; 1409 id->locked = 0; 1410 } 1411 return rc; 1412 #endif 1413 } 1414 1415 /* 1416 ** Get information to seed the random number generator. The seed 1417 ** is written into the buffer zBuf[256]. The calling function must 1418 ** supply a sufficiently large buffer. 1419 */ 1420 int sqliteOsRandomSeed(char *zBuf){ 1421 #ifdef SQLITE_TEST 1422 /* When testing, always use the same random number sequence. 1423 ** This makes the tests repeatable. 1424 */ 1425 memset(zBuf, 0, 256); 1426 #endif 1427 #if OS_UNIX && !defined(SQLITE_TEST) 1428 int pid; 1429 time((time_t*)zBuf); 1430 pid = getpid(); 1431 memcpy(&zBuf[sizeof(time_t)], &pid, sizeof(pid)); 1432 #endif 1433 #if OS_WIN && !defined(SQLITE_TEST) 1434 GetSystemTime((LPSYSTEMTIME)zBuf); 1435 #endif 1436 #if OS_MAC 1437 int pid; 1438 Microseconds((UnsignedWide*)zBuf); 1439 pid = getpid(); 1440 memcpy(&zBuf[sizeof(UnsignedWide)], &pid, sizeof(pid)); 1441 #endif 1442 return SQLITE_OK; 1443 } 1444 1445 /* 1446 ** Sleep for a little while. Return the amount of time slept. 1447 */ 1448 int sqliteOsSleep(int ms){ 1449 #if OS_UNIX 1450 #if defined(HAVE_USLEEP) && HAVE_USLEEP 1451 usleep(ms*1000); 1452 return ms; 1453 #else 1454 sleep((ms+999)/1000); 1455 return 1000*((ms+999)/1000); 1456 #endif 1457 #endif 1458 #if OS_WIN 1459 Sleep(ms); 1460 return ms; 1461 #endif 1462 #if OS_MAC 1463 UInt32 finalTicks; 1464 UInt32 ticks = (((UInt32)ms+16)*3)/50; /* 1/60 sec per tick */ 1465 Delay(ticks, &finalTicks); 1466 return (int)((ticks*50)/3); 1467 #endif 1468 } 1469 1470 /* 1471 ** Macros used to determine whether or not to use threads. The 1472 ** SQLITE_UNIX_THREADS macro is defined if we are synchronizing for 1473 ** Posix threads and SQLITE_W32_THREADS is defined if we are 1474 ** synchronizing using Win32 threads. 1475 */ 1476 #if OS_UNIX && defined(THREADSAFE) && THREADSAFE 1477 # include <pthread.h> 1478 # define SQLITE_UNIX_THREADS 1 1479 #endif 1480 #if OS_WIN && defined(THREADSAFE) && THREADSAFE 1481 # define SQLITE_W32_THREADS 1 1482 #endif 1483 #if OS_MAC && defined(THREADSAFE) && THREADSAFE 1484 # include <Multiprocessing.h> 1485 # define SQLITE_MACOS_MULTITASKING 1 1486 #endif 1487 1488 /* 1489 ** Static variables used for thread synchronization 1490 */ 1491 static int inMutex = 0; 1492 #ifdef SQLITE_UNIX_THREADS 1493 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 1494 #endif 1495 #ifdef SQLITE_W32_THREADS 1496 static CRITICAL_SECTION cs; 1497 #endif 1498 #ifdef SQLITE_MACOS_MULTITASKING 1499 static MPCriticalRegionID criticalRegion; 1500 #endif 1501 1502 /* 1503 ** The following pair of routine implement mutual exclusion for 1504 ** multi-threaded processes. Only a single thread is allowed to 1505 ** executed code that is surrounded by EnterMutex() and LeaveMutex(). 1506 ** 1507 ** SQLite uses only a single Mutex. There is not much critical 1508 ** code and what little there is executes quickly and without blocking. 1509 */ 1510 void sqliteOsEnterMutex(){ 1511 #ifdef SQLITE_UNIX_THREADS 1512 pthread_mutex_lock(&mutex); 1513 #endif 1514 #ifdef SQLITE_W32_THREADS 1515 static int isInit = 0; 1516 while( !isInit ){ 1517 static long lock = 0; 1518 if( InterlockedIncrement(&lock)==1 ){ 1519 InitializeCriticalSection(&cs); 1520 isInit = 1; 1521 }else{ 1522 Sleep(1); 1523 } 1524 } 1525 EnterCriticalSection(&cs); 1526 #endif 1527 #ifdef SQLITE_MACOS_MULTITASKING 1528 static volatile int notInit = 1; 1529 if( notInit ){ 1530 if( notInit == 2 ) /* as close as you can get to thread safe init */ 1531 MPYield(); 1532 else{ 1533 notInit = 2; 1534 MPCreateCriticalRegion(&criticalRegion); 1535 notInit = 0; 1536 } 1537 } 1538 MPEnterCriticalRegion(criticalRegion, kDurationForever); 1539 #endif 1540 assert( !inMutex ); 1541 inMutex = 1; 1542 } 1543 void sqliteOsLeaveMutex(){ 1544 assert( inMutex ); 1545 inMutex = 0; 1546 #ifdef SQLITE_UNIX_THREADS 1547 pthread_mutex_unlock(&mutex); 1548 #endif 1549 #ifdef SQLITE_W32_THREADS 1550 LeaveCriticalSection(&cs); 1551 #endif 1552 #ifdef SQLITE_MACOS_MULTITASKING 1553 MPExitCriticalRegion(criticalRegion); 1554 #endif 1555 } 1556 1557 /* 1558 ** Turn a relative pathname into a full pathname. Return a pointer 1559 ** to the full pathname stored in space obtained from sqliteMalloc(). 1560 ** The calling function is responsible for freeing this space once it 1561 ** is no longer needed. 1562 */ 1563 char *sqliteOsFullPathname(const char *zRelative){ 1564 #if OS_UNIX 1565 char *zFull = 0; 1566 if( zRelative[0]=='/' ){ 1567 sqliteSetString(&zFull, zRelative, 0); 1568 }else{ 1569 char zBuf[5000]; 1570 sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), "/", zRelative, 0); 1571 } 1572 return zFull; 1573 #endif 1574 #if OS_WIN 1575 char *zNotUsed; 1576 char *zFull; 1577 int nByte; 1578 nByte = GetFullPathName(zRelative, 0, 0, &zNotUsed) + 1; 1579 zFull = sqliteMalloc( nByte ); 1580 if( zFull==0 ) return 0; 1581 GetFullPathName(zRelative, nByte, zFull, &zNotUsed); 1582 return zFull; 1583 #endif 1584 #if OS_MAC 1585 char *zFull = 0; 1586 if( zRelative[0]==':' ){ 1587 char zBuf[_MAX_PATH+1]; 1588 sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), &(zRelative[1]), 0); 1589 }else{ 1590 if( strchr(zRelative, ':') ){ 1591 sqliteSetString(&zFull, zRelative, 0); 1592 }else{ 1593 char zBuf[_MAX_PATH+1]; 1594 sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), zRelative, 0); 1595 } 1596 } 1597 return zFull; 1598 #endif 1599 } 1600 1601 /* 1602 ** Find the current time (in Universal Coordinated Time). Write the 1603 ** current time and date as a Julian Day number into *prNow and 1604 ** return 0. Return 1 if the time and date cannot be found. 1605 */ 1606 int sqliteOsCurrentTime(double *prNow){ 1607 #if OS_UNIX 1608 time_t t; 1609 time(&t); 1610 *prNow = t/86400.0 + 2440587.5; 1611 return 0; 1612 #endif 1613 #if OS_WIN 1614 FILETIME ft; 1615 /* FILETIME structure is a 64-bit value representing the number of 1616 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 1617 */ 1618 double now; 1619 GetSystemTimeAsFileTime( &ft ); 1620 now = ((double)ft.dwHighDateTime) * 4294967296.0; 1621 *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5; 1622 #endif 1623 return 0; 1624 1625 return 1; 1626 } 1627