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