monotone

monotone Mtn Source Tree

Root/sqlite/os_os2.c

1/*
2** 2006 Feb 14
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 OS/2.
14*/
15
16#if (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 3) && defined(OS2_HIGH_MEMORY)
17/* os2safe.h has to be included before os2.h, needed for high mem */
18#include <os2safe.h>
19#endif
20
21#include "sqliteInt.h"
22#include "os.h"
23
24#if OS_OS2
25
26/*
27** Macros used to determine whether or not to use threads.
28*/
29#if defined(THREADSAFE) && THREADSAFE
30# define SQLITE_OS2_THREADS 1
31#endif
32
33/*
34** Include code that is common to all os_*.c files
35*/
36#include "os_common.h"
37
38/*
39** The os2File structure is subclass of OsFile specific for the OS/2
40** protability layer.
41*/
42typedef struct os2File os2File;
43struct os2File {
44 IoMethod const *pMethod; /* Always the first entry */
45 HFILE h; /* Handle for accessing the file */
46 int delOnClose; /* True if file is to be deleted on close */
47 char* pathToDel; /* Name of file to delete on close */
48 unsigned char locktype; /* Type of lock currently held on this file */
49};
50
51/*
52** Do not include any of the File I/O interface procedures if the
53** SQLITE_OMIT_DISKIO macro is defined (indicating that there database
54** will be in-memory only)
55*/
56#ifndef SQLITE_OMIT_DISKIO
57
58/*
59** Delete the named file
60*/
61int sqlite3Os2Delete( const char *zFilename ){
62 APIRET rc = NO_ERROR;
63
64 rc = DosDelete( (PSZ)zFilename );
65 OSTRACE2( "DELETE \"%s\"\n", zFilename );
66 return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
67}
68
69/*
70** Return TRUE if the named file exists.
71*/
72int sqlite3Os2FileExists( const char *zFilename ){
73 FILESTATUS3 fsts3ConfigInfo;
74 memset(&fsts3ConfigInfo, 0, sizeof(fsts3ConfigInfo));
75 return DosQueryPathInfo( (PSZ)zFilename, FIL_STANDARD,
76 &fsts3ConfigInfo, sizeof(FILESTATUS3) ) == NO_ERROR;
77}
78
79/* Forward declaration */
80int allocateOs2File( os2File *pInit, OsFile **pld );
81
82/*
83** Attempt to open a file for both reading and writing. If that
84** fails, try opening it read-only. If the file does not exist,
85** try to create it.
86**
87** On success, a handle for the open file is written to *id
88** and *pReadonly is set to 0 if the file was opened for reading and
89** writing or 1 if the file was opened read-only. The function returns
90** SQLITE_OK.
91**
92** On failure, the function returns SQLITE_CANTOPEN and leaves
93** *id and *pReadonly unchanged.
94*/
95int sqlite3Os2OpenReadWrite(
96 const char *zFilename,
97 OsFile **pld,
98 int *pReadonly
99){
100 os2File f;
101 HFILE hf;
102 ULONG ulAction;
103 APIRET rc = NO_ERROR;
104
105 assert( *pld == 0 );
106 rc = DosOpen( (PSZ)zFilename, &hf, &ulAction, 0L,
107 FILE_ARCHIVED | FILE_NORMAL,
108 OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
109 OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_RANDOM |
110 OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE, (PEAOP2)NULL );
111 if( rc != NO_ERROR ){
112 rc = DosOpen( (PSZ)zFilename, &hf, &ulAction, 0L,
113 FILE_ARCHIVED | FILE_NORMAL,
114 OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
115 OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_RANDOM |
116 OPEN_SHARE_DENYWRITE | OPEN_ACCESS_READONLY, (PEAOP2)NULL );
117 if( rc != NO_ERROR ){
118 return SQLITE_CANTOPEN;
119 }
120 *pReadonly = 1;
121 }
122 else{
123 *pReadonly = 0;
124 }
125 f.h = hf;
126 f.locktype = NO_LOCK;
127 f.delOnClose = 0;
128 f.pathToDel = NULL;
129 OpenCounter(+1);
130 OSTRACE3( "OPEN R/W %d \"%s\"\n", hf, zFilename );
131 return allocateOs2File( &f, pld );
132}
133
134
135/*
136** Attempt to open a new file for exclusive access by this process.
137** The file will be opened for both reading and writing. To avoid
138** a potential security problem, we do not allow the file to have
139** previously existed. Nor do we allow the file to be a symbolic
140** link.
141**
142** If delFlag is true, then make arrangements to automatically delete
143** the file when it is closed.
144**
145** On success, write the file handle into *id and return SQLITE_OK.
146**
147** On failure, return SQLITE_CANTOPEN.
148*/
149int sqlite3Os2OpenExclusive( const char *zFilename, OsFile **pld, int delFlag ){
150 os2File f;
151 HFILE hf;
152 ULONG ulAction;
153 APIRET rc = NO_ERROR;
154
155 assert( *pld == 0 );
156 rc = DosOpen( (PSZ)zFilename, &hf, &ulAction, 0L, FILE_NORMAL,
157 OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS,
158 OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_RANDOM |
159 OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_READWRITE, (PEAOP2)NULL );
160 if( rc != NO_ERROR ){
161 return SQLITE_CANTOPEN;
162 }
163
164 f.h = hf;
165 f.locktype = NO_LOCK;
166 f.delOnClose = delFlag ? 1 : 0;
167 f.pathToDel = delFlag ? sqlite3OsFullPathname( zFilename ) : NULL;
168 OpenCounter( +1 );
169 if( delFlag ) DosForceDelete( sqlite3OsFullPathname( zFilename ) );
170 OSTRACE3( "OPEN EX %d \"%s\"\n", hf, sqlite3OsFullPathname ( zFilename ) );
171 return allocateOs2File( &f, pld );
172}
173
174/*
175** Attempt to open a new file for read-only access.
176**
177** On success, write the file handle into *id and return SQLITE_OK.
178**
179** On failure, return SQLITE_CANTOPEN.
180*/
181int sqlite3Os2OpenReadOnly( const char *zFilename, OsFile **pld ){
182 os2File f;
183 HFILE hf;
184 ULONG ulAction;
185 APIRET rc = NO_ERROR;
186
187 assert( *pld == 0 );
188 rc = DosOpen( (PSZ)zFilename, &hf, &ulAction, 0L,
189 FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS,
190 OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_RANDOM |
191 OPEN_SHARE_DENYWRITE | OPEN_ACCESS_READONLY, (PEAOP2)NULL );
192 if( rc != NO_ERROR ){
193 return SQLITE_CANTOPEN;
194 }
195 f.h = hf;
196 f.locktype = NO_LOCK;
197 f.delOnClose = 0;
198 f.pathToDel = NULL;
199 OpenCounter( +1 );
200 OSTRACE3( "OPEN RO %d \"%s\"\n", hf, zFilename );
201 return allocateOs2File( &f, pld );
202}
203
204/*
205** Attempt to open a file descriptor for the directory that contains a
206** file. This file descriptor can be used to fsync() the directory
207** in order to make sure the creation of a new file is actually written
208** to disk.
209**
210** This routine is only meaningful for Unix. It is a no-op under
211** OS/2 since OS/2 does not support hard links.
212**
213** On success, a handle for a previously open file is at *id is
214** updated with the new directory file descriptor and SQLITE_OK is
215** returned.
216**
217** On failure, the function returns SQLITE_CANTOPEN and leaves
218** *id unchanged.
219*/
220int os2OpenDirectory(
221 OsFile *id,
222 const char *zDirname
223){
224 return SQLITE_OK;
225}
226
227/*
228** Create a temporary file name in zBuf. zBuf must be big enough to
229** hold at least SQLITE_TEMPNAME_SIZE characters.
230*/
231int sqlite3Os2TempFileName( char *zBuf ){
232 static const unsigned char zChars[] =
233 "abcdefghijklmnopqrstuvwxyz"
234 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
235 "0123456789";
236 int i, j;
237 PSZ zTempPath = 0;
238 if( DosScanEnv( "TEMP", &zTempPath ) ){
239 if( DosScanEnv( "TMP", &zTempPath ) ){
240 if( DosScanEnv( "TMPDIR", &zTempPath ) ){
241 ULONG ulDriveNum = 0, ulDriveMap = 0;
242 DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap );
243 sprintf( zTempPath, "%c:", (char)( 'A' + ulDriveNum - 1 ) );
244 }
245 }
246 }
247 for(;;){
248 sprintf( zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath );
249 j = strlen( zBuf );
250 sqlite3Randomness( 15, &zBuf[j] );
251 for( i = 0; i < 15; i++, j++ ){
252 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
253 }
254 zBuf[j] = 0;
255 if( !sqlite3OsFileExists( zBuf ) ) break;
256 }
257 OSTRACE2( "TEMP FILENAME: %s\n", zBuf );
258 return SQLITE_OK;
259}
260
261/*
262** Close a file.
263*/
264int os2Close( OsFile **pld ){
265 os2File *pFile;
266 APIRET rc = NO_ERROR;
267 if( pld && (pFile = (os2File*)*pld) != 0 ){
268 OSTRACE2( "CLOSE %d\n", pFile->h );
269 rc = DosClose( pFile->h );
270 pFile->locktype = NO_LOCK;
271 if( pFile->delOnClose != 0 ){
272 rc = DosForceDelete( pFile->pathToDel );
273 }
274 *pld = 0;
275 OpenCounter( -1 );
276 }
277
278 return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
279}
280
281/*
282** Read data from a file into a buffer. Return SQLITE_OK if all
283** bytes were read successfully and SQLITE_IOERR if anything goes
284** wrong.
285*/
286int os2Read( OsFile *id, void *pBuf, int amt ){
287 ULONG got;
288 assert( id!=0 );
289 SimulateIOError( return SQLITE_IOERR );
290 OSTRACE3( "READ %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype );
291 DosRead( ((os2File*)id)->h, pBuf, amt, &got );
292 if (got == (ULONG)amt)
293 return SQLITE_OK;
294 else if (got < 0)
295 return SQLITE_IOERR_READ;
296 else {
297 memset(&((char*)pBuf)[got], 0, amt-got);
298 return SQLITE_IOERR_SHORT_READ;
299 }
300}
301
302/*
303** Write data from a buffer into a file. Return SQLITE_OK on success
304** or some other error code on failure.
305*/
306int os2Write( OsFile *id, const void *pBuf, int amt ){
307 APIRET rc = NO_ERROR;
308 ULONG wrote;
309 assert( id!=0 );
310 SimulateIOError( return SQLITE_IOERR );
311 SimulateDiskfullError( return SQLITE_FULL );
312 OSTRACE3( "WRITE %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype );
313 while( amt > 0 &&
314 (rc = DosWrite( ((os2File*)id)->h, (PVOID)pBuf, amt, &wrote )) && wrote > 0 ){
315 amt -= wrote;
316 pBuf = &((char*)pBuf)[wrote];
317 }
318
319 return ( rc != NO_ERROR || amt > (int)wrote ) ? SQLITE_FULL : SQLITE_OK;
320}
321
322/*
323** Move the read/write pointer in a file.
324*/
325int os2Seek( OsFile *id, i64 offset ){
326 APIRET rc = NO_ERROR;
327 ULONG filePointer = 0L;
328 assert( id!=0 );
329 rc = DosSetFilePtr( ((os2File*)id)->h, offset, FILE_BEGIN, &filePointer );
330 OSTRACE3( "SEEK %d %lld\n", ((os2File*)id)->h, offset );
331 return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
332}
333
334/*
335** Make sure all writes to a particular file are committed to disk.
336*/
337int os2Sync( OsFile *id, int dataOnly ){
338 assert( id!=0 );
339 OSTRACE3( "SYNC %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype );
340 return DosResetBuffer( ((os2File*)id)->h ) == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
341}
342
343/*
344** Sync the directory zDirname. This is a no-op on operating systems other
345** than UNIX.
346*/
347int sqlite3Os2SyncDirectory( const char *zDirname ){
348 SimulateIOError( return SQLITE_IOERR );
349 return SQLITE_OK;
350}
351
352/*
353** Truncate an open file to a specified size
354*/
355int os2Truncate( OsFile *id, i64 nByte ){
356 APIRET rc = NO_ERROR;
357 ULONG upperBits = nByte>>32;
358 assert( id!=0 );
359 OSTRACE3( "TRUNCATE %d %lld\n", ((os2File*)id)->h, nByte );
360 SimulateIOError( return SQLITE_IOERR );
361 rc = DosSetFilePtr( ((os2File*)id)->h, nByte, FILE_BEGIN, &upperBits );
362 if( rc != NO_ERROR ){
363 return SQLITE_IOERR;
364 }
365 rc = DosSetFilePtr( ((os2File*)id)->h, 0L, FILE_END, &upperBits );
366 return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
367}
368
369/*
370** Determine the current size of a file in bytes
371*/
372int os2FileSize( OsFile *id, i64 *pSize ){
373 APIRET rc = NO_ERROR;
374 FILESTATUS3 fsts3FileInfo;
375 memset(&fsts3FileInfo, 0, sizeof(fsts3FileInfo));
376 assert( id!=0 );
377 SimulateIOError( return SQLITE_IOERR );
378 rc = DosQueryFileInfo( ((os2File*)id)->h, FIL_STANDARD, &fsts3FileInfo, sizeof(FILESTATUS3) );
379 if( rc == NO_ERROR ){
380 *pSize = fsts3FileInfo.cbFile;
381 return SQLITE_OK;
382 }
383 else{
384 return SQLITE_IOERR;
385 }
386}
387
388/*
389** Acquire a reader lock.
390*/
391static int getReadLock( os2File *id ){
392 FILELOCK LockArea,
393 UnlockArea;
394 memset(&LockArea, 0, sizeof(LockArea));
395 memset(&UnlockArea, 0, sizeof(UnlockArea));
396 LockArea.lOffset = SHARED_FIRST;
397 LockArea.lRange = SHARED_SIZE;
398 UnlockArea.lOffset = 0L;
399 UnlockArea.lRange = 0L;
400 return DosSetFileLocks( id->h, &UnlockArea, &LockArea, 2000L, 1L );
401}
402
403/*
404** Undo a readlock
405*/
406static int unlockReadLock( os2File *id ){
407 FILELOCK LockArea,
408 UnlockArea;
409 memset(&LockArea, 0, sizeof(LockArea));
410 memset(&UnlockArea, 0, sizeof(UnlockArea));
411 LockArea.lOffset = 0L;
412 LockArea.lRange = 0L;
413 UnlockArea.lOffset = SHARED_FIRST;
414 UnlockArea.lRange = SHARED_SIZE;
415 return DosSetFileLocks( id->h, &UnlockArea, &LockArea, 2000L, 1L );
416}
417
418#ifndef SQLITE_OMIT_PAGER_PRAGMAS
419/*
420** Check that a given pathname is a directory and is writable
421**
422*/
423int sqlite3Os2IsDirWritable( char *zDirname ){
424 FILESTATUS3 fsts3ConfigInfo;
425 APIRET rc = NO_ERROR;
426 memset(&fsts3ConfigInfo, 0, sizeof(fsts3ConfigInfo));
427 if( zDirname==0 ) return 0;
428 if( strlen(zDirname)>CCHMAXPATH ) return 0;
429 rc = DosQueryPathInfo( (PSZ)zDirname, FIL_STANDARD, &fsts3ConfigInfo, sizeof(FILESTATUS3) );
430 if( rc != NO_ERROR ) return 0;
431 if( (fsts3ConfigInfo.attrFile & FILE_DIRECTORY) != FILE_DIRECTORY ) return 0;
432
433 return 1;
434}
435#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
436
437/*
438** Lock the file with the lock specified by parameter locktype - one
439** of the following:
440**
441** (1) SHARED_LOCK
442** (2) RESERVED_LOCK
443** (3) PENDING_LOCK
444** (4) EXCLUSIVE_LOCK
445**
446** Sometimes when requesting one lock state, additional lock states
447** are inserted in between. The locking might fail on one of the later
448** transitions leaving the lock state different from what it started but
449** still short of its goal. The following chart shows the allowed
450** transitions and the inserted intermediate states:
451**
452** UNLOCKED -> SHARED
453** SHARED -> RESERVED
454** SHARED -> (PENDING) -> EXCLUSIVE
455** RESERVED -> (PENDING) -> EXCLUSIVE
456** PENDING -> EXCLUSIVE
457**
458** This routine will only increase a lock. The os2Unlock() routine
459** erases all locks at once and returns us immediately to locking level 0.
460** It is not possible to lower the locking level one step at a time. You
461** must go straight to locking level 0.
462*/
463int os2Lock( OsFile *id, int locktype ){
464 APIRET rc = SQLITE_OK; /* Return code from subroutines */
465 APIRET res = NO_ERROR; /* Result of an OS/2 lock call */
466 int newLocktype; /* Set id->locktype to this value before exiting */
467 int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
468 FILELOCK LockArea,
469 UnlockArea;
470 os2File *pFile = (os2File*)id;
471 memset(&LockArea, 0, sizeof(LockArea));
472 memset(&UnlockArea, 0, sizeof(UnlockArea));
473 assert( pFile!=0 );
474 OSTRACE4( "LOCK %d %d was %d\n", pFile->h, locktype, pFile->locktype );
475
476 /* If there is already a lock of this type or more restrictive on the
477 ** OsFile, do nothing. Don't use the end_lock: exit path, as
478 ** sqlite3OsEnterMutex() hasn't been called yet.
479 */
480 if( pFile->locktype>=locktype ){
481 return SQLITE_OK;
482 }
483
484 /* Make sure the locking sequence is correct
485 */
486 assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
487 assert( locktype!=PENDING_LOCK );
488 assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
489
490 /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
491 ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
492 ** the PENDING_LOCK byte is temporary.
493 */
494 newLocktype = pFile->locktype;
495 if( pFile->locktype==NO_LOCK
496 || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK)
497 ){
498 int cnt = 3;
499
500 LockArea.lOffset = PENDING_BYTE;
501 LockArea.lRange = 1L;
502 UnlockArea.lOffset = 0L;
503 UnlockArea.lRange = 0L;
504
505 while( cnt-->0 && (res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L) )!=NO_ERROR ){
506 /* Try 3 times to get the pending lock. The pending lock might be
507 ** held by another reader process who will release it momentarily.
508 */
509 OSTRACE2( "could not get a PENDING lock. cnt=%d\n", cnt );
510 DosSleep(1);
511 }
512 gotPendingLock = res;
513 }
514
515 /* Acquire a shared lock
516 */
517 if( locktype==SHARED_LOCK && res ){
518 assert( pFile->locktype==NO_LOCK );
519 res = getReadLock(pFile);
520 if( res == NO_ERROR ){
521 newLocktype = SHARED_LOCK;
522 }
523 }
524
525 /* Acquire a RESERVED lock
526 */
527 if( locktype==RESERVED_LOCK && res ){
528 assert( pFile->locktype==SHARED_LOCK );
529 LockArea.lOffset = RESERVED_BYTE;
530 LockArea.lRange = 1L;
531 UnlockArea.lOffset = 0L;
532 UnlockArea.lRange = 0L;
533 res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );
534 if( res == NO_ERROR ){
535 newLocktype = RESERVED_LOCK;
536 }
537 }
538
539 /* Acquire a PENDING lock
540 */
541 if( locktype==EXCLUSIVE_LOCK && res ){
542 newLocktype = PENDING_LOCK;
543 gotPendingLock = 0;
544 }
545
546 /* Acquire an EXCLUSIVE lock
547 */
548 if( locktype==EXCLUSIVE_LOCK && res ){
549 assert( pFile->locktype>=SHARED_LOCK );
550 res = unlockReadLock(pFile);
551 OSTRACE2( "unreadlock = %d\n", res );
552 LockArea.lOffset = SHARED_FIRST;
553 LockArea.lRange = SHARED_SIZE;
554 UnlockArea.lOffset = 0L;
555 UnlockArea.lRange = 0L;
556 res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );
557 if( res == NO_ERROR ){
558 newLocktype = EXCLUSIVE_LOCK;
559 }else{
560 OSTRACE2( "error-code = %d\n", res );
561 }
562 }
563
564 /* If we are holding a PENDING lock that ought to be released, then
565 ** release it now.
566 */
567 if( gotPendingLock && locktype==SHARED_LOCK ){
568 LockArea.lOffset = 0L;
569 LockArea.lRange = 0L;
570 UnlockArea.lOffset = PENDING_BYTE;
571 UnlockArea.lRange = 1L;
572 DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );
573 }
574
575 /* Update the state of the lock has held in the file descriptor then
576 ** return the appropriate result code.
577 */
578 if( res == NO_ERROR ){
579 rc = SQLITE_OK;
580 }else{
581 OSTRACE4( "LOCK FAILED %d trying for %d but got %d\n", pFile->h,
582 locktype, newLocktype );
583 rc = SQLITE_BUSY;
584 }
585 pFile->locktype = newLocktype;
586 return rc;
587}
588
589/*
590** This routine checks if there is a RESERVED lock held on the specified
591** file by this or any other process. If such a lock is held, return
592** non-zero, otherwise zero.
593*/
594int os2CheckReservedLock( OsFile *id ){
595 APIRET rc = NO_ERROR;
596 os2File *pFile = (os2File*)id;
597 assert( pFile!=0 );
598 if( pFile->locktype>=RESERVED_LOCK ){
599 rc = 1;
600 OSTRACE3( "TEST WR-LOCK %d %d (local)\n", pFile->h, rc );
601 }else{
602 FILELOCK LockArea,
603 UnlockArea;
604 memset(&LockArea, 0, sizeof(LockArea));
605 memset(&UnlockArea, 0, sizeof(UnlockArea));
606 LockArea.lOffset = RESERVED_BYTE;
607 LockArea.lRange = 1L;
608 UnlockArea.lOffset = 0L;
609 UnlockArea.lRange = 0L;
610 rc = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );
611 if( rc == NO_ERROR ){
612 LockArea.lOffset = 0L;
613 LockArea.lRange = 0L;
614 UnlockArea.lOffset = RESERVED_BYTE;
615 UnlockArea.lRange = 1L;
616 rc = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );
617 }
618 OSTRACE3( "TEST WR-LOCK %d %d (remote)\n", pFile->h, rc );
619 }
620 return rc;
621}
622
623/*
624** Lower the locking level on file descriptor id to locktype. locktype
625** must be either NO_LOCK or SHARED_LOCK.
626**
627** If the locking level of the file descriptor is already at or below
628** the requested locking level, this routine is a no-op.
629**
630** It is not possible for this routine to fail if the second argument
631** is NO_LOCK. If the second argument is SHARED_LOCK then this routine
632** might return SQLITE_IOERR;
633*/
634int os2Unlock( OsFile *id, int locktype ){
635 int type;
636 APIRET rc = SQLITE_OK;
637 os2File *pFile = (os2File*)id;
638 FILELOCK LockArea,
639 UnlockArea;
640 memset(&LockArea, 0, sizeof(LockArea));
641 memset(&UnlockArea, 0, sizeof(UnlockArea));
642 assert( pFile!=0 );
643 assert( locktype<=SHARED_LOCK );
644 OSTRACE4( "UNLOCK %d to %d was %d\n", pFile->h, locktype, pFile->locktype );
645 type = pFile->locktype;
646 if( type>=EXCLUSIVE_LOCK ){
647 LockArea.lOffset = 0L;
648 LockArea.lRange = 0L;
649 UnlockArea.lOffset = SHARED_FIRST;
650 UnlockArea.lRange = SHARED_SIZE;
651 DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );
652 if( locktype==SHARED_LOCK && getReadLock(pFile) != NO_ERROR ){
653 /* This should never happen. We should always be able to
654 ** reacquire the read lock */
655 rc = SQLITE_IOERR;
656 }
657 }
658 if( type>=RESERVED_LOCK ){
659 LockArea.lOffset = 0L;
660 LockArea.lRange = 0L;
661 UnlockArea.lOffset = RESERVED_BYTE;
662 UnlockArea.lRange = 1L;
663 DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );
664 }
665 if( locktype==NO_LOCK && type>=SHARED_LOCK ){
666 unlockReadLock(pFile);
667 }
668 if( type>=PENDING_LOCK ){
669 LockArea.lOffset = 0L;
670 LockArea.lRange = 0L;
671 UnlockArea.lOffset = PENDING_BYTE;
672 UnlockArea.lRange = 1L;
673 DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );
674 }
675 pFile->locktype = locktype;
676 return rc;
677}
678
679/*
680** Turn a relative pathname into a full pathname. Return a pointer
681** to the full pathname stored in space obtained from sqliteMalloc().
682** The calling function is responsible for freeing this space once it
683** is no longer needed.
684*/
685char *sqlite3Os2FullPathname( const char *zRelative ){
686 char *zFull = 0;
687 if( strchr(zRelative, ':') ){
688 sqlite3SetString( &zFull, zRelative, (char*)0 );
689 }else{
690 char zBuff[SQLITE_TEMPNAME_SIZE - 2] = {0};
691 char zDrive[1] = {0};
692 ULONG cbzFullLen = SQLITE_TEMPNAME_SIZE;
693 ULONG ulDriveNum = 0;
694 ULONG ulDriveMap = 0;
695 DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap );
696 DosQueryCurrentDir( 0L, zBuff, &cbzFullLen );
697 zFull = sqliteMalloc( cbzFullLen );
698 sprintf( zDrive, "%c", (char)('A' + ulDriveNum - 1) );
699 sqlite3SetString( &zFull, zDrive, ":\\", zBuff, "\\", zRelative, (char*)0 );
700 }
701 return zFull;
702}
703
704/*
705** The fullSync option is meaningless on os2, or correct me if I'm wrong. This is a no-op.
706** From os_unix.c: Change the value of the fullsync flag in the given file descriptor.
707** From os_unix.c: ((unixFile*)id)->fullSync = v;
708*/
709static void os2SetFullSync( OsFile *id, int v ){
710 return;
711}
712
713/*
714** Return the underlying file handle for an OsFile
715*/
716static int os2FileHandle( OsFile *id ){
717 return (int)((os2File*)id)->h;
718}
719
720/*
721** Return an integer that indices the type of lock currently held
722** by this handle. (Used for testing and analysis only.)
723*/
724static int os2LockState( OsFile *id ){
725 return ((os2File*)id)->locktype;
726}
727
728/*
729** Return the sector size in bytes of the underlying block device for
730** the specified file. This is almost always 512 bytes, but may be
731** larger for some devices.
732**
733** SQLite code assumes this function cannot fail. It also assumes that
734** if two files are created in the same file-system directory (i.e.
735** a database and it's journal file) that the sector size will be the
736** same for both.
737*/
738static int os2SectorSize(OsFile *id){
739 return SQLITE_DEFAULT_SECTOR_SIZE;
740}
741
742/*
743** This vector defines all the methods that can operate on an OsFile
744** for os2.
745*/
746static const IoMethod sqlite3Os2IoMethod = {
747 os2Close,
748 os2OpenDirectory,
749 os2Read,
750 os2Write,
751 os2Seek,
752 os2Truncate,
753 os2Sync,
754 os2SetFullSync,
755 os2FileHandle,
756 os2FileSize,
757 os2Lock,
758 os2Unlock,
759 os2LockState,
760 os2CheckReservedLock,
761 os2SectorSize,
762};
763
764/*
765** Allocate memory for an OsFile. Initialize the new OsFile
766** to the value given in pInit and return a pointer to the new
767** OsFile. If we run out of memory, close the file and return NULL.
768*/
769int allocateOs2File( os2File *pInit, OsFile **pld ){
770 os2File *pNew;
771 pNew = sqliteMalloc( sizeof(*pNew) );
772 if( pNew==0 ){
773 DosClose( pInit->h );
774 *pld = 0;
775 return SQLITE_NOMEM;
776 }else{
777 *pNew = *pInit;
778 pNew->pMethod = &sqlite3Os2IoMethod;
779 pNew->locktype = NO_LOCK;
780 *pld = (OsFile*)pNew;
781 OpenCounter(+1);
782 return SQLITE_OK;
783 }
784}
785
786#endif /* SQLITE_OMIT_DISKIO */
787/***************************************************************************
788** Everything above deals with file I/O. Everything that follows deals
789** with other miscellanous aspects of the operating system interface
790****************************************************************************/
791
792#ifndef SQLITE_OMIT_LOAD_EXTENSION
793/*
794** Interfaces for opening a shared library, finding entry points
795** within the shared library, and closing the shared library.
796*/
797void *sqlite3Os2Dlopen(const char *zFilename){
798 UCHAR loadErr[256];
799 HMODULE hmod;
800 APIRET rc;
801 rc = DosLoadModule(loadErr, sizeof(loadErr), zFilename, &hmod);
802 if (rc != NO_ERROR) return 0;
803 return (void*)hmod;
804}
805void *sqlite3Os2Dlsym(void *pHandle, const char *zSymbol){
806 PFN pfn;
807 APIRET rc;
808 rc = DosQueryProcAddr((HMODULE)pHandle, 0L, zSymbol, &pfn);
809 if (rc != NO_ERROR) {
810 /* if the symbol itself was not found, search again for the same
811 * symbol with an extra underscore, that might be needed depending
812 * on the calling convention */
813 char _zSymbol[256] = "_";
814 strncat(_zSymbol, zSymbol, 255);
815 rc = DosQueryProcAddr((HMODULE)pHandle, 0L, _zSymbol, &pfn);
816 }
817 if (rc != NO_ERROR) return 0;
818 return pfn;
819}
820int sqlite3Os2Dlclose(void *pHandle){
821 return DosFreeModule((HMODULE)pHandle);
822}
823#endif /* SQLITE_OMIT_LOAD_EXTENSION */
824
825
826/*
827** Get information to seed the random number generator. The seed
828** is written into the buffer zBuf[256]. The calling function must
829** supply a sufficiently large buffer.
830*/
831int sqlite3Os2RandomSeed( char *zBuf ){
832 /* We have to initialize zBuf to prevent valgrind from reporting
833 ** errors. The reports issued by valgrind are incorrect - we would
834 ** prefer that the randomness be increased by making use of the
835 ** uninitialized space in zBuf - but valgrind errors tend to worry
836 ** some users. Rather than argue, it seems easier just to initialize
837 ** the whole array and silence valgrind, even if that means less randomness
838 ** in the random seed.
839 **
840 ** When testing, initializing zBuf[] to zero is all we do. That means
841 ** that we always use the same random number sequence. This makes the
842 ** tests repeatable.
843 */
844 memset( zBuf, 0, 256 );
845 DosGetDateTime( (PDATETIME)zBuf );
846 return SQLITE_OK;
847}
848
849/*
850** Sleep for a little while. Return the amount of time slept.
851*/
852int sqlite3Os2Sleep( int ms ){
853 DosSleep( ms );
854 return ms;
855}
856
857/*
858** Static variables used for thread synchronization
859*/
860static int inMutex = 0;
861#ifdef SQLITE_OS2_THREADS
862static ULONG mutexOwner;
863#endif
864
865/*
866** The following pair of routines implement mutual exclusion for
867** multi-threaded processes. Only a single thread is allowed to
868** executed code that is surrounded by EnterMutex() and LeaveMutex().
869**
870** SQLite uses only a single Mutex. There is not much critical
871** code and what little there is executes quickly and without blocking.
872*/
873void sqlite3Os2EnterMutex(){
874 PTIB ptib;
875#ifdef SQLITE_OS2_THREADS
876 DosEnterCritSec();
877 DosGetInfoBlocks( &ptib, NULL );
878 mutexOwner = ptib->tib_ptib2->tib2_ultid;
879#endif
880 assert( !inMutex );
881 inMutex = 1;
882}
883void sqlite3Os2LeaveMutex(){
884 PTIB ptib;
885 assert( inMutex );
886 inMutex = 0;
887#ifdef SQLITE_OS2_THREADS
888 DosGetInfoBlocks( &ptib, NULL );
889 assert( mutexOwner == ptib->tib_ptib2->tib2_ultid );
890 DosExitCritSec();
891#endif
892}
893
894/*
895** Return TRUE if the mutex is currently held.
896**
897** If the thisThreadOnly parameter is true, return true if and only if the
898** calling thread holds the mutex. If the parameter is false, return
899** true if any thread holds the mutex.
900*/
901int sqlite3Os2InMutex( int thisThreadOnly ){
902#ifdef SQLITE_OS2_THREADS
903 PTIB ptib;
904 DosGetInfoBlocks( &ptib, NULL );
905 return inMutex>0 && (thisThreadOnly==0 || mutexOwner==ptib->tib_ptib2->tib2_ultid);
906#else
907 return inMutex>0;
908#endif
909}
910
911/*
912** The following variable, if set to a non-zero value, becomes the result
913** returned from sqlite3OsCurrentTime(). This is used for testing.
914*/
915#ifdef SQLITE_TEST
916int sqlite3_current_time = 0;
917#endif
918
919/*
920** Find the current time (in Universal Coordinated Time). Write the
921** current time and date as a Julian Day number into *prNow and
922** return 0. Return 1 if the time and date cannot be found.
923*/
924int sqlite3Os2CurrentTime( double *prNow ){
925 double now;
926 USHORT second, minute, hour,
927 day, month, year;
928 DATETIME dt;
929 DosGetDateTime( &dt );
930 second = (USHORT)dt.seconds;
931 minute = (USHORT)dt.minutes + dt.timezone;
932 hour = (USHORT)dt.hours;
933 day = (USHORT)dt.day;
934 month = (USHORT)dt.month;
935 year = (USHORT)dt.year;
936
937 /* Calculations from http://www.astro.keele.ac.uk/~rno/Astronomy/hjd.html
938 http://www.astro.keele.ac.uk/~rno/Astronomy/hjd-0.1.c */
939 /* Calculate the Julian days */
940 now = day - 32076 +
941 1461*(year + 4800 + (month - 14)/12)/4 +
942 367*(month - 2 - (month - 14)/12*12)/12 -
943 3*((year + 4900 + (month - 14)/12)/100)/4;
944
945 /* Add the fractional hours, mins and seconds */
946 now += (hour + 12.0)/24.0;
947 now += minute/1440.0;
948 now += second/86400.0;
949 *prNow = now;
950#ifdef SQLITE_TEST
951 if( sqlite3_current_time ){
952 *prNow = sqlite3_current_time/86400.0 + 2440587.5;
953 }
954#endif
955 return 0;
956}
957
958/*
959** Remember the number of thread-specific-data blocks allocated.
960** Use this to verify that we are not leaking thread-specific-data.
961** Ticket #1601
962*/
963#ifdef SQLITE_TEST
964int sqlite3_tsd_count = 0;
965# define TSD_COUNTER_INCR InterlockedIncrement( &sqlite3_tsd_count )
966# define TSD_COUNTER_DECR InterlockedDecrement( &sqlite3_tsd_count )
967#else
968# define TSD_COUNTER_INCR /* no-op */
969# define TSD_COUNTER_DECR /* no-op */
970#endif
971
972/*
973** If called with allocateFlag>1, then return a pointer to thread
974** specific data for the current thread. Allocate and zero the
975** thread-specific data if it does not already exist necessary.
976**
977** If called with allocateFlag==0, then check the current thread
978** specific data. Return it if it exists. If it does not exist,
979** then return NULL.
980**
981** If called with allocateFlag<0, check to see if the thread specific
982** data is allocated and is all zero. If it is then deallocate it.
983** Return a pointer to the thread specific data or NULL if it is
984** unallocated or gets deallocated.
985*/
986ThreadData *sqlite3Os2ThreadSpecificData( int allocateFlag ){
987 static ThreadData **s_ppTsd = NULL;
988 static const ThreadData zeroData = {0, 0, 0};
989 ThreadData *pTsd;
990
991 if( !s_ppTsd ){
992 sqlite3OsEnterMutex();
993 if( !s_ppTsd ){
994 PULONG pul;
995 APIRET rc = DosAllocThreadLocalMemory(1, &pul);
996 if( rc != NO_ERROR ){
997 sqlite3OsLeaveMutex();
998 return 0;
999 }
1000 s_ppTsd = (ThreadData **)pul;
1001 }
1002 sqlite3OsLeaveMutex();
1003 }
1004 pTsd = *s_ppTsd;
1005 if( allocateFlag>0 ){
1006 if( !pTsd ){
1007 pTsd = sqlite3OsMalloc( sizeof(zeroData) );
1008 if( pTsd ){
1009 *pTsd = zeroData;
1010 *s_ppTsd = pTsd;
1011 TSD_COUNTER_INCR;
1012 }
1013 }
1014 }else if( pTsd!=0 && allocateFlag<0
1015 && memcmp( pTsd, &zeroData, sizeof(ThreadData) )==0 ){
1016 sqlite3OsFree(pTsd);
1017 *s_ppTsd = NULL;
1018 TSD_COUNTER_DECR;
1019 pTsd = 0;
1020 }
1021 return pTsd;
1022}
1023#endif /* OS_OS2 */

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status