source: trunk/src/3rdparty/sqlite/os.c

Last change on this file was 205, checked in by rudi, 14 years ago

Added SQLite 2.8.17 sources. This allows to build at least one of the sql drivers / plugins.

File size: 58.9 KB
Line 
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#if OS_OS2
40# include <time.h>
41# include <errno.h>
42# include <unistd.h>
43# define INCL_DOSFILEMGR
44# define INCL_DOSERRORS
45# define INCL_DOSPROCESS
46# include <os2.h>
47# include <stdio.h>
48# include <stdlib.h>
49# include <io.h>
50# include <share.h>
51#endif
52
53#if OS_WIN
54# include <winbase.h>
55#endif
56
57#if OS_MAC
58# include <extras.h>
59# include <path2fss.h>
60# include <TextUtils.h>
61# include <FinderRegistry.h>
62# include <Folders.h>
63# include <Timer.h>
64# include <OSUtils.h>
65#endif
66
67/*
68** The DJGPP compiler environment looks mostly like Unix, but it
69** lacks the fcntl() system call. So redefine fcntl() to be something
70** that always succeeds. This means that locking does not occur under
71** DJGPP. But its DOS - what did you expect?
72*/
73#ifdef __DJGPP__
74# define fcntl(A,B,C) 0
75#endif
76
77/*
78** Macros used to determine whether or not to use threads. The
79** SQLITE_UNIX_THREADS macro is defined if we are synchronizing for
80** Posix threads and SQLITE_W32_THREADS is defined if we are
81** synchronizing using Win32 threads.
82*/
83#if OS_UNIX && defined(THREADSAFE) && THREADSAFE
84# include <pthread.h>
85# define SQLITE_UNIX_THREADS 1
86#endif
87#if OS_WIN && defined(THREADSAFE) && THREADSAFE
88# define SQLITE_W32_THREADS 1
89#endif
90#if OS_MAC && defined(THREADSAFE) && THREADSAFE
91# include <Multiprocessing.h>
92# define SQLITE_MACOS_MULTITASKING 1
93#endif
94#if OS_OS2 && defined(THREADSAFE) && THREADSAFE
95/* this mutex implementation only available with EMX */
96# include <sys/builtin.h>
97# include <sys/smutex.h>
98# define SQLITE_OS2_THREADS 1
99#endif
100
101/*
102** Macros for performance tracing. Normally turned off
103*/
104#if 0
105static int last_page = 0;
106__inline__ unsigned long long int hwtime(void){
107 unsigned long long int x;
108 __asm__("rdtsc\n\t"
109 "mov %%edx, %%ecx\n\t"
110 :"=A" (x));
111 return x;
112}
113static unsigned long long int g_start;
114static unsigned int elapse;
115#define TIMER_START g_start=hwtime()
116#define TIMER_END elapse=hwtime()-g_start
117#define SEEK(X) last_page=(X)
118#define TRACE1(X) fprintf(stderr,X)
119#define TRACE2(X,Y) fprintf(stderr,X,Y)
120#define TRACE3(X,Y,Z) fprintf(stderr,X,Y,Z)
121#define TRACE4(X,Y,Z,A) fprintf(stderr,X,Y,Z,A)
122#define TRACE5(X,Y,Z,A,B) fprintf(stderr,X,Y,Z,A,B)
123#else
124#define TIMER_START
125#define TIMER_END
126#define SEEK(X)
127#define TRACE1(X)
128#define TRACE2(X,Y)
129#define TRACE3(X,Y,Z)
130#define TRACE4(X,Y,Z,A)
131#define TRACE5(X,Y,Z,A,B)
132#endif
133
134
135#if OS_UNIX
136/*
137** Here is the dirt on POSIX advisory locks: ANSI STD 1003.1 (1996)
138** section 6.5.2.2 lines 483 through 490 specify that when a process
139** sets or clears a lock, that operation overrides any prior locks set
140** by the same process. It does not explicitly say so, but this implies
141** that it overrides locks set by the same process using a different
142** file descriptor. Consider this test case:
143**
144** int fd1 = open("./file1", O_RDWR|O_CREAT, 0644);
145** int fd2 = open("./file2", O_RDWR|O_CREAT, 0644);
146**
147** Suppose ./file1 and ./file2 are really the same file (because
148** one is a hard or symbolic link to the other) then if you set
149** an exclusive lock on fd1, then try to get an exclusive lock
150** on fd2, it works. I would have expected the second lock to
151** fail since there was already a lock on the file due to fd1.
152** But not so. Since both locks came from the same process, the
153** second overrides the first, even though they were on different
154** file descriptors opened on different file names.
155**
156** Bummer. If you ask me, this is broken. Badly broken. It means
157** that we cannot use POSIX locks to synchronize file access among
158** competing threads of the same process. POSIX locks will work fine
159** to synchronize access for threads in separate processes, but not
160** threads within the same process.
161**
162** To work around the problem, SQLite has to manage file locks internally
163** on its own. Whenever a new database is opened, we have to find the
164** specific inode of the database file (the inode is determined by the
165** st_dev and st_ino fields of the stat structure that fstat() fills in)
166** and check for locks already existing on that inode. When locks are
167** created or removed, we have to look at our own internal record of the
168** locks to see if another thread has previously set a lock on that same
169** inode.
170**
171** The OsFile structure for POSIX is no longer just an integer file
172** descriptor. It is now a structure that holds the integer file
173** descriptor and a pointer to a structure that describes the internal
174** locks on the corresponding inode. There is one locking structure
175** per inode, so if the same inode is opened twice, both OsFile structures
176** point to the same locking structure. The locking structure keeps
177** a reference count (so we will know when to delete it) and a "cnt"
178** field that tells us its internal lock status. cnt==0 means the
179** file is unlocked. cnt==-1 means the file has an exclusive lock.
180** cnt>0 means there are cnt shared locks on the file.
181**
182** Any attempt to lock or unlock a file first checks the locking
183** structure. The fcntl() system call is only invoked to set a
184** POSIX lock if the internal lock structure transitions between
185** a locked and an unlocked state.
186**
187** 2004-Jan-11:
188** More recent discoveries about POSIX advisory locks. (The more
189** I discover, the more I realize the a POSIX advisory locks are
190** an abomination.)
191**
192** If you close a file descriptor that points to a file that has locks,
193** all locks on that file that are owned by the current process are
194** released. To work around this problem, each OsFile structure contains
195** a pointer to an openCnt structure. There is one openCnt structure
196** per open inode, which means that multiple OsFiles can point to a single
197** openCnt. When an attempt is made to close an OsFile, if there are
198** other OsFiles open on the same inode that are holding locks, the call
199** to close() the file descriptor is deferred until all of the locks clear.
200** The openCnt structure keeps a list of file descriptors that need to
201** be closed and that list is walked (and cleared) when the last lock
202** clears.
203**
204** First, under Linux threads, because each thread has a separate
205** process ID, lock operations in one thread do not override locks
206** to the same file in other threads. Linux threads behave like
207** separate processes in this respect. But, if you close a file
208** descriptor in linux threads, all locks are cleared, even locks
209** on other threads and even though the other threads have different
210** process IDs. Linux threads is inconsistent in this respect.
211** (I'm beginning to think that linux threads is an abomination too.)
212** The consequence of this all is that the hash table for the lockInfo
213** structure has to include the process id as part of its key because
214** locks in different threads are treated as distinct. But the
215** openCnt structure should not include the process id in its
216** key because close() clears lock on all threads, not just the current
217** thread. Were it not for this goofiness in linux threads, we could
218** combine the lockInfo and openCnt structures into a single structure.
219*/
220
221/*
222** An instance of the following structure serves as the key used
223** to locate a particular lockInfo structure given its inode. Note
224** that we have to include the process ID as part of the key. On some
225** threading implementations (ex: linux), each thread has a separate
226** process ID.
227*/
228struct lockKey {
229 dev_t dev; /* Device number */
230 ino_t ino; /* Inode number */
231 pid_t pid; /* Process ID */
232};
233
234/*
235** An instance of the following structure is allocated for each open
236** inode on each thread with a different process ID. (Threads have
237** different process IDs on linux, but not on most other unixes.)
238**
239** A single inode can have multiple file descriptors, so each OsFile
240** structure contains a pointer to an instance of this object and this
241** object keeps a count of the number of OsFiles pointing to it.
242*/
243struct lockInfo {
244 struct lockKey key; /* The lookup key */
245 int cnt; /* 0: unlocked. -1: write lock. 1...: read lock. */
246 int nRef; /* Number of pointers to this structure */
247};
248
249/*
250** An instance of the following structure serves as the key used
251** to locate a particular openCnt structure given its inode. This
252** is the same as the lockKey except that the process ID is omitted.
253*/
254struct openKey {
255 dev_t dev; /* Device number */
256 ino_t ino; /* Inode number */
257};
258
259/*
260** An instance of the following structure is allocated for each open
261** inode. This structure keeps track of the number of locks on that
262** inode. If a close is attempted against an inode that is holding
263** locks, the close is deferred until all locks clear by adding the
264** file descriptor to be closed to the pending list.
265*/
266struct openCnt {
267 struct openKey key; /* The lookup key */
268 int nRef; /* Number of pointers to this structure */
269 int nLock; /* Number of outstanding locks */
270 int nPending; /* Number of pending close() operations */
271 int *aPending; /* Malloced space holding fd's awaiting a close() */
272};
273
274/*
275** These hash table maps inodes and process IDs into lockInfo and openCnt
276** structures. Access to these hash tables must be protected by a mutex.
277*/
278static Hash lockHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };
279static Hash openHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };
280
281/*
282** Release a lockInfo structure previously allocated by findLockInfo().
283*/
284static void releaseLockInfo(struct lockInfo *pLock){
285 pLock->nRef--;
286 if( pLock->nRef==0 ){
287 sqliteHashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0);
288 sqliteFree(pLock);
289 }
290}
291
292/*
293** Release a openCnt structure previously allocated by findLockInfo().
294*/
295static void releaseOpenCnt(struct openCnt *pOpen){
296 pOpen->nRef--;
297 if( pOpen->nRef==0 ){
298 sqliteHashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0);
299 sqliteFree(pOpen->aPending);
300 sqliteFree(pOpen);
301 }
302}
303
304/*
305** Given a file descriptor, locate lockInfo and openCnt structures that
306** describes that file descriptor. Create a new ones if necessary. The
307** return values might be unset if an error occurs.
308**
309** Return the number of errors.
310*/
311int findLockInfo(
312 int fd, /* The file descriptor used in the key */
313 struct lockInfo **ppLock, /* Return the lockInfo structure here */
314 struct openCnt **ppOpen /* Return the openCnt structure here */
315){
316 int rc;
317 struct lockKey key1;
318 struct openKey key2;
319 struct stat statbuf;
320 struct lockInfo *pLock;
321 struct openCnt *pOpen;
322 rc = fstat(fd, &statbuf);
323 if( rc!=0 ) return 1;
324 memset(&key1, 0, sizeof(key1));
325 key1.dev = statbuf.st_dev;
326 key1.ino = statbuf.st_ino;
327 key1.pid = getpid();
328 memset(&key2, 0, sizeof(key2));
329 key2.dev = statbuf.st_dev;
330 key2.ino = statbuf.st_ino;
331 pLock = (struct lockInfo*)sqliteHashFind(&lockHash, &key1, sizeof(key1));
332 if( pLock==0 ){
333 struct lockInfo *pOld;
334 pLock = sqliteMallocRaw( sizeof(*pLock) );
335 if( pLock==0 ) return 1;
336 pLock->key = key1;
337 pLock->nRef = 1;
338 pLock->cnt = 0;
339 pOld = sqliteHashInsert(&lockHash, &pLock->key, sizeof(key1), pLock);
340 if( pOld!=0 ){
341 assert( pOld==pLock );
342 sqliteFree(pLock);
343 return 1;
344 }
345 }else{
346 pLock->nRef++;
347 }
348 *ppLock = pLock;
349 pOpen = (struct openCnt*)sqliteHashFind(&openHash, &key2, sizeof(key2));
350 if( pOpen==0 ){
351 struct openCnt *pOld;
352 pOpen = sqliteMallocRaw( sizeof(*pOpen) );
353 if( pOpen==0 ){
354 releaseLockInfo(pLock);
355 return 1;
356 }
357 pOpen->key = key2;
358 pOpen->nRef = 1;
359 pOpen->nLock = 0;
360 pOpen->nPending = 0;
361 pOpen->aPending = 0;
362 pOld = sqliteHashInsert(&openHash, &pOpen->key, sizeof(key2), pOpen);
363 if( pOld!=0 ){
364 assert( pOld==pOpen );
365 sqliteFree(pOpen);
366 releaseLockInfo(pLock);
367 return 1;
368 }
369 }else{
370 pOpen->nRef++;
371 }
372 *ppOpen = pOpen;
373 return 0;
374}
375
376#endif /** POSIX advisory lock work-around **/
377
378/*
379** If we compile with the SQLITE_TEST macro set, then the following block
380** of code will give us the ability to simulate a disk I/O error. This
381** is used for testing the I/O recovery logic.
382*/
383#ifdef SQLITE_TEST
384int sqlite_io_error_pending = 0;
385#define SimulateIOError(A) \
386 if( sqlite_io_error_pending ) \
387 if( sqlite_io_error_pending-- == 1 ){ local_ioerr(); return A; }
388static void local_ioerr(){
389 sqlite_io_error_pending = 0; /* Really just a place to set a breakpoint */
390}
391#else
392#define SimulateIOError(A)
393#endif
394
395/*
396** When testing, keep a count of the number of open files.
397*/
398#ifdef SQLITE_TEST
399int sqlite_open_file_count = 0;
400#define OpenCounter(X) sqlite_open_file_count+=(X)
401#else
402#define OpenCounter(X)
403#endif
404
405
406/*
407** Delete the named file
408*/
409int sqliteOsDelete(const char *zFilename){
410#if OS_UNIX
411 unlink(zFilename);
412#endif
413#if OS_WIN
414 DeleteFile(zFilename);
415#endif
416#if OS_MAC
417 unlink(zFilename);
418#endif
419#if OS_OS2
420 unlink(zFilename);
421#endif
422 return SQLITE_OK;
423}
424
425/*
426** Return TRUE if the named file exists.
427*/
428int sqliteOsFileExists(const char *zFilename){
429#if OS_UNIX
430 return access(zFilename, 0)==0;
431#endif
432#if OS_WIN
433 return GetFileAttributes(zFilename) != 0xffffffff;
434#endif
435#if OS_MAC
436 return access(zFilename, 0)==0;
437#endif
438#if OS_OS2
439 return access(zFilename, 0)==0;
440#endif
441}
442
443
444#if 0 /* NOT USED */
445/*
446** Change the name of an existing file.
447*/
448int sqliteOsFileRename(const char *zOldName, const char *zNewName){
449#if OS_UNIX
450 if( link(zOldName, zNewName) ){
451 return SQLITE_ERROR;
452 }
453 unlink(zOldName);
454 return SQLITE_OK;
455#endif
456#if OS_WIN
457 if( !MoveFile(zOldName, zNewName) ){
458 return SQLITE_ERROR;
459 }
460 return SQLITE_OK;
461#endif
462#if OS_MAC
463 /**** FIX ME ***/
464 return SQLITE_ERROR;
465#endif
466#if OS_OS2
467 if( link(zOldName, zNewName) ){
468 return SQLITE_ERROR;
469 }
470 unlink(zOldName);
471 return SQLITE_OK;
472#endif
473}
474#endif /* NOT USED */
475
476/*
477** Attempt to open a file for both reading and writing. If that
478** fails, try opening it read-only. If the file does not exist,
479** try to create it.
480**
481** On success, a handle for the open file is written to *id
482** and *pReadonly is set to 0 if the file was opened for reading and
483** writing or 1 if the file was opened read-only. The function returns
484** SQLITE_OK.
485**
486** On failure, the function returns SQLITE_CANTOPEN and leaves
487** *id and *pReadonly unchanged.
488*/
489int sqliteOsOpenReadWrite(
490 const char *zFilename,
491 OsFile *id,
492 int *pReadonly
493){
494#if OS_UNIX
495 int rc;
496 id->dirfd = -1;
497 id->fd = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY, 0644);
498 if( id->fd<0 ){
499#ifdef EISDIR
500 if( errno==EISDIR ){
501 return SQLITE_CANTOPEN;
502 }
503#endif
504 id->fd = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
505 if( id->fd<0 ){
506 return SQLITE_CANTOPEN;
507 }
508 *pReadonly = 1;
509 }else{
510 *pReadonly = 0;
511 }
512 sqliteOsEnterMutex();
513 rc = findLockInfo(id->fd, &id->pLock, &id->pOpen);
514 sqliteOsLeaveMutex();
515 if( rc ){
516 close(id->fd);
517 return SQLITE_NOMEM;
518 }
519 id->locked = 0;
520 TRACE3("OPEN %-3d %s\n", id->fd, zFilename);
521 OpenCounter(+1);
522 return SQLITE_OK;
523#endif
524#if OS_WIN
525 HANDLE h = CreateFile(zFilename,
526 GENERIC_READ | GENERIC_WRITE,
527 FILE_SHARE_READ | FILE_SHARE_WRITE,
528 NULL,
529 OPEN_ALWAYS,
530 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
531 NULL
532 );
533 if( h==INVALID_HANDLE_VALUE ){
534 h = CreateFile(zFilename,
535 GENERIC_READ,
536 FILE_SHARE_READ,
537 NULL,
538 OPEN_ALWAYS,
539 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
540 NULL
541 );
542 if( h==INVALID_HANDLE_VALUE ){
543 return SQLITE_CANTOPEN;
544 }
545 *pReadonly = 1;
546 }else{
547 *pReadonly = 0;
548 }
549 id->h = h;
550 id->locked = 0;
551 OpenCounter(+1);
552 return SQLITE_OK;
553#endif
554#if OS_MAC
555 FSSpec fsSpec;
556# ifdef _LARGE_FILE
557 HFSUniStr255 dfName;
558 FSRef fsRef;
559 if( __path2fss(zFilename, &fsSpec) != noErr ){
560 if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
561 return SQLITE_CANTOPEN;
562 }
563 if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr )
564 return SQLITE_CANTOPEN;
565 FSGetDataForkName(&dfName);
566 if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,
567 fsRdWrShPerm, &(id->refNum)) != noErr ){
568 if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,
569 fsRdWrPerm, &(id->refNum)) != noErr ){
570 if (FSOpenFork(&fsRef, dfName.length, dfName.unicode,
571 fsRdPerm, &(id->refNum)) != noErr )
572 return SQLITE_CANTOPEN;
573 else
574 *pReadonly = 1;
575 } else
576 *pReadonly = 0;
577 } else
578 *pReadonly = 0;
579# else
580 __path2fss(zFilename, &fsSpec);
581 if( !sqliteOsFileExists(zFilename) ){
582 if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
583 return SQLITE_CANTOPEN;
584 }
585 if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNum)) != noErr ){
586 if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrPerm, &(id->refNum)) != noErr ){
587 if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdPerm, &(id->refNum)) != noErr )
588 return SQLITE_CANTOPEN;
589 else
590 *pReadonly = 1;
591 } else
592 *pReadonly = 0;
593 } else
594 *pReadonly = 0;
595# endif
596 if( HOpenRF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNumRF)) != noErr){
597 id->refNumRF = -1;
598 }
599 id->locked = 0;
600 id->delOnClose = 0;
601 OpenCounter(+1);
602 return SQLITE_OK;
603#endif
604#if OS_OS2
605 id->fd = sopen(zFilename, O_RDWR|O_CREAT|O_BINARY, SH_DENYNO, 0600);
606 if( id->fd<0 ){
607 id->fd = sopen(zFilename, O_RDONLY|O_BINARY, SH_DENYNO);
608 if( id->fd<0 ){
609 return SQLITE_CANTOPEN;
610 }
611 *pReadonly = 1;
612 }else{
613 *pReadonly = 0;
614 }
615 id->locked = 0;
616 id->delOnClose = 0;
617 TRACE3("OPEN %-3d %s\n", id->fd, zFilename);
618 OpenCounter(+1);
619 return SQLITE_OK;
620#endif
621}
622
623
624/*
625** Attempt to open a new file for exclusive access by this process.
626** The file will be opened for both reading and writing. To avoid
627** a potential security problem, we do not allow the file to have
628** previously existed. Nor do we allow the file to be a symbolic
629** link.
630**
631** If delFlag is true, then make arrangements to automatically delete
632** the file when it is closed.
633**
634** On success, write the file handle into *id and return SQLITE_OK.
635**
636** On failure, return SQLITE_CANTOPEN.
637*/
638int sqliteOsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
639#if OS_UNIX
640 int rc;
641 if( access(zFilename, 0)==0 ){
642 return SQLITE_CANTOPEN;
643 }
644 id->dirfd = -1;
645 id->fd = open(zFilename,
646 O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY, 0600);
647 if( id->fd<0 ){
648 return SQLITE_CANTOPEN;
649 }
650 sqliteOsEnterMutex();
651 rc = findLockInfo(id->fd, &id->pLock, &id->pOpen);
652 sqliteOsLeaveMutex();
653 if( rc ){
654 close(id->fd);
655 unlink(zFilename);
656 return SQLITE_NOMEM;
657 }
658 id->locked = 0;
659 if( delFlag ){
660 unlink(zFilename);
661 }
662 TRACE3("OPEN-EX %-3d %s\n", id->fd, zFilename);
663 OpenCounter(+1);
664 return SQLITE_OK;
665#endif
666#if OS_WIN
667 HANDLE h;
668 int fileflags;
669 if( delFlag ){
670 fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS
671 | FILE_FLAG_DELETE_ON_CLOSE;
672 }else{
673 fileflags = FILE_FLAG_RANDOM_ACCESS;
674 }
675 h = CreateFile(zFilename,
676 GENERIC_READ | GENERIC_WRITE,
677 0,
678 NULL,
679 CREATE_ALWAYS,
680 fileflags,
681 NULL
682 );
683 if( h==INVALID_HANDLE_VALUE ){
684 return SQLITE_CANTOPEN;
685 }
686 id->h = h;
687 id->locked = 0;
688 OpenCounter(+1);
689 return SQLITE_OK;
690#endif
691#if OS_MAC
692 FSSpec fsSpec;
693# ifdef _LARGE_FILE
694 HFSUniStr255 dfName;
695 FSRef fsRef;
696 __path2fss(zFilename, &fsSpec);
697 if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
698 return SQLITE_CANTOPEN;
699 if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr )
700 return SQLITE_CANTOPEN;
701 FSGetDataForkName(&dfName);
702 if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,
703 fsRdWrPerm, &(id->refNum)) != noErr )
704 return SQLITE_CANTOPEN;
705# else
706 __path2fss(zFilename, &fsSpec);
707 if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
708 return SQLITE_CANTOPEN;
709 if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrPerm, &(id->refNum)) != noErr )
710 return SQLITE_CANTOPEN;
711# endif
712 id->refNumRF = -1;
713 id->locked = 0;
714 id->delOnClose = delFlag;
715 if (delFlag)
716 id->pathToDel = sqliteOsFullPathname(zFilename);
717 OpenCounter(+1);
718 return SQLITE_OK;
719#endif
720#if OS_OS2
721 if( access(zFilename, 0)==0 ){
722 return SQLITE_CANTOPEN;
723 }
724 id->fd = sopen(zFilename, O_RDWR|O_CREAT|O_EXCL|O_BINARY, SH_DENYNO, 0600);
725 if( id->fd<0 ){
726 return SQLITE_CANTOPEN;
727 }
728 id->locked = 0;
729 id->delOnClose = delFlag;
730 if (delFlag)
731 id->pathToDel = sqliteOsFullPathname(zFilename);
732 TRACE3("OPEN-EX %-3d %s\n", id->fd, zFilename);
733 OpenCounter(+1);
734 return SQLITE_OK;
735#endif
736}
737
738/*
739** Attempt to open a new file for read-only access.
740**
741** On success, write the file handle into *id and return SQLITE_OK.
742**
743** On failure, return SQLITE_CANTOPEN.
744*/
745int sqliteOsOpenReadOnly(const char *zFilename, OsFile *id){
746#if OS_UNIX
747 int rc;
748 id->dirfd = -1;
749 id->fd = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
750 if( id->fd<0 ){
751 return SQLITE_CANTOPEN;
752 }
753 sqliteOsEnterMutex();
754 rc = findLockInfo(id->fd, &id->pLock, &id->pOpen);
755 sqliteOsLeaveMutex();
756 if( rc ){
757 close(id->fd);
758 return SQLITE_NOMEM;
759 }
760 id->locked = 0;
761 TRACE3("OPEN-RO %-3d %s\n", id->fd, zFilename);
762 OpenCounter(+1);
763 return SQLITE_OK;
764#endif
765#if OS_WIN
766 HANDLE h = CreateFile(zFilename,
767 GENERIC_READ,
768 0,
769 NULL,
770 OPEN_EXISTING,
771 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
772 NULL
773 );
774 if( h==INVALID_HANDLE_VALUE ){
775 return SQLITE_CANTOPEN;
776 }
777 id->h = h;
778 id->locked = 0;
779 OpenCounter(+1);
780 return SQLITE_OK;
781#endif
782#if OS_MAC
783 FSSpec fsSpec;
784# ifdef _LARGE_FILE
785 HFSUniStr255 dfName;
786 FSRef fsRef;
787 if( __path2fss(zFilename, &fsSpec) != noErr )
788 return SQLITE_CANTOPEN;
789 if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr )
790 return SQLITE_CANTOPEN;
791 FSGetDataForkName(&dfName);
792 if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,
793 fsRdPerm, &(id->refNum)) != noErr )
794 return SQLITE_CANTOPEN;
795# else
796 __path2fss(zFilename, &fsSpec);
797 if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdPerm, &(id->refNum)) != noErr )
798 return SQLITE_CANTOPEN;
799# endif
800 if( HOpenRF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNumRF)) != noErr){
801 id->refNumRF = -1;
802 }
803 id->locked = 0;
804 id->delOnClose = 0;
805 OpenCounter(+1);
806 return SQLITE_OK;
807#endif
808#if OS_OS2
809 id->fd = sopen(zFilename, O_RDONLY|O_BINARY, SH_DENYNO, 0600);
810 if( id->fd<0 ){
811 return SQLITE_CANTOPEN;
812 }
813 id->locked = 0;
814 id->delOnClose = 0;
815 TRACE3("OPEN-RO %-3d %s\n", id->fd, zFilename);
816 OpenCounter(+1);
817 return SQLITE_OK;
818#endif
819}
820
821/*
822** Attempt to open a file descriptor for the directory that contains a
823** file. This file descriptor can be used to fsync() the directory
824** in order to make sure the creation of a new file is actually written
825** to disk.
826**
827** This routine is only meaningful for Unix. It is a no-op under
828** windows since windows does not support hard links.
829**
830** On success, a handle for a previously open file is at *id is
831** updated with the new directory file descriptor and SQLITE_OK is
832** returned.
833**
834** On failure, the function returns SQLITE_CANTOPEN and leaves
835** *id unchanged.
836*/
837int sqliteOsOpenDirectory(
838 const char *zDirname,
839 OsFile *id
840){
841#if OS_UNIX
842 if( id->fd<0 ){
843 /* Do not open the directory if the corresponding file is not already
844 ** open. */
845 return SQLITE_CANTOPEN;
846 }
847 assert( id->dirfd<0 );
848 id->dirfd = open(zDirname, O_RDONLY|O_BINARY, 0644);
849 if( id->dirfd<0 ){
850 return SQLITE_CANTOPEN;
851 }
852 TRACE3("OPENDIR %-3d %s\n", id->dirfd, zDirname);
853#endif
854 return SQLITE_OK;
855}
856
857/*
858** If the following global variable points to a string which is the
859** name of a directory, then that directory will be used to store
860** temporary files.
861*/
862const char *sqlite_temp_directory = 0;
863
864/*
865** Create a temporary file name in zBuf. zBuf must be big enough to
866** hold at least SQLITE_TEMPNAME_SIZE characters.
867*/
868int sqliteOsTempFileName(char *zBuf){
869#if OS_UNIX
870 static const char *azDirs[] = {
871 0,
872 "/var/tmp",
873 "/usr/tmp",
874 "/tmp",
875 ".",
876 };
877 static unsigned char zChars[] =
878 "abcdefghijklmnopqrstuvwxyz"
879 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
880 "0123456789";
881 int i, j;
882 struct stat buf;
883 const char *zDir = ".";
884 azDirs[0] = sqlite_temp_directory;
885 for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
886 if( azDirs[i]==0 ) continue;
887 if( stat(azDirs[i], &buf) ) continue;
888 if( !S_ISDIR(buf.st_mode) ) continue;
889 if( access(azDirs[i], 07) ) continue;
890 zDir = azDirs[i];
891 break;
892 }
893 do{
894 sprintf(zBuf, "%s/"TEMP_FILE_PREFIX, zDir);
895 j = strlen(zBuf);
896 sqliteRandomness(15, &zBuf[j]);
897 for(i=0; i<15; i++, j++){
898 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
899 }
900 zBuf[j] = 0;
901 }while( access(zBuf,0)==0 );
902#endif
903#if OS_WIN
904 static char zChars[] =
905 "abcdefghijklmnopqrstuvwxyz"
906 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
907 "0123456789";
908 int i, j;
909 const char *zDir;
910 char zTempPath[SQLITE_TEMPNAME_SIZE];
911 if( sqlite_temp_directory==0 ){
912 GetTempPath(SQLITE_TEMPNAME_SIZE-30, zTempPath);
913 for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
914 zTempPath[i] = 0;
915 zDir = zTempPath;
916 }else{
917 zDir = sqlite_temp_directory;
918 }
919 for(;;){
920 sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zDir);
921 j = strlen(zBuf);
922 sqliteRandomness(15, &zBuf[j]);
923 for(i=0; i<15; i++, j++){
924 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
925 }
926 zBuf[j] = 0;
927 if( !sqliteOsFileExists(zBuf) ) break;
928 }
929#endif
930#if OS_MAC
931 static char zChars[] =
932 "abcdefghijklmnopqrstuvwxyz"
933 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
934 "0123456789";
935 int i, j;
936 char *zDir;
937 char zTempPath[SQLITE_TEMPNAME_SIZE];
938 char zdirName[32];
939 CInfoPBRec infoRec;
940 Str31 dirName;
941 memset(&infoRec, 0, sizeof(infoRec));
942 memset(zTempPath, 0, SQLITE_TEMPNAME_SIZE);
943 if( sqlite_temp_directory!=0 ){
944 zDir = sqlite_temp_directory;
945 }else if( FindFolder(kOnSystemDisk, kTemporaryFolderType, kCreateFolder,
946 &(infoRec.dirInfo.ioVRefNum), &(infoRec.dirInfo.ioDrParID)) == noErr ){
947 infoRec.dirInfo.ioNamePtr = dirName;
948 do{
949 infoRec.dirInfo.ioFDirIndex = -1;
950 infoRec.dirInfo.ioDrDirID = infoRec.dirInfo.ioDrParID;
951 if( PBGetCatInfoSync(&infoRec) == noErr ){
952 CopyPascalStringToC(dirName, zdirName);
953 i = strlen(zdirName);
954 memmove(&(zTempPath[i+1]), zTempPath, strlen(zTempPath));
955 strcpy(zTempPath, zdirName);
956 zTempPath[i] = ':';
957 }else{
958 *zTempPath = 0;
959 break;
960 }
961 } while( infoRec.dirInfo.ioDrDirID != fsRtDirID );
962 zDir = zTempPath;
963 }
964 if( zDir[0]==0 ){
965 getcwd(zTempPath, SQLITE_TEMPNAME_SIZE-24);
966 zDir = zTempPath;
967 }
968 for(;;){
969 sprintf(zBuf, "%s"TEMP_FILE_PREFIX, zDir);
970 j = strlen(zBuf);
971 sqliteRandomness(15, &zBuf[j]);
972 for(i=0; i<15; i++, j++){
973 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
974 }
975 zBuf[j] = 0;
976 if( !sqliteOsFileExists(zBuf) ) break;
977 }
978#endif
979#if OS_OS2
980 static const char *azDirs[] = {
981 "/temp", /* supercede from TEMP env var */
982 "/temp",
983 "/tmp",
984 ".",
985 };
986 static char zChars[] =
987 "abcdefghijklmnopqrstuvwxyz"
988 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
989 "0123456789";
990 int i, j;
991 struct stat buf;
992 const char *zDir = ".";
993 azDirs[0] = getenv("TEMP");
994 zDir = ".";
995 for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
996 if( !azDirs[i] ) continue;
997 if( stat(azDirs[i], &buf) ) continue;
998 if( !S_ISDIR(buf.st_mode) ) continue;
999 if( access(azDirs[i], 07) ) continue;
1000 zDir = azDirs[i];
1001 break;
1002 }
1003 do{
1004 snprintf(zBuf, SQLITE_TEMPNAME_SIZE, "%s/"TEMP_FILE_PREFIX, zDir);
1005 j = strlen(zBuf);
1006 sqliteRandomness(15, &zBuf[j]);
1007 for(i=0; i<15; i++, j++){
1008 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
1009 }
1010 zBuf[j] = 0;
1011 }while( access(zBuf,0)==0 );
1012#endif
1013 return SQLITE_OK;
1014}
1015
1016/*
1017** Close a file.
1018*/
1019int sqliteOsClose(OsFile *id){
1020#if OS_UNIX
1021 sqliteOsUnlock(id);
1022 if( id->dirfd>=0 ) close(id->dirfd);
1023 id->dirfd = -1;
1024 sqliteOsEnterMutex();
1025 if( id->pOpen->nLock ){
1026 /* If there are outstanding locks, do not actually close the file just
1027 ** yet because that would clear those locks. Instead, add the file
1028 ** descriptor to pOpen->aPending. It will be automatically closed when
1029 ** the last lock is cleared.
1030 */
1031 int *aNew;
1032 struct openCnt *pOpen = id->pOpen;
1033 pOpen->nPending++;
1034 aNew = sqliteRealloc( pOpen->aPending, pOpen->nPending*sizeof(int) );
1035 if( aNew==0 ){
1036 /* If a malloc fails, just leak the file descriptor */
1037 }else{
1038 pOpen->aPending = aNew;
1039 pOpen->aPending[pOpen->nPending-1] = id->fd;
1040 }
1041 }else{
1042 /* There are no outstanding locks so we can close the file immediately */
1043 close(id->fd);
1044 }
1045 releaseLockInfo(id->pLock);
1046 releaseOpenCnt(id->pOpen);
1047 sqliteOsLeaveMutex();
1048 TRACE2("CLOSE %-3d\n", id->fd);
1049 OpenCounter(-1);
1050 return SQLITE_OK;
1051#endif
1052#if OS_WIN
1053 CloseHandle(id->h);
1054 OpenCounter(-1);
1055 return SQLITE_OK;
1056#endif
1057#if OS_MAC
1058 if( id->refNumRF!=-1 )
1059 FSClose(id->refNumRF);
1060# ifdef _LARGE_FILE
1061 FSCloseFork(id->refNum);
1062# else
1063 FSClose(id->refNum);
1064# endif
1065 if( id->delOnClose ){
1066 unlink(id->pathToDel);
1067 sqliteFree(id->pathToDel);
1068 }
1069 OpenCounter(-1);
1070 return SQLITE_OK;
1071#endif
1072#if OS_OS2
1073 close(id->fd);
1074 if( id->delOnClose ){
1075 unlink(id->pathToDel);
1076 sqliteFree(id->pathToDel);
1077 }
1078 TRACE2("CLOSE %-3d\n", id->fd);
1079 OpenCounter(-1);
1080 return SQLITE_OK;
1081#endif
1082}
1083
1084/*
1085** Read data from a file into a buffer. Return SQLITE_OK if all
1086** bytes were read successfully and SQLITE_IOERR if anything goes
1087** wrong.
1088*/
1089int sqliteOsRead(OsFile *id, void *pBuf, int amt){
1090#if OS_UNIX
1091 int got;
1092 SimulateIOError(SQLITE_IOERR);
1093 TIMER_START;
1094 got = read(id->fd, pBuf, amt);
1095 TIMER_END;
1096 TRACE4("READ %-3d %7d %d\n", id->fd, last_page, elapse);
1097 SEEK(0);
1098 /* if( got<0 ) got = 0; */
1099 if( got==amt ){
1100 return SQLITE_OK;
1101 }else{
1102 return SQLITE_IOERR;
1103 }
1104#endif
1105#if OS_WIN
1106 DWORD got;
1107 SimulateIOError(SQLITE_IOERR);
1108 TRACE2("READ %d\n", last_page);
1109 if( !ReadFile(id->h, pBuf, amt, &got, 0) ){
1110 got = 0;
1111 }
1112 if( got==(DWORD)amt ){
1113 return SQLITE_OK;
1114 }else{
1115 return SQLITE_IOERR;
1116 }
1117#endif
1118#if OS_MAC
1119 int got;
1120 SimulateIOError(SQLITE_IOERR);
1121 TRACE2("READ %d\n", last_page);
1122# ifdef _LARGE_FILE
1123 FSReadFork(id->refNum, fsAtMark, 0, (ByteCount)amt, pBuf, (ByteCount*)&got);
1124# else
1125 got = amt;
1126 FSRead(id->refNum, &got, pBuf);
1127# endif
1128 if( got==amt ){
1129 return SQLITE_OK;
1130 }else{
1131 return SQLITE_IOERR;
1132 }
1133#endif
1134#if OS_OS2
1135 int got;
1136 SimulateIOError(SQLITE_IOERR);
1137 TIMER_START;
1138 got = read(id->fd, pBuf, amt);
1139 TIMER_END;
1140 TRACE4("READ %-3d %7d %d\n", id->fd, last_page, elapse);
1141 SEEK(0);
1142 /* if( got<0 ) got = 0; */
1143 if( got==amt ){
1144 return SQLITE_OK;
1145 }else{
1146 return SQLITE_IOERR;
1147 }
1148#endif
1149}
1150
1151/*
1152** Write data from a buffer into a file. Return SQLITE_OK on success
1153** or some other error code on failure.
1154*/
1155int sqliteOsWrite(OsFile *id, const void *pBuf, int amt){
1156#if OS_UNIX
1157 int wrote = 0;
1158 SimulateIOError(SQLITE_IOERR);
1159 TIMER_START;
1160 while( amt>0 && (wrote = write(id->fd, pBuf, amt))>0 ){
1161 amt -= wrote;
1162 pBuf = &((char*)pBuf)[wrote];
1163 }
1164 TIMER_END;
1165 TRACE4("WRITE %-3d %7d %d\n", id->fd, last_page, elapse);
1166 SEEK(0);
1167 if( amt>0 ){
1168 return SQLITE_FULL;
1169 }
1170 return SQLITE_OK;
1171#endif
1172#if OS_WIN
1173 int rc;
1174 DWORD wrote;
1175 SimulateIOError(SQLITE_IOERR);
1176 TRACE2("WRITE %d\n", last_page);
1177 while( amt>0 && (rc = WriteFile(id->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){
1178 amt -= wrote;
1179 pBuf = &((char*)pBuf)[wrote];
1180 }
1181 if( !rc || amt>(int)wrote ){
1182 return SQLITE_FULL;
1183 }
1184 return SQLITE_OK;
1185#endif
1186#if OS_MAC
1187 OSErr oserr;
1188 int wrote = 0;
1189 SimulateIOError(SQLITE_IOERR);
1190 TRACE2("WRITE %d\n", last_page);
1191 while( amt>0 ){
1192# ifdef _LARGE_FILE
1193 oserr = FSWriteFork(id->refNum, fsAtMark, 0,
1194 (ByteCount)amt, pBuf, (ByteCount*)&wrote);
1195# else
1196 wrote = amt;
1197 oserr = FSWrite(id->refNum, &wrote, pBuf);
1198# endif
1199 if( wrote == 0 || oserr != noErr)
1200 break;
1201 amt -= wrote;
1202 pBuf = &((char*)pBuf)[wrote];
1203 }
1204 if( oserr != noErr || amt>wrote ){
1205 return SQLITE_FULL;
1206 }
1207 return SQLITE_OK;
1208#endif
1209#if OS_OS2
1210 int wrote = 0;
1211 SimulateIOError(SQLITE_IOERR);
1212 TIMER_START;
1213 wrote = write(id->fd, pBuf, amt);
1214 TIMER_END;
1215 if ( wrote<0 ){
1216 return SQLITE_IOERR;
1217 }
1218 TRACE4("WRITE %-3d %7d %d\n", id->fd, last_page, elapse);
1219 SEEK(0);
1220 if( (wrote - amt)>0 ){
1221 return SQLITE_FULL;
1222 }
1223 return SQLITE_OK;
1224#endif
1225}
1226
1227/*
1228** Move the read/write pointer in a file.
1229*/
1230int sqliteOsSeek(OsFile *id, off_t offset){
1231 SEEK(offset/1024 + 1);
1232#if OS_UNIX
1233 lseek(id->fd, offset, SEEK_SET);
1234 return SQLITE_OK;
1235#endif
1236#if OS_WIN
1237 {
1238 LONG upperBits = offset>>32;
1239 LONG lowerBits = offset & 0xffffffff;
1240 DWORD rc;
1241 rc = SetFilePointer(id->h, lowerBits, &upperBits, FILE_BEGIN);
1242 /* TRACE3("SEEK rc=0x%x upper=0x%x\n", rc, upperBits); */
1243 }
1244 return SQLITE_OK;
1245#endif
1246#if OS_MAC
1247 {
1248 off_t curSize;
1249 if( sqliteOsFileSize(id, &curSize) != SQLITE_OK ){
1250 return SQLITE_IOERR;
1251 }
1252 if( offset >= curSize ){
1253 if( sqliteOsTruncate(id, offset+1) != SQLITE_OK ){
1254 return SQLITE_IOERR;
1255 }
1256 }
1257# ifdef _LARGE_FILE
1258 if( FSSetForkPosition(id->refNum, fsFromStart, offset) != noErr ){
1259# else
1260 if( SetFPos(id->refNum, fsFromStart, offset) != noErr ){
1261# endif
1262 return SQLITE_IOERR;
1263 }else{
1264 return SQLITE_OK;
1265 }
1266 }
1267#endif
1268#if OS_OS2
1269 {
1270 long pos;
1271 pos = lseek(id->fd, offset, SEEK_SET);
1272 if ( pos<0 )
1273 return SQLITE_IOERR;
1274 return SQLITE_OK;
1275 }
1276#endif
1277}
1278
1279#ifdef SQLITE_NOSYNC
1280# define fsync(X) 0
1281#endif
1282
1283/*
1284** Make sure all writes to a particular file are committed to disk.
1285**
1286** Under Unix, also make sure that the directory entry for the file
1287** has been created by fsync-ing the directory that contains the file.
1288** If we do not do this and we encounter a power failure, the directory
1289** entry for the journal might not exist after we reboot. The next
1290** SQLite to access the file will not know that the journal exists (because
1291** the directory entry for the journal was never created) and the transaction
1292** will not roll back - possibly leading to database corruption.
1293*/
1294int sqliteOsSync(OsFile *id){
1295#if OS_UNIX
1296 SimulateIOError(SQLITE_IOERR);
1297 TRACE2("SYNC %-3d\n", id->fd);
1298 if( fsync(id->fd) ){
1299 return SQLITE_IOERR;
1300 }else{
1301 if( id->dirfd>=0 ){
1302 TRACE2("DIRSYNC %-3d\n", id->dirfd);
1303 fsync(id->dirfd);
1304 close(id->dirfd); /* Only need to sync once, so close the directory */
1305 id->dirfd = -1; /* when we are done. */
1306 }
1307 return SQLITE_OK;
1308 }
1309#endif
1310#if OS_WIN
1311 if( FlushFileBuffers(id->h) ){
1312 return SQLITE_OK;
1313 }else{
1314 return SQLITE_IOERR;
1315 }
1316#endif
1317#if OS_MAC
1318# ifdef _LARGE_FILE
1319 if( FSFlushFork(id->refNum) != noErr ){
1320# else
1321 ParamBlockRec params;
1322 memset(&params, 0, sizeof(ParamBlockRec));
1323 params.ioParam.ioRefNum = id->refNum;
1324 if( PBFlushFileSync(&params) != noErr ){
1325# endif
1326 return SQLITE_IOERR;
1327 }else{
1328 return SQLITE_OK;
1329 }
1330#endif
1331#if OS_OS2
1332 SimulateIOError(SQLITE_IOERR);
1333 TRACE2("SYNC %-3d\n", id->fd);
1334 if( fsync(id->fd) ){
1335 return SQLITE_IOERR;
1336 }else{
1337 return SQLITE_OK;
1338 }
1339#endif
1340}
1341
1342/*
1343** Truncate an open file to a specified size
1344*/
1345int sqliteOsTruncate(OsFile *id, off_t nByte){
1346 SimulateIOError(SQLITE_IOERR);
1347#if OS_UNIX
1348 return ftruncate(id->fd, nByte)==0 ? SQLITE_OK : SQLITE_IOERR;
1349#endif
1350#if OS_WIN
1351 {
1352 LONG upperBits = nByte>>32;
1353 SetFilePointer(id->h, nByte, &upperBits, FILE_BEGIN);
1354 SetEndOfFile(id->h);
1355 }
1356 return SQLITE_OK;
1357#endif
1358#if OS_MAC
1359# ifdef _LARGE_FILE
1360 if( FSSetForkSize(id->refNum, fsFromStart, nByte) != noErr){
1361# else
1362 if( SetEOF(id->refNum, nByte) != noErr ){
1363# endif
1364 return SQLITE_IOERR;
1365 }else{
1366 return SQLITE_OK;
1367 }
1368#endif
1369#if OS_OS2
1370 return ftruncate(id->fd, nByte)==0 ? SQLITE_OK : SQLITE_IOERR;
1371#endif
1372}
1373
1374/*
1375** Determine the current size of a file in bytes
1376*/
1377int sqliteOsFileSize(OsFile *id, off_t *pSize){
1378#if OS_UNIX
1379 struct stat buf;
1380 SimulateIOError(SQLITE_IOERR);
1381 if( fstat(id->fd, &buf)!=0 ){
1382 return SQLITE_IOERR;
1383 }
1384 *pSize = buf.st_size;
1385 return SQLITE_OK;
1386#endif
1387#if OS_WIN
1388 DWORD upperBits, lowerBits;
1389 SimulateIOError(SQLITE_IOERR);
1390 lowerBits = GetFileSize(id->h, &upperBits);
1391 *pSize = (((off_t)upperBits)<<32) + lowerBits;
1392 return SQLITE_OK;
1393#endif
1394#if OS_MAC
1395# ifdef _LARGE_FILE
1396 if( FSGetForkSize(id->refNum, pSize) != noErr){
1397# else
1398 if( GetEOF(id->refNum, pSize) != noErr ){
1399# endif
1400 return SQLITE_IOERR;
1401 }else{
1402 return SQLITE_OK;
1403 }
1404#endif
1405#if OS_OS2
1406 struct stat buf;
1407 SimulateIOError(SQLITE_IOERR);
1408 if( fstat(id->fd, &buf)!=0 ){
1409 return SQLITE_IOERR;
1410 }
1411 *pSize = buf.st_size;
1412 return SQLITE_OK;
1413#endif
1414}
1415
1416#if OS_WIN
1417/*
1418** Return true (non-zero) if we are running under WinNT, Win2K or WinXP.
1419** Return false (zero) for Win95, Win98, or WinME.
1420**
1421** Here is an interesting observation: Win95, Win98, and WinME lack
1422** the LockFileEx() API. But we can still statically link against that
1423** API as long as we don't call it win running Win95/98/ME. A call to
1424** this routine is used to determine if the host is Win95/98/ME or
1425** WinNT/2K/XP so that we will know whether or not we can safely call
1426** the LockFileEx() API.
1427*/
1428int isNT(void){
1429 static int osType = 0; /* 0=unknown 1=win95 2=winNT */
1430 if( osType==0 ){
1431 OSVERSIONINFO sInfo;
1432 sInfo.dwOSVersionInfoSize = sizeof(sInfo);
1433 GetVersionEx(&sInfo);
1434 osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
1435 }
1436 return osType==2;
1437}
1438#endif
1439
1440/*
1441** Windows file locking notes: [similar issues apply to MacOS]
1442**
1443** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because
1444** those functions are not available. So we use only LockFile() and
1445** UnlockFile().
1446**
1447** LockFile() prevents not just writing but also reading by other processes.
1448** (This is a design error on the part of Windows, but there is nothing
1449** we can do about that.) So the region used for locking is at the
1450** end of the file where it is unlikely to ever interfere with an
1451** actual read attempt.
1452**
1453** A database read lock is obtained by locking a single randomly-chosen
1454** byte out of a specific range of bytes. The lock byte is obtained at
1455** random so two separate readers can probably access the file at the
1456** same time, unless they are unlucky and choose the same lock byte.
1457** A database write lock is obtained by locking all bytes in the range.
1458** There can only be one writer.
1459**
1460** A lock is obtained on the first byte of the lock range before acquiring
1461** either a read lock or a write lock. This prevents two processes from
1462** attempting to get a lock at a same time. The semantics of
1463** sqliteOsReadLock() require that if there is already a write lock, that
1464** lock is converted into a read lock atomically. The lock on the first
1465** byte allows us to drop the old write lock and get the read lock without
1466** another process jumping into the middle and messing us up. The same
1467** argument applies to sqliteOsWriteLock().
1468**
1469** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available,
1470** which means we can use reader/writer locks. When reader writer locks
1471** are used, the lock is placed on the same range of bytes that is used
1472** for probabilistic locking in Win95/98/ME. Hence, the locking scheme
1473** will support two or more Win95 readers or two or more WinNT readers.
1474** But a single Win95 reader will lock out all WinNT readers and a single
1475** WinNT reader will lock out all other Win95 readers.
1476**
1477** Note: On MacOS we use the resource fork for locking.
1478**
1479** The following #defines specify the range of bytes used for locking.
1480** N_LOCKBYTE is the number of bytes available for doing the locking.
1481** The first byte used to hold the lock while the lock is changing does
1482** not count toward this number. FIRST_LOCKBYTE is the address of
1483** the first byte in the range of bytes used for locking.
1484*/
1485#if OS_OS2
1486# define N_LOCKBYTE 0x7fffffffL
1487# define FIRST_LOCKBYTE 0L
1488#else
1489# define N_LOCKBYTE 10239
1490# if OS_MAC
1491# define FIRST_LOCKBYTE (0x000fffff - N_LOCKBYTE)
1492# else
1493# define FIRST_LOCKBYTE (0xffffffff - N_LOCKBYTE)
1494# endif
1495#endif
1496
1497/*
1498** Change the status of the lock on the file "id" to be a readlock.
1499** If the file was write locked, then this reduces the lock to a read.
1500** If the file was read locked, then this acquires a new read lock.
1501**
1502** Return SQLITE_OK on success and SQLITE_BUSY on failure. If this
1503** library was compiled with large file support (LFS) but LFS is not
1504** available on the host, then an SQLITE_NOLFS is returned.
1505*/
1506int sqliteOsReadLock(OsFile *id){
1507#if OS_UNIX
1508 int rc;
1509 sqliteOsEnterMutex();
1510 if( id->pLock->cnt>0 ){
1511 if( !id->locked ){
1512 id->pLock->cnt++;
1513 id->locked = 1;
1514 id->pOpen->nLock++;
1515 }
1516 rc = SQLITE_OK;
1517 }else if( id->locked || id->pLock->cnt==0 ){
1518 struct flock lock;
1519 int s;
1520 lock.l_type = F_RDLCK;
1521 lock.l_whence = SEEK_SET;
1522 lock.l_start = lock.l_len = 0L;
1523 s = fcntl(id->fd, F_SETLK, &lock);
1524 if( s!=0 ){
1525 rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
1526 }else{
1527 rc = SQLITE_OK;
1528 if( !id->locked ){
1529 id->pOpen->nLock++;
1530 id->locked = 1;
1531 }
1532 id->pLock->cnt = 1;
1533 }
1534 }else{
1535 rc = SQLITE_BUSY;
1536 }
1537 sqliteOsLeaveMutex();
1538 return rc;
1539#endif
1540#if OS_WIN
1541 int rc;
1542 if( id->locked>0 ){
1543 rc = SQLITE_OK;
1544 }else{
1545 int lk;
1546 int res;
1547 int cnt = 100;
1548 sqliteRandomness(sizeof(lk), &lk);
1549 lk = (lk & 0x7fffffff)%N_LOCKBYTE + 1;
1550 while( cnt-->0 && (res = LockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0))==0 ){
1551 Sleep(1);
1552 }
1553 if( res ){
1554 UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
1555 if( isNT() ){
1556 OVERLAPPED ovlp;
1557 ovlp.Offset = FIRST_LOCKBYTE+1;
1558 ovlp.OffsetHigh = 0;
1559 ovlp.hEvent = 0;
1560 res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY,
1561 0, N_LOCKBYTE, 0, &ovlp);
1562 }else{
1563 res = LockFile(id->h, FIRST_LOCKBYTE+lk, 0, 1, 0);
1564 }
1565 UnlockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0);
1566 }
1567 if( res ){
1568 id->locked = lk;
1569 rc = SQLITE_OK;
1570 }else{
1571 rc = SQLITE_BUSY;
1572 }
1573 }
1574 return rc;
1575#endif
1576#if OS_MAC
1577 int rc;
1578 if( id->locked>0 || id->refNumRF == -1 ){
1579 rc = SQLITE_OK;
1580 }else{
1581 int lk;
1582 OSErr res;
1583 int cnt = 5;
1584 ParamBlockRec params;
1585 sqliteRandomness(sizeof(lk), &lk);
1586 lk = (lk & 0x7fffffff)%N_LOCKBYTE + 1;
1587 memset(&params, 0, sizeof(params));
1588 params.ioParam.ioRefNum = id->refNumRF;
1589 params.ioParam.ioPosMode = fsFromStart;
1590 params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
1591 params.ioParam.ioReqCount = 1;
1592 while( cnt-->0 && (res = PBLockRangeSync(&params))!=noErr ){
1593 UInt32 finalTicks;
1594 Delay(1, &finalTicks); /* 1/60 sec */
1595 }
1596 if( res == noErr ){
1597 params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1;
1598 params.ioParam.ioReqCount = N_LOCKBYTE;
1599 PBUnlockRangeSync(&params);
1600 params.ioParam.ioPosOffset = FIRST_LOCKBYTE+lk;
1601 params.ioParam.ioReqCount = 1;
1602 res = PBLockRangeSync(&params);
1603 params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
1604 params.ioParam.ioReqCount = 1;
1605 PBUnlockRangeSync(&params);
1606 }
1607 if( res == noErr ){
1608 id->locked = lk;
1609 rc = SQLITE_OK;
1610 }else{
1611 rc = SQLITE_BUSY;
1612 }
1613 }
1614 return rc;
1615#endif
1616#if OS_OS2
1617 int rc;
1618 if( id->locked>0 ){
1619 rc = SQLITE_OK;
1620 }else{
1621 APIRET s;
1622 FILELOCK ulock = {0L, 0L};
1623 FILELOCK lock = {FIRST_LOCKBYTE, N_LOCKBYTE};
1624 long readlock = 1L;
1625 if( id->locked<0 ){
1626 ulock.lOffset = lock.lOffset;
1627 ulock.lRange = lock.lRange;
1628 readlock += 2L; /* atomic unlock/lock */
1629 }
1630 s = DosSetFileLocks(id->fd, &ulock, &lock, 0L, readlock);
1631 if( s!=NO_ERROR ){
1632 rc = SQLITE_BUSY;
1633 }else{
1634 rc = SQLITE_OK;
1635 id->locked = 1;
1636 }
1637 }
1638 return rc;
1639#endif
1640}
1641
1642/*
1643** Change the lock status to be an exclusive or write lock. Return
1644** SQLITE_OK on success and SQLITE_BUSY on a failure. If this
1645** library was compiled with large file support (LFS) but LFS is not
1646** available on the host, then an SQLITE_NOLFS is returned.
1647*/
1648int sqliteOsWriteLock(OsFile *id){
1649#if OS_UNIX
1650 int rc;
1651 sqliteOsEnterMutex();
1652 if( id->pLock->cnt==0 || (id->pLock->cnt==1 && id->locked==1) ){
1653 struct flock lock;
1654 int s;
1655 lock.l_type = F_WRLCK;
1656 lock.l_whence = SEEK_SET;
1657 lock.l_start = lock.l_len = 0L;
1658 s = fcntl(id->fd, F_SETLK, &lock);
1659 if( s!=0 ){
1660 rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
1661 }else{
1662 rc = SQLITE_OK;
1663 if( !id->locked ){
1664 id->pOpen->nLock++;
1665 id->locked = 1;
1666 }
1667 id->pLock->cnt = -1;
1668 }
1669 }else{
1670 rc = SQLITE_BUSY;
1671 }
1672 sqliteOsLeaveMutex();
1673 return rc;
1674#endif
1675#if OS_WIN
1676 int rc;
1677 if( id->locked<0 ){
1678 rc = SQLITE_OK;
1679 }else{
1680 int res;
1681 int cnt = 100;
1682 while( cnt-->0 && (res = LockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0))==0 ){
1683 Sleep(1);
1684 }
1685 if( res ){
1686 if( id->locked>0 ){
1687 if( isNT() ){
1688 UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
1689 }else{
1690 res = UnlockFile(id->h, FIRST_LOCKBYTE + id->locked, 0, 1, 0);
1691 }
1692 }
1693 if( res ){
1694 res = LockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
1695 }else{
1696 res = 0;
1697 }
1698 UnlockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0);
1699 }
1700 if( res ){
1701 id->locked = -1;
1702 rc = SQLITE_OK;
1703 }else{
1704 rc = SQLITE_BUSY;
1705 }
1706 }
1707 return rc;
1708#endif
1709#if OS_MAC
1710 int rc;
1711 if( id->locked<0 || id->refNumRF == -1 ){
1712 rc = SQLITE_OK;
1713 }else{
1714 OSErr res;
1715 int cnt = 5;
1716 ParamBlockRec params;
1717 memset(&params, 0, sizeof(params));
1718 params.ioParam.ioRefNum = id->refNumRF;
1719 params.ioParam.ioPosMode = fsFromStart;
1720 params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
1721 params.ioParam.ioReqCount = 1;
1722 while( cnt-->0 && (res = PBLockRangeSync(&params))!=noErr ){
1723 UInt32 finalTicks;
1724 Delay(1, &finalTicks); /* 1/60 sec */
1725 }
1726 if( res == noErr ){
1727 params.ioParam.ioPosOffset = FIRST_LOCKBYTE + id->locked;
1728 params.ioParam.ioReqCount = 1;
1729 if( id->locked==0
1730 || PBUnlockRangeSync(&params)==noErr ){
1731 params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1;
1732 params.ioParam.ioReqCount = N_LOCKBYTE;
1733 res = PBLockRangeSync(&params);
1734 }else{
1735 res = afpRangeNotLocked;
1736 }
1737 params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
1738 params.ioParam.ioReqCount = 1;
1739 PBUnlockRangeSync(&params);
1740 }
1741 if( res == noErr ){
1742 id->locked = -1;
1743 rc = SQLITE_OK;
1744 }else{
1745 rc = SQLITE_BUSY;
1746 }
1747 }
1748 return rc;
1749#endif
1750#if OS_OS2
1751 int rc;
1752 if( id->locked<0 ){
1753 rc = SQLITE_OK;
1754 }else{
1755 APIRET s;
1756 FILELOCK ulock = {0L, 0L};
1757 FILELOCK lock = {FIRST_LOCKBYTE, N_LOCKBYTE};
1758 long writelock = 0L;
1759 if( id->locked>0 ){
1760 ulock.lOffset = lock.lOffset;
1761 ulock.lRange = lock.lRange;
1762 writelock += 2L; /* atomic unlock/lock */
1763 }
1764 s = DosSetFileLocks(id->fd, &ulock, &lock, 0L, writelock);
1765 if( s!=NO_ERROR ){
1766 rc = SQLITE_BUSY;
1767 }else{
1768 rc = SQLITE_OK;
1769 id->locked = -1;
1770 }
1771 }
1772 return rc;
1773#endif
1774}
1775
1776/*
1777** Unlock the given file descriptor. If the file descriptor was
1778** not previously locked, then this routine is a no-op. If this
1779** library was compiled with large file support (LFS) but LFS is not
1780** available on the host, then an SQLITE_NOLFS is returned.
1781*/
1782int sqliteOsUnlock(OsFile *id){
1783#if OS_UNIX
1784 int rc;
1785 if( !id->locked ) return SQLITE_OK;
1786 sqliteOsEnterMutex();
1787 assert( id->pLock->cnt!=0 );
1788 if( id->pLock->cnt>1 ){
1789 id->pLock->cnt--;
1790 rc = SQLITE_OK;
1791 }else{
1792 struct flock lock;
1793 int s;
1794 lock.l_type = F_UNLCK;
1795 lock.l_whence = SEEK_SET;
1796 lock.l_start = lock.l_len = 0L;
1797 s = fcntl(id->fd, F_SETLK, &lock);
1798 if( s!=0 ){
1799 rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
1800 }else{
1801 rc = SQLITE_OK;
1802 id->pLock->cnt = 0;
1803 }
1804 }
1805 if( rc==SQLITE_OK ){
1806 /* Decrement the count of locks against this same file. When the
1807 ** count reaches zero, close any other file descriptors whose close
1808 ** was deferred because of outstanding locks.
1809 */
1810 struct openCnt *pOpen = id->pOpen;
1811 pOpen->nLock--;
1812 assert( pOpen->nLock>=0 );
1813 if( pOpen->nLock==0 && pOpen->nPending>0 ){
1814 int i;
1815 for(i=0; i<pOpen->nPending; i++){
1816 close(pOpen->aPending[i]);
1817 }
1818 sqliteFree(pOpen->aPending);
1819 pOpen->nPending = 0;
1820 pOpen->aPending = 0;
1821 }
1822 }
1823 sqliteOsLeaveMutex();
1824 id->locked = 0;
1825 return rc;
1826#endif
1827#if OS_WIN
1828 int rc;
1829 if( id->locked==0 ){
1830 rc = SQLITE_OK;
1831 }else if( isNT() || id->locked<0 ){
1832 UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
1833 rc = SQLITE_OK;
1834 id->locked = 0;
1835 }else{
1836 UnlockFile(id->h, FIRST_LOCKBYTE+id->locked, 0, 1, 0);
1837 rc = SQLITE_OK;
1838 id->locked = 0;
1839 }
1840 return rc;
1841#endif
1842#if OS_MAC
1843 int rc;
1844 ParamBlockRec params;
1845 memset(&params, 0, sizeof(params));
1846 params.ioParam.ioRefNum = id->refNumRF;
1847 params.ioParam.ioPosMode = fsFromStart;
1848 if( id->locked==0 || id->refNumRF == -1 ){
1849 rc = SQLITE_OK;
1850 }else if( id->locked<0 ){
1851 params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1;
1852 params.ioParam.ioReqCount = N_LOCKBYTE;
1853 PBUnlockRangeSync(&params);
1854 rc = SQLITE_OK;
1855 id->locked = 0;
1856 }else{
1857 params.ioParam.ioPosOffset = FIRST_LOCKBYTE+id->locked;
1858 params.ioParam.ioReqCount = 1;
1859 PBUnlockRangeSync(&params);
1860 rc = SQLITE_OK;
1861 id->locked = 0;
1862 }
1863 return rc;
1864#endif
1865#if OS_OS2
1866 int rc;
1867 if( id->locked==0 ){
1868 rc = SQLITE_OK;
1869 }else{
1870 APIRET s;
1871 FILELOCK ulock = {FIRST_LOCKBYTE, N_LOCKBYTE};
1872 FILELOCK lock = {0L, 0L};
1873 s = DosSetFileLocks(id->fd, &ulock, &lock, 0L, 0L);
1874 if( s!=NO_ERROR ){
1875 rc = SQLITE_BUSY;
1876 }else{
1877 rc = SQLITE_OK;
1878 id->locked = 0;
1879 }
1880 }
1881 return rc;
1882#endif
1883}
1884
1885/*
1886** Get information to seed the random number generator. The seed
1887** is written into the buffer zBuf[256]. The calling function must
1888** supply a sufficiently large buffer.
1889*/
1890int sqliteOsRandomSeed(char *zBuf){
1891 /* We have to initialize zBuf to prevent valgrind from reporting
1892 ** errors. The reports issued by valgrind are incorrect - we would
1893 ** prefer that the randomness be increased by making use of the
1894 ** uninitialized space in zBuf - but valgrind errors tend to worry
1895 ** some users. Rather than argue, it seems easier just to initialize
1896 ** the whole array and silence valgrind, even if that means less randomness
1897 ** in the random seed.
1898 **
1899 ** When testing, initializing zBuf[] to zero is all we do. That means
1900 ** that we always use the same random number sequence.* This makes the
1901 ** tests repeatable.
1902 */
1903 memset(zBuf, 0, 256);
1904#if OS_UNIX && !defined(SQLITE_TEST)
1905 {
1906 int pid;
1907 time((time_t*)zBuf);
1908 pid = getpid();
1909 memcpy(&zBuf[sizeof(time_t)], &pid, sizeof(pid));
1910 }
1911#endif
1912#if OS_WIN && !defined(SQLITE_TEST)
1913 GetSystemTime((LPSYSTEMTIME)zBuf);
1914#endif
1915#if OS_MAC
1916 {
1917 int pid;
1918 Microseconds((UnsignedWide*)zBuf);
1919 pid = getpid();
1920 memcpy(&zBuf[sizeof(UnsignedWide)], &pid, sizeof(pid));
1921 }
1922#endif
1923#if OS_OS2 && !defined(SQLITE_TEST)
1924 {
1925 int pid;
1926 time((time_t*)zBuf);
1927 pid = getpid();
1928 memcpy(&zBuf[sizeof(time_t)], &pid, sizeof(pid));
1929 }
1930#endif
1931 return SQLITE_OK;
1932}
1933
1934/*
1935** Sleep for a little while. Return the amount of time slept.
1936*/
1937int sqliteOsSleep(int ms){
1938#if OS_UNIX
1939#if defined(HAVE_USLEEP) && HAVE_USLEEP
1940 usleep(ms*1000);
1941 return ms;
1942#else
1943 sleep((ms+999)/1000);
1944 return 1000*((ms+999)/1000);
1945#endif
1946#endif
1947#if OS_WIN
1948 Sleep(ms);
1949 return ms;
1950#endif
1951#if OS_MAC
1952 UInt32 finalTicks;
1953 UInt32 ticks = (((UInt32)ms+16)*3)/50; /* 1/60 sec per tick */
1954 Delay(ticks, &finalTicks);
1955 return (int)((ticks*50)/3);
1956#endif
1957#if OS_OS2
1958 APIRET rc;
1959 rc = DosSleep(ms);
1960 return ms;
1961#endif
1962}
1963
1964/*
1965** Static variables used for thread synchronization
1966*/
1967static int inMutex = 0;
1968#ifdef SQLITE_UNIX_THREADS
1969 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
1970#endif
1971#ifdef SQLITE_W32_THREADS
1972 static CRITICAL_SECTION cs;
1973#endif
1974#ifdef SQLITE_MACOS_MULTITASKING
1975 static MPCriticalRegionID criticalRegion;
1976#endif
1977#ifdef SQLITE_OS2_THREADS
1978 static _smutex mutex = 0;
1979#endif
1980
1981/*
1982** The following pair of routine implement mutual exclusion for
1983** multi-threaded processes. Only a single thread is allowed to
1984** executed code that is surrounded by EnterMutex() and LeaveMutex().
1985**
1986** SQLite uses only a single Mutex. There is not much critical
1987** code and what little there is executes quickly and without blocking.
1988*/
1989void sqliteOsEnterMutex(){
1990#ifdef SQLITE_UNIX_THREADS
1991 pthread_mutex_lock(&mutex);
1992#endif
1993#ifdef SQLITE_W32_THREADS
1994 static int isInit = 0;
1995 while( !isInit ){
1996 static long lock = 0;
1997 if( InterlockedIncrement(&lock)==1 ){
1998 InitializeCriticalSection(&cs);
1999 isInit = 1;
2000 }else{
2001 Sleep(1);
2002 }
2003 }
2004 EnterCriticalSection(&cs);
2005#endif
2006#ifdef SQLITE_MACOS_MULTITASKING
2007 static volatile int notInit = 1;
2008 if( notInit ){
2009 if( notInit == 2 ) /* as close as you can get to thread safe init */
2010 MPYield();
2011 else{
2012 notInit = 2;
2013 MPCreateCriticalRegion(&criticalRegion);
2014 notInit = 0;
2015 }
2016 }
2017 MPEnterCriticalRegion(criticalRegion, kDurationForever);
2018#endif
2019#ifdef SQLITE_OS2_THREADS
2020 _smutex_request(&mutex);
2021#endif
2022 assert( !inMutex );
2023 inMutex = 1;
2024}
2025void sqliteOsLeaveMutex(){
2026 assert( inMutex );
2027 inMutex = 0;
2028#ifdef SQLITE_UNIX_THREADS
2029 pthread_mutex_unlock(&mutex);
2030#endif
2031#ifdef SQLITE_W32_THREADS
2032 LeaveCriticalSection(&cs);
2033#endif
2034#ifdef SQLITE_MACOS_MULTITASKING
2035 MPExitCriticalRegion(criticalRegion);
2036#endif
2037#ifdef SQLITE_OS2_THREADS
2038 _smutex_release(&mutex);
2039#endif
2040}
2041
2042/*
2043** Turn a relative pathname into a full pathname. Return a pointer
2044** to the full pathname stored in space obtained from sqliteMalloc().
2045** The calling function is responsible for freeing this space once it
2046** is no longer needed.
2047*/
2048char *sqliteOsFullPathname(const char *zRelative){
2049#if OS_UNIX
2050 char *zFull = 0;
2051 if( zRelative[0]=='/' ){
2052 sqliteSetString(&zFull, zRelative, (char*)0);
2053 }else{
2054 char zBuf[5000];
2055 zBuf[0] = 0;
2056 sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), "/", zRelative,
2057 (char*)0);
2058 }
2059 return zFull;
2060#endif
2061#if OS_WIN
2062 char *zNotUsed;
2063 char *zFull;
2064 int nByte;
2065 nByte = GetFullPathName(zRelative, 0, 0, &zNotUsed) + 1;
2066 zFull = sqliteMalloc( nByte );
2067 if( zFull==0 ) return 0;
2068 GetFullPathName(zRelative, nByte, zFull, &zNotUsed);
2069 return zFull;
2070#endif
2071#if OS_MAC
2072 char *zFull = 0;
2073 if( zRelative[0]==':' ){
2074 char zBuf[_MAX_PATH+1];
2075 sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), &(zRelative[1]),
2076 (char*)0);
2077 }else{
2078 if( strchr(zRelative, ':') ){
2079 sqliteSetString(&zFull, zRelative, (char*)0);
2080 }else{
2081 char zBuf[_MAX_PATH+1];
2082 sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), zRelative, (char*)0);
2083 }
2084 }
2085 return zFull;
2086#endif
2087#if OS_OS2
2088 char *zFull = 0;
2089 char zPath[260]; /* max OS/2 path length, incl drive */
2090 if( !_abspath(zPath, zRelative, sizeof(zPath)) ){
2091 sqliteSetString(&zFull, zPath, 0);
2092 }else{
2093 char zBuf[260];
2094 snprintf(zPath, sizeof(zPath), "%s/%s",
2095 getcwd(zBuf, sizeof(zBuf)), zRelative);
2096 sqliteSetString(&zFull, zPath, 0);
2097 }
2098 return zFull;
2099#endif
2100}
2101
2102/*
2103** The following variable, if set to a non-zero value, becomes the result
2104** returned from sqliteOsCurrentTime(). This is used for testing.
2105*/
2106#ifdef SQLITE_TEST
2107int sqlite_current_time = 0;
2108#endif
2109
2110/*
2111** Find the current time (in Universal Coordinated Time). Write the
2112** current time and date as a Julian Day number into *prNow and
2113** return 0. Return 1 if the time and date cannot be found.
2114*/
2115int sqliteOsCurrentTime(double *prNow){
2116#if OS_UNIX
2117 time_t t;
2118 time(&t);
2119 *prNow = t/86400.0 + 2440587.5;
2120#endif
2121#if OS_WIN
2122 FILETIME ft;
2123 /* FILETIME structure is a 64-bit value representing the number of
2124 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
2125 */
2126 double now;
2127 GetSystemTimeAsFileTime( &ft );
2128 now = ((double)ft.dwHighDateTime) * 4294967296.0;
2129 *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
2130 return 0;
2131#endif
2132#if OS_OS2
2133 time_t t;
2134 time(&t);
2135 *prNow = t/86400.0 + 2440587.5;
2136#endif
2137#ifdef SQLITE_TEST
2138 if( sqlite_current_time ){
2139 *prNow = sqlite_current_time/86400.0 + 2440587.5;
2140 }
2141#endif
2142 return 0;
2143}
Note: See TracBrowser for help on using the repository browser.