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

Last change on this file since 205 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.