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