/ Check-in [82db5456]
Login
Overview
Comment:Add the OpenReadOnly() OS method to fix a bug in the pager. (CVS 257)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:82db5456c9817283d725daf4e1081d32a71466ad
User & Date: drh 2001-09-19 13:58:44
Context
2001-09-20
01:44
2.0-Alpha-2 release (CVS 258) check-in: d2a1aac4 user: drh tags: trunk
2001-09-19
13:58
Add the OpenReadOnly() OS method to fix a bug in the pager. (CVS 257) check-in: 82db5456 user: drh tags: trunk
13:22
Trying to get the OS abstraction layer to work. (CVS 256) check-in: abff526d user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/os.c.

24
25
26
27
28
29
30

31
32
33
34
35
36
37
38
39
40
...
170
171
172
173
174
175
176

































177
178
179
180
181
182
183
...
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
...
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
#  define OS_UNIX 0
# endif
#endif
#ifndef OS_WIN
# define OS_WIN 0
#endif
#if OS_UNIX

# include <fcntl.h>
# include <sys/stat.h>
# include <unistd.h>
# include <time.h>
#endif
#if OS_WIN
# include <winbase.h>
#endif

/*
................................................................................
  HANDLE h = CreateFile(zFilename,
     GENERIC_READ | GENERIC_WRITE,
     0,
     NULL,
     CREATE_ALWAYS,
     FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
     NULL

































  );
  if( h==INVALID_HANDLE_VALUE ){
    return SQLITE_CANTOPEN;
  }
  *pResult = h;
  return SQLITE_OK;
#endif
................................................................................
/*
** Get a read or write lock on a file.
*/
int sqliteOsLock(OsFile id, int wrlock){
#if OS_UNIX
  int rc;
  struct flock lock;
memset(&lock, 0, sizeof(lock));
  lock.l_type = wrlock ? F_WRLCK : F_RDLCK;
  lock.l_whence = SEEK_SET;
  lock.l_start = 0L;
  lock.l_len = 1024L;
printf("LOCK %s %d\n",wrlock?"WRITE":"READ",id);
  rc = fcntl(id, F_SETLK, &lock);
fcntl(id, F_GETLK, &lock);
printf("rc=%d why=%d\n",rc,lock.l_type);
  return rc==0 ? SQLITE_OK : SQLITE_BUSY;
#endif
#if OS_WIN
  if( !LockFile(id, 0, 0, 1024, 0) ){
    return SQLITE_BUSY;
  }
  return SQLITE_OK;
................................................................................
*/
int sqliteOsUnlock(OsFile id){
#if OS_UNIX
  int rc;
  struct flock lock;
  lock.l_type = F_UNLCK;
  lock.l_whence = SEEK_SET;
  lock.l_start = 0L;
  lock.l_len = 1L;
printf("UNLOCK %d\n",id);
  rc = fcntl(id, F_SETLK, &lock);
  return rc==0 ? SQLITE_OK : SQLITE_IOERR;
#endif
#if OS_WIN
  return UnlockFile(id, 0, 0, 1024, 0) ? SQLITE_OK : SQLITE_IOERR;
#endif
}







>


<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







<


|
<
<

<
<







 







|
<
<







24
25
26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
...
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
...
386
387
388
389
390
391
392

393
394
395


396


397
398
399
400
401
402
403
...
409
410
411
412
413
414
415
416


417
418
419
420
421
422
423
#  define OS_UNIX 0
# endif
#endif
#ifndef OS_WIN
# define OS_WIN 0
#endif
#if OS_UNIX
# include <unistd.h>
# include <fcntl.h>
# include <sys/stat.h>

# include <time.h>
#endif
#if OS_WIN
# include <winbase.h>
#endif

/*
................................................................................
  HANDLE h = CreateFile(zFilename,
     GENERIC_READ | GENERIC_WRITE,
     0,
     NULL,
     CREATE_ALWAYS,
     FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
     NULL
  );
  if( h==INVALID_HANDLE_VALUE ){
    return SQLITE_CANTOPEN;
  }
  *pResult = h;
  return SQLITE_OK;
#endif
}

/*
** Attempt to open a new file for read-only access.
**
** On success, write the file handle into *pResult and return SQLITE_OK.
**
** On failure, return SQLITE_CANTOPEN.
*/
int sqliteOsOpenReadOnly(const char *zFilename, OsFile *pResult){
#if OS_UNIX
  int fd = open(zFilename, O_RDONLY);
  if( fd<0 ){
    return SQLITE_CANTOPEN;
  }
  *pResult = fd;
  return SQLITE_OK;
#endif
#if OS_WIN
  HANDLE h = CreateFile(zFilename,
     GENERIC_READ,
     0,
     NULL,
     OPEN_EXISTING,
     FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
     NULL
  );
  if( h==INVALID_HANDLE_VALUE ){
    return SQLITE_CANTOPEN;
  }
  *pResult = h;
  return SQLITE_OK;
#endif
................................................................................
/*
** Get a read or write lock on a file.
*/
int sqliteOsLock(OsFile id, int wrlock){
#if OS_UNIX
  int rc;
  struct flock lock;

  lock.l_type = wrlock ? F_WRLCK : F_RDLCK;
  lock.l_whence = SEEK_SET;
  lock.l_start = lock.l_len = 0L;


  rc = fcntl(id, F_SETLK, &lock);


  return rc==0 ? SQLITE_OK : SQLITE_BUSY;
#endif
#if OS_WIN
  if( !LockFile(id, 0, 0, 1024, 0) ){
    return SQLITE_BUSY;
  }
  return SQLITE_OK;
................................................................................
*/
int sqliteOsUnlock(OsFile id){
#if OS_UNIX
  int rc;
  struct flock lock;
  lock.l_type = F_UNLCK;
  lock.l_whence = SEEK_SET;
  lock.l_start = lock.l_len = 0L;


  rc = fcntl(id, F_SETLK, &lock);
  return rc==0 ? SQLITE_OK : SQLITE_IOERR;
#endif
#if OS_WIN
  return UnlockFile(id, 0, 0, 1024, 0) ? SQLITE_OK : SQLITE_IOERR;
#endif
}

Changes to src/os.h.

36
37
38
39
40
41
42

43
44
45
46
47
48
49
# deifne SQLITE_MIN_SLEEP_MS 1
#endif

int sqliteOsDelete(const char*);
int sqliteOsFileExists(const char*);
int sqliteOsOpenReadWrite(const char*, OsFile*, int*);
int sqliteOsOpenExclusive(const char*, OsFile*);

int sqliteOsTempFileName(char*);
int sqliteOsClose(OsFile);
int sqliteOsRead(OsFile, void*, int amt);
int sqliteOsWrite(OsFile, const void*, int amt);
int sqliteOsSeek(OsFile, int offset);
int sqliteOsSync(OsFile);
int sqliteOsTruncate(OsFile, int size);







>







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# deifne SQLITE_MIN_SLEEP_MS 1
#endif

int sqliteOsDelete(const char*);
int sqliteOsFileExists(const char*);
int sqliteOsOpenReadWrite(const char*, OsFile*, int*);
int sqliteOsOpenExclusive(const char*, OsFile*);
int sqliteOsOpenReadOnly(const char*, OsFile*);
int sqliteOsTempFileName(char*);
int sqliteOsClose(OsFile);
int sqliteOsRead(OsFile, void*, int amt);
int sqliteOsWrite(OsFile, const void*, int amt);
int sqliteOsSeek(OsFile, int offset);
int sqliteOsSync(OsFile);
int sqliteOsTruncate(OsFile, int size);

Changes to src/pager.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.22 2001/09/19 13:22:40 drh Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
#include "os.h"
#include <assert.h>
#include <string.h>

................................................................................
      return SQLITE_BUSY;
    }
    pPager->state = SQLITE_READLOCK;

    /* If a journal file exists, try to play it back.
    */
    if( sqliteOsFileExists(pPager->zJournal) ){
       int rc, readOnly;

       /* Open the journal for exclusive access.  Return SQLITE_BUSY if
       ** we cannot get exclusive access to the journal file
       */
       rc = sqliteOsOpenReadWrite(pPager->zJournal, &pPager->jfd, &readOnly);
       if( rc==SQLITE_OK ){
         pPager->journalOpen = 1;
       }
       if( rc!=SQLITE_OK || sqliteOsLock(pPager->jfd, 1)!=SQLITE_OK ){
         if( pPager->journalOpen ){
           sqliteOsClose(pPager->jfd);
           pPager->journalOpen = 0;







|







 







|




|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.23 2001/09/19 13:58:44 drh Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
#include "os.h"
#include <assert.h>
#include <string.h>

................................................................................
      return SQLITE_BUSY;
    }
    pPager->state = SQLITE_READLOCK;

    /* If a journal file exists, try to play it back.
    */
    if( sqliteOsFileExists(pPager->zJournal) ){
       int rc;

       /* Open the journal for exclusive access.  Return SQLITE_BUSY if
       ** we cannot get exclusive access to the journal file
       */
       rc = sqliteOsOpenReadOnly(pPager->zJournal, &pPager->jfd);
       if( rc==SQLITE_OK ){
         pPager->journalOpen = 1;
       }
       if( rc!=SQLITE_OK || sqliteOsLock(pPager->jfd, 1)!=SQLITE_OK ){
         if( pPager->journalOpen ){
           sqliteOsClose(pPager->jfd);
           pPager->journalOpen = 0;