SQLite

Check-in [adb0aafaa6]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Factor out and simplify the canonical pathname logic in the VxWorks OS interface. (CVS 5943)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: adb0aafaa6b1ea06541f653a2559f099fb1b2795
User & Date: drh 2008-11-21 22:21:50.000
Context
2008-11-21
23:35
Fix testfixture linking problem by marking unix-only symbol as such. (CVS 5944) (check-in: 2ca8b82247 user: pweilbacher tags: trunk)
22:21
Factor out and simplify the canonical pathname logic in the VxWorks OS interface. (CVS 5943) (check-in: adb0aafaa6 user: drh tags: trunk)
20:32
Work toward cleaning up and refactoring the os_unix.c VFS module. Change IS_VXWORKS to OS_VXWORKS. The VxWorks implementation can now be built and tested on Linux using -DOS_VXWORKS=1 -Dsem_t=int -DPATH_MAX=512 -DNO_GETTOD=1. (CVS 5942) (check-in: 30a0132a83 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/os_unix.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains code that is specific to Unix systems.
**
** $Id: os_unix.c,v 1.219 2008/11/21 20:32:34 drh Exp $
*/
#include "sqliteInt.h"
#if SQLITE_OS_UNIX              /* This file is used on unix only */

/*
** If SQLITE_ENABLE_LOCKING_STYLE is defined and is non-zero, then several
** alternative locking implementations are provided:







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains code that is specific to Unix systems.
**
** $Id: os_unix.c,v 1.220 2008/11/21 22:21:50 drh Exp $
*/
#include "sqliteInt.h"
#if SQLITE_OS_UNIX              /* This file is used on unix only */

/*
** If SQLITE_ENABLE_LOCKING_STYLE is defined and is non-zero, then several
** alternative locking implementations are provided:
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
  int oflags;                      /* The flags specified at open */
#endif
#if SQLITE_THREADSAFE
  pthread_t tid;                   /* The thread that "owns" this unixFile */
#endif
#if OS_VXWORKS
  int isDelete;                    /* Delete on close if true */
  char *zVxworksPath;              /* Canonical pathname of the file */
#endif
#ifdef SQLITE_TEST
  /* In test mode, increase the size of this structure a bit so that 
  ** it is larger than the struct CrashFile defined in test6.c.
  */
  char aPadding[32];
#endif







|







143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
  int oflags;                      /* The flags specified at open */
#endif
#if SQLITE_THREADSAFE
  pthread_t tid;                   /* The thread that "owns" this unixFile */
#endif
#if OS_VXWORKS
  int isDelete;                    /* Delete on close if true */
  struct vxworksFileId *pId;       /* Unique file ID */
#endif
#ifdef SQLITE_TEST
  /* In test mode, increase the size of this structure a bit so that 
  ** it is larger than the struct CrashFile defined in test6.c.
  */
  char aPadding[32];
#endif
195
196
197
198
199
200
201










202
203
204
205
206
207
208
*/
#if SQLITE_THREADSAFE
#define threadid pthread_self()
#else
#define threadid 0
#endif












/************************************************************************
*********** Posix Advisory Locking And Thread Interaction ***************
*************************************************************************
**
** Here is the dirt on POSIX advisory locks:  ANSI STD 1003.1 (1996)
** section 6.5.2.2 lines 483 through 490 specify that when a process







>
>
>
>
>
>
>
>
>
>







195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
*/
#if SQLITE_THREADSAFE
#define threadid pthread_self()
#else
#define threadid 0
#endif


/*
** Helper functions to obtain and relinquish the global mutex.
*/
static void unixEnterMutex(void){
  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
}
static void unixLeaveMutex(void){
  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
}

/************************************************************************
*********** Posix Advisory Locking And Thread Interaction ***************
*************************************************************************
**
** Here is the dirt on POSIX advisory locks:  ANSI STD 1003.1 (1996)
** section 6.5.2.2 lines 483 through 490 specify that when a process
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348

/*
** An instance of the following structure serves as the key used
** to locate a particular unixOpenCnt structure given its inode.  This
** is the same as the unixLockKey except that the thread ID is omitted.
*/
struct unixFileId {
  dev_t dev;      /* Device number */
#if OS_VXWORKS
  void *pNameId;  /* Key of canonical filename entry in vxworksFilenameHash */
#else
  ino_t ino;      /* Inode number */
#endif
};

/*
** An instance of the following structure serves as the key used
** to locate a particular unixLockInfo structure given its inode.
**







|

|

|







340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358

/*
** An instance of the following structure serves as the key used
** to locate a particular unixOpenCnt structure given its inode.  This
** is the same as the unixLockKey except that the thread ID is omitted.
*/
struct unixFileId {
  dev_t dev;                  /* Device number */
#if OS_VXWORKS
  struct vxworksFileId *pId;  /* Unique file ID for vxworks. */
#else
  ino_t ino;                  /* Inode number */
#endif
};

/*
** An instance of the following structure serves as the key used
** to locate a particular unixLockInfo structure given its inode.
**
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
      return SQLITE_IOERR;
    }
  }

  memset(&lockKey, 0, sizeof(lockKey));
  lockKey.fid.dev = statbuf.st_dev;
#if OS_VXWORKS
  /* The pFile->zVxworksPath name has been hashed into the vxworksFilenameHash
  ** hash table at this point, so safe to using pointer comparison
  ** to compare the names. */
  lockKey.fid.pNameId = pFile->zVxworksPath;
#else
  lockKey.fid.ino = statbuf.st_ino;
#endif
#if SQLITE_THREADSAFE
  if( threadsOverrideEachOthersLocks<0 ){
    testThreadLockingBehavior(fd);
  }







<
<
<
|







662
663
664
665
666
667
668



669
670
671
672
673
674
675
676
      return SQLITE_IOERR;
    }
  }

  memset(&lockKey, 0, sizeof(lockKey));
  lockKey.fid.dev = statbuf.st_dev;
#if OS_VXWORKS



  lockKey.fid.pId = pFile->pId;
#else
  lockKey.fid.ino = statbuf.st_ino;
#endif
#if SQLITE_THREADSAFE
  if( threadsOverrideEachOthersLocks<0 ){
    testThreadLockingBehavior(fd);
  }
728
729
730
731
732
733
734

























735
736





737


738
739
740
741
742








743
744





















745
746
747
748
749
750
751






752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778


779
780


781

782

783



784
785


786
787
788
789
790
791
792
793
794
795
796
797
798
799

800
801
802
803
804
805
806
807
808
809
810

811
812
813
814
815
816
817
818
819
820
821
822









823
824
825
826

827

828
829
830
831
832
833
834
835
836
837
838
839

840
841
842
843
844
845
846
exit_findlockinfo:
  return rc;
}
/**************************************************************************
******************** End of the posix lock work-around ********************
**************************************************************************/


























#if OS_VXWORKS
/*





** This hash table is used to bind the canonical file name to a


** unixFile structure and use the hash key (= canonical name)
** instead of the Inode number of the file to find the matching
** unixLockInfo and unixOpenCnt structures. It also helps to make the
** name of the semaphore when LOCKING_STYLE_NAMEDSEM is used
** for the file.








*/
static Hash vxworksFilenameHash;





















#endif

#if OS_VXWORKS
/*
** Implementation of a realpath() like function for vxWorks
** to determine canonical path name from given name. It does
** not support symlinks. Neither does it handle volume prefixes.






*/
char *
vxrealpath(const char *pathname, int dostat)
{
  struct stat sbuf;
  int len;
  char *where, *ptr, *last;
  char *result, *curpath, *workpath, *namebuf;

  len = pathconf(pathname, _PC_PATH_MAX);
  if( len<0 ){
    len = PATH_MAX;
  }
  result = sqlite3_malloc(len * 4);
  if( !result ){
    return 0;
  }
  curpath = result + len;
  workpath = curpath + len;
  namebuf = workpath + len;
  strcpy(curpath, pathname);
  if( *pathname!='/' ){
    if( !getcwd(workpath, len) ){
      sqlite3_free(result);
      return 0;
    }
  }else{


    *workpath = '\0';
  }


  where = curpath;

  while( *where ){

    if( !strcmp(where, ".") ){



      where++;
      continue;


    }
    if( !strncmp(where, "./", 2) ){
      where += 2;
      continue;
    }
    if( !strncmp(where, "../", 3) ){
      where += 3;
      ptr = last = workpath;
      while( *ptr ){
        if( *ptr=='/' ){
          last = ptr;
        }
        ptr++;
      }

      *last = '\0';
      continue;
    }
    ptr = strchr(where, '/');
    if( !ptr ){
      ptr = where + strlen(where) - 1;
    }else{
      *ptr = '\0';
    }
    strcpy(namebuf, workpath);
    for( last = namebuf; *last; last++ ){

      continue;
    }
    if( *--last!='/' ){
      strcat(namebuf, "/");
    }
    strcat(namebuf, where);
    where = ++ptr;
    if( dostat ){
      if( stat(namebuf, &sbuf)==-1 ){
        sqlite3_free(result);
        return 0;
      }









      if( (sbuf.st_mode & S_IFDIR)==S_IFDIR ){
        strcpy(workpath, namebuf);
        continue;
      }

      if( *where ){

        sqlite3_free(result);
        return 0;
      }
    }
    strcpy(workpath, namebuf);
  }
  strcpy(result, workpath);
  return result;
}
#endif




#ifdef SQLITE_TEST
/* simulate multiple hosts by creating unique hostid file paths */
int sqlite3_hostid_num = 0;
#endif

/*







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

|
>
>
>
>
>
|
>
>
|
|
<
<
|
>
>
>
>
>
>
>
>

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|



|
|
|
>
>
>
>
>
>

<
|
<
|
<
<
<
|
<
|
<
<
<
<
<
<
<
<
|
<
|
|
|
|
<
<
>
>
|
|
>
>
|
>
|
>
|
>
>
>
|
<
>
>

<
<
<
|
<
<
<
<
<
<
|
<
<
>
|
<
<
|
<
<
<
|
<
|
<
>
|
|
|
<
<
<
<
<
<
<
<
|
>
>
>
>
>
>
>
>
>
|
|
<
<
>
|
>
|
<
|
<
<
<
|
<

|
|
|
>







735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778


779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824

825

826



827

828








829

830
831
832
833


834
835
836
837
838
839
840
841
842
843
844
845
846
847
848

849
850
851



852






853


854
855


856



857

858

859
860
861
862








863
864
865
866
867
868
869
870
871
872
873
874


875
876
877
878

879



880

881
882
883
884
885
886
887
888
889
890
891
892
exit_findlockinfo:
  return rc;
}
/**************************************************************************
******************** End of the posix lock work-around ********************
**************************************************************************/

/**************************************************************************
**************** Begin Unique File ID Utility Used By VxWorks *************
***************************************************************************
**
** The inode numbers of files are meaningless in VxWorks.  Inodes cannot
** be used to find a unique identifier for a file.   A unique file id
** must be based on the canonical filename.
**
** A pointer to an instance of the following structure can be used as a
** unique file ID in VxWorks.  Each instance of this structure contains
** a copy of the canonical filename.  There is also a reference count.  
** The structure is reclaimed when the number of pointers to it drops to
** zero.
**
** There are never very many files open at one time and lookups are not
** a performance-critical path, so it is sufficient to put these
** structures on a linked list.
*/
struct vxworksFileId {
  struct vxworksFileId *pNext;  /* Next in a list of them all */
  int nRef;                     /* Number of references to this one */
  int nName;                    /* Length of the zCanonicalName[] string */
  char *zCanonicalName;         /* Canonical filename */
};

#if OS_VXWORKS
/* 
** All unique filesname are held on a linked list headed by this
** variable:
*/
static struct vxworksFileId *vxworksFileList = 0;
#endif

#if OS_VXWORKS
/*
** Simplify a filename into its canonical form
** by making the following changes:


**
**  * removing any trailing and duplicate /
**  * removing /./
**  * removing /A/../
**
** Changes are made in-place.  Return the new name length.
**
** The original filename is in z[0..n-1].  Return the number of
** characters in the simplified name.
*/
static int vxworksSimplifyName(char *z, int n){
  int i, j;
  while( n>1 && z[n-1]=='/' ){ n--; }
  for(i=j=0; i<n; i++){
    if( z[i]=='/' ){
      if( z[i+1]=='/' ) continue;
      if( z[i+1]=='.' && i+2<n && z[i+2]=='/' ){
        i += 1;
        continue;
      }
      if( z[i+1]=='.' && i+3<n && z[i+2]=='.' && z[i+3]=='/' ){
        while( j>0 && z[j-1]!='/' ){ j--; }
        if( j>0 ){ j--; }
        i += 2;
        continue;
      }
    }
    z[j++] = z[i];
  }
  z[j] = 0;
  return j;
}
#endif /* OS_VXWORKS */

#if OS_VXWORKS
/*
** Find a unique file ID for the given absolute pathname.  Return
** a pointer to the vxworksFileId object.  This pointer is the unique
** file ID.
**
** The nRef field of the vxworksFileId object is incremented before
** the object is returned.  A new vxworksFileId object is created
** and added to the global list if necessary.
**
** If a memory allocation error occurs, return NULL.
*/

static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){

  struct vxworksFileId *pNew;         /* search key and new file ID */



  struct vxworksFileId *pCandidate;   /* For looping over existing file IDs */

  int n;                              /* Length of zAbsoluteName string */










  assert( zAbsoluteName[0]=='/' );
  n = strlen(zAbsoluteName);
  pNew = sqlite3_malloc( sizeof(*pNew) + (n+1) );
  if( pNew==0 ) return 0;


  pNew->zCanonicalName = (char*)&pNew[1];
  memcpy(pNew->zCanonicalName, zAbsoluteName, n+1);
  n = vxworksSimplifyName(pNew->zCanonicalName, n);

  /* Search for an existing entry that matching the canonical name.
  ** If found, increment the reference count and return a pointer to
  ** the existing file ID.
  */
  unixEnterMutex();
  for(pCandidate=vxworksFileList; pCandidate; pCandidate=pCandidate->pNext){
    if( pCandidate->nName==n 
     && memcmp(pCandidate->zCanonicalName, pNew->zCanonicalName, n)==0
    ){
       sqlite3_free(pNew);
       pCandidate->nRef++;

       unixLeaveMutex();
       return pCandidate;
    }



  }









  /* No match was found.  We will make a new file ID */
  pNew->nRef = 1;


  pNew->nName = n;



  pNew->pNext = vxworksFileList;

  vxworksFileList = pNew;

  unixLeaveMutex();
  return pNew;
}
#endif /* OS_VXWORKS */









#if OS_VXWORKS
/*
** Decrement the reference count on a vxworksFileId object.  Free
** the object when the reference count reaches zero.
*/
static void vxworksReleaseFileId(struct vxworksFileId *pId){
  unixEnterMutex();
  assert( pId->nRef>0 );
  pId->nRef--;
  if( pId->nRef==0 ){
    struct vxworksFileId **pp;


    for(pp=&vxworksFileList; *pp && *pp!=pId; pp = &((*pp)->pNext)){}
    assert( *pp==pId );
    *pp = pId->pNext;
    sqlite3_free(pId);

  }



  unixLeaveMutex();

}
#endif /* OS_VXWORKS */
/**************************************************************************
************** End of Unique File ID Utility Used By VxWorks **************
**************************************************************************/

#ifdef SQLITE_TEST
/* simulate multiple hosts by creating unique hostid file paths */
int sqlite3_hostid_num = 0;
#endif

/*
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901

/*
** Only set the lastErrno if the error code is a real error and not 
** a normal expected return code of SQLITE_BUSY or SQLITE_OK
*/
#define IS_LOCK_ERROR(x)  ((x != SQLITE_OK) && (x != SQLITE_BUSY))

/*
** Helper functions to obtain and relinquish the global mutex.
*/
static void unixEnterMutex(void){
  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
}
static void unixLeaveMutex(void){
  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
}

#ifdef SQLITE_LOCK_TRACE
/*
** Print out information about all locking operations.
**
** This routine is used for troubleshooting locks on multithreaded
** platforms.  Enable by compiling with the -DSQLITE_LOCK_TRACE
** command-line option on the compiler.  This code is normally







<
<
<
<
<
<
<
<
<
<







924
925
926
927
928
929
930










931
932
933
934
935
936
937

/*
** Only set the lastErrno if the error code is a real error and not 
** a normal expected return code of SQLITE_BUSY or SQLITE_OK
*/
#define IS_LOCK_ERROR(x)  ((x != SQLITE_OK) && (x != SQLITE_BUSY))











#ifdef SQLITE_LOCK_TRACE
/*
** Print out information about all locking operations.
**
** This routine is used for troubleshooting locks on multithreaded
** platforms.  Enable by compiling with the -DSQLITE_LOCK_TRACE
** command-line option on the compiler.  This code is normally
1953
1954
1955
1956
1957
1958
1959

1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
      int err = close(pFile->h);
      if( err ){
        pFile->lastErrno = errno;
        return SQLITE_IOERR_CLOSE;
      }
    }
#if OS_VXWORKS

    if( pFile->isDelete && pFile->zVxworksPath ){
      unlink(pFile->zVxworksPath);
    }
    if( pFile->zVxworksPath ){
      HashElem *pElem;
      int n = strlen(pFile->zVxworksPath) + 1;
      pElem = sqlite3HashFindElem(&vxworksFilenameHash, pFile->zVxworksPath, n);
      if( pElem ){
        long cnt = (long)pElem->data;
        cnt--;
        if( cnt==0 ){
          sqlite3HashInsert(&vxworksFilenameHash, pFile->zVxworksPath, n, 0);
        }else{
          pElem->data = (void*)cnt;
        }
      }
    }
#endif
    OSTRACE2("CLOSE   %-3d\n", pFile->h);
    OpenCounter(-1);
    memset(pFile, 0, sizeof(unixFile));
  }
  return SQLITE_OK;







>
|
|
|
|
<
|
<
<
<
<
<
<
<
<
<
<







1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000

2001










2002
2003
2004
2005
2006
2007
2008
      int err = close(pFile->h);
      if( err ){
        pFile->lastErrno = errno;
        return SQLITE_IOERR_CLOSE;
      }
    }
#if OS_VXWORKS
    if( pFile->pId ){
      if( pFile->isDelete ){
         unlink(pFile->pId->zCanonicalName);
      }
      vxworksReleaseFileId(pFile->pId);

      pFile->pId = 0;










    }
#endif
    OSTRACE2("CLOSE   %-3d\n", pFile->h);
    OpenCounter(-1);
    memset(pFile, 0, sizeof(unixFile));
  }
  return SQLITE_OK;
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608

  OSTRACE3("OPEN    %-3d %s\n", h, zFilename);    
  pNew->h = h;
  pNew->dirfd = dirfd;
  SET_THREADID(pNew);

#if OS_VXWORKS
  {
    HashElem *pElem;
    char *zRealname = vxrealpath(zFilename, 1);
    int n;
    pNew->zVxworksPath = 0;
    if( !zRealname ){
      rc = SQLITE_NOMEM;
      eLockingStyle = LOCKING_STYLE_NONE;
    }else{
      n = strlen(zRealname) + 1;
      unixEnterMutex();
      pElem = sqlite3HashFindElem(&vxworksFilenameHash, zRealname, n);
      if( pElem ){
        long cnt = (long)pElem->data;
        cnt++;
        pNew->zVxworksPath = pElem->pKey;
        pElem->data = (void*)cnt;
      }else{
        if( sqlite3HashInsert(&vxworksFilenameHash, zRealname, n,(void*)1)==0 ){
          pElem = sqlite3HashFindElem(&vxworksFilenameHash, zRealname, n);
          if( pElem ){
            pNew->zVxworksPath = pElem->pKey;
          }else{
            sqlite3HashInsert(&vxworksFilenameHash, zRealname, n, 0);
            rc = SQLITE_NOMEM;
            eLockingStyle = LOCKING_STYLE_NONE;
          }
        }
      }
      unixLeaveMutex();
      sqlite3_free(zRealname);
    }
  }
#endif

  if( noLock ){
    eLockingStyle = LOCKING_STYLE_NONE;
  }else{
    eLockingStyle = detectLockingStyle(pVfs, zFilename, h);







<
<
|
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<







3589
3590
3591
3592
3593
3594
3595


3596

3597

3598

















3599







3600
3601
3602
3603
3604
3605
3606

  OSTRACE3("OPEN    %-3d %s\n", h, zFilename);    
  pNew->h = h;
  pNew->dirfd = dirfd;
  SET_THREADID(pNew);

#if OS_VXWORKS


  pNew->pId = vxworksFindFileId(zFilename);

  if( pNew->pId==0 ){

    noLock = 1;

















    rc = SQLITE_NOMEM;







  }
#endif

  if( noLock ){
    eLockingStyle = LOCKING_STYLE_NONE;
  }else{
    eLockingStyle = detectLockingStyle(pVfs, zFilename, h);
3684
3685
3686
3687
3688
3689
3690
3691

3692
3693
3694
3695
3696
3697
3698
       ** included in the namedsemLockingContext
       */
      unixEnterMutex();
      rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen);
      if( (rc==SQLITE_OK) && (pNew->pOpen->pSem==NULL) ){
        char *zSemName = pNew->pOpen->aSemName;
        int n;
        sqlite3_snprintf(MAX_PATHNAME, zSemName, "%s.sem", pNew->zVxworksPath);

        for( n=0; zSemName[n]; n++ )
          if( zSemName[n]=='/' ) zSemName[n] = '_';
        pNew->pOpen->pSem = sem_open(zSemName, O_CREAT, 0666, 1);
        if( pNew->pOpen->pSem == SEM_FAILED ){
          rc = SQLITE_NOMEM;
          pNew->pOpen->aSemName[0] = '\0';
        }







|
>







3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
       ** included in the namedsemLockingContext
       */
      unixEnterMutex();
      rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen);
      if( (rc==SQLITE_OK) && (pNew->pOpen->pSem==NULL) ){
        char *zSemName = pNew->pOpen->aSemName;
        int n;
        sqlite3_snprintf(MAX_PATHNAME, zSemName, "%s.sem",
                         pNew->pId->zCanonicalName);
        for( n=0; zSemName[n]; n++ )
          if( zSemName[n]=='/' ) zSemName[n] = '_';
        pNew->pOpen->pSem = sem_open(zSemName, O_CREAT, 0666, 1);
        if( pNew->pOpen->pSem == SEM_FAILED ){
          rc = SQLITE_NOMEM;
          pNew->pOpen->aSemName[0] = '\0';
        }
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
  ** current working directly has been unlinked.
  */
  SimulateIOError( return SQLITE_ERROR );

  assert( pVfs->mxPathname==MAX_PATHNAME );
  UNUSED_PARAMETER(pVfs);

#if OS_VXWORKS
  {
    char *zRealname = vxrealpath(zPath, 0);
    zOut[0] = '\0';
    if( !zRealname ){
      return SQLITE_CANTOPEN;
    }
    sqlite3_snprintf(nOut, zOut, "%s", zRealname);
    sqlite3_free(zRealname);
    return SQLITE_OK;
  }
#else
  zOut[nOut-1] = '\0';
  if( zPath[0]=='/' ){
    sqlite3_snprintf(nOut, zOut, "%s", zPath);
  }else{
    int nCwd;
    if( getcwd(zOut, nOut-1)==0 ){
      return SQLITE_CANTOPEN;
    }
    nCwd = strlen(zOut);
    sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath);
  }
  return SQLITE_OK;

#if 0
  /*
  ** Remove "/./" path elements and convert "/A/./" path elements
  ** to just "/".
  */
  if( zFull ){
    int i, j;
    for(i=j=0; zFull[i]; i++){
      if( zFull[i]=='/' ){
        if( zFull[i+1]=='/' ) continue;
        if( zFull[i+1]=='.' && zFull[i+2]=='/' ){
          i += 1;
          continue;
        }
        if( zFull[i+1]=='.' && zFull[i+2]=='.' && zFull[i+3]=='/' ){
          while( j>0 && zFull[j-1]!='/' ){ j--; }
          i += 3;
          continue;
        }
      }
      zFull[j++] = zFull[i];
    }
    zFull[j] = 0;
  }
#endif
#endif /* #if OS_VXWORKS */
}


#ifndef SQLITE_OMIT_LOAD_EXTENSION
/*
** Interfaces for opening a shared library, finding entry points
** within the shared library, and closing the shared library.







<
<
<
<
<
<
<
<
<
<
<
<












<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







4107
4108
4109
4110
4111
4112
4113












4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125



























4126
4127
4128
4129
4130
4131
4132
  ** current working directly has been unlinked.
  */
  SimulateIOError( return SQLITE_ERROR );

  assert( pVfs->mxPathname==MAX_PATHNAME );
  UNUSED_PARAMETER(pVfs);













  zOut[nOut-1] = '\0';
  if( zPath[0]=='/' ){
    sqlite3_snprintf(nOut, zOut, "%s", zPath);
  }else{
    int nCwd;
    if( getcwd(zOut, nOut-1)==0 ){
      return SQLITE_CANTOPEN;
    }
    nCwd = strlen(zOut);
    sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath);
  }
  return SQLITE_OK;



























}


#ifndef SQLITE_OMIT_LOAD_EXTENSION
/*
** Interfaces for opening a shared library, finding entry points
** within the shared library, and closing the shared library.
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
    UNIXVFS("unix-namedsem",LOCKING_STYLE_NAMEDSEM),
    UNIXVFS("unix-proxy",   LOCKING_STYLE_PROXY)
  };
  for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
    sqlite3_vfs_register(&aVfs[i], 0);
  }
#endif
#if OS_VXWORKS
  sqlite3HashInit(&vxworksFilenameHash, 1);
#endif
  sqlite3_vfs_register(&unixVfs, 1);
  return SQLITE_OK; 
}

/*
** Shutdown the operating system interface. This is a no-op for unix.
*/
int sqlite3_os_end(void){ 
  return SQLITE_OK; 
}
 
#endif /* SQLITE_OS_UNIX */







<
<
<












4324
4325
4326
4327
4328
4329
4330



4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
    UNIXVFS("unix-namedsem",LOCKING_STYLE_NAMEDSEM),
    UNIXVFS("unix-proxy",   LOCKING_STYLE_PROXY)
  };
  for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
    sqlite3_vfs_register(&aVfs[i], 0);
  }
#endif



  sqlite3_vfs_register(&unixVfs, 1);
  return SQLITE_OK; 
}

/*
** Shutdown the operating system interface. This is a no-op for unix.
*/
int sqlite3_os_end(void){ 
  return SQLITE_OK; 
}
 
#endif /* SQLITE_OS_UNIX */
Changes to test/bigfile.test.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script testing the ability of SQLite to handle database
# files larger than 4GB.
#
# $Id: bigfile.test,v 1.10 2007/08/18 10:59:21 danielk1977 Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# If SQLITE_DISABLE_LFS is defined, omit this file.
ifcapable !lfs {







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script testing the ability of SQLite to handle database
# files larger than 4GB.
#
# $Id: bigfile.test,v 1.11 2008/11/21 22:21:51 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# If SQLITE_DISABLE_LFS is defined, omit this file.
ifcapable !lfs {
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
} $::MAGIC_SUM

# Try to create a large file - a file that is larger than 2^32 bytes.
# If this fails, it means that the system being tested does not support
# large files.  So skip all of the remaining tests in this file.
#
db close
if {[catch {fake_big_file 4096 test.db} msg]} {
  puts "**** Unable to create a file larger than 4096 MB. *****"
  puts "$msg"
  finish_test
  return
}

do_test bigfile-1.2 {







|







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
} $::MAGIC_SUM

# Try to create a large file - a file that is larger than 2^32 bytes.
# If this fails, it means that the system being tested does not support
# large files.  So skip all of the remaining tests in this file.
#
db close
if {[catch {fake_big_file 4096 [pwd]/test.db} msg]} {
  puts "**** Unable to create a file larger than 4096 MB. *****"
  puts "$msg"
  finish_test
  return
}

do_test bigfile-1.2 {
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
do_test bigfile-1.5 {
  execsql {
    SELECT md5sum(x) FROM t2;
  }
} $::MAGIC_SUM

db close
if {[catch {fake_big_file 8192 test.db}]} {
  puts "**** Unable to create a file larger than 8192 MB. *****"
  finish_test
  return
}

do_test bigfile-1.6 {
  sqlite3 db test.db







|







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
do_test bigfile-1.5 {
  execsql {
    SELECT md5sum(x) FROM t2;
  }
} $::MAGIC_SUM

db close
if {[catch {fake_big_file 8192 [pwd]/test.db}]} {
  puts "**** Unable to create a file larger than 8192 MB. *****"
  finish_test
  return
}

do_test bigfile-1.6 {
  sqlite3 db test.db
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
do_test bigfile-1.10 {
  execsql {
    SELECT md5sum(x) FROM t3;
  }
} $::MAGIC_SUM

db close
if {[catch {fake_big_file 16384 test.db}]} {
  puts "**** Unable to create a file larger than 16384 MB. *****"
  finish_test
  return
}

do_test bigfile-1.11 {
  sqlite3 db test.db







|







138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
do_test bigfile-1.10 {
  execsql {
    SELECT md5sum(x) FROM t3;
  }
} $::MAGIC_SUM

db close
if {[catch {fake_big_file 16384 [pwd]/test.db}]} {
  puts "**** Unable to create a file larger than 16384 MB. *****"
  finish_test
  return
}

do_test bigfile-1.11 {
  sqlite3 db test.db
Changes to test/lock.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22



23
24
25
26
27
28
29
30
# 2001 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is database locks.
#
# $Id: lock.test,v 1.33 2006/08/16 16:42:48 drh Exp $


set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Create an alternative connection to the database
#
do_test lock-1.0 {



  sqlite3 db2 ./test.db
  set dummy {}
} {}
do_test lock-1.1 {
  execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
} {}
do_test lock-1.2 {
  execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name} db2













|








>
>
>
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 2001 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is database locks.
#
# $Id: lock.test,v 1.34 2008/11/21 22:21:51 drh Exp $


set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Create an alternative connection to the database
#
do_test lock-1.0 {
  # Give a complex pathnme to stress the path simplification logic in
  # the vxworks driver.
  file mkdir tempdir/t1/t2
  sqlite3 db2 ./tempdir/../tempdir/t1/.//t2/../../..//test.db
  set dummy {}
} {}
do_test lock-1.1 {
  execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
} {}
do_test lock-1.2 {
  execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name} db2
Changes to test/lock3.test.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is database locks and the operation of the
# DEFERRED, IMMEDIATE, and EXCLUSIVE keywords as modifiers to the
# BEGIN command.
#
# $Id: lock3.test,v 1.1 2004/10/05 02:41:43 drh Exp $


set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Establish two connections to the same database.  Put some
# sample data into the database.
#
do_test lock3-1.1 {

  sqlite3 db2 test.db
  execsql {
    CREATE TABLE t1(a);
    INSERT INTO t1 VALUES(1);
  }
  execsql {
    SELECT * FROM t1
  } db2







|









>
|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is database locks and the operation of the
# DEFERRED, IMMEDIATE, and EXCLUSIVE keywords as modifiers to the
# BEGIN command.
#
# $Id: lock3.test,v 1.2 2008/11/21 22:21:51 drh Exp $


set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Establish two connections to the same database.  Put some
# sample data into the database.
#
do_test lock3-1.1 {
  file mkdir tempdir/t1/t2/t3
  sqlite3 db2 ./tempdir/t1//t2/./t3//./../..//./../../tempdir/..//test.db//
  execsql {
    CREATE TABLE t1(a);
    INSERT INTO t1 VALUES(1);
  }
  execsql {
    SELECT * FROM t1
  } db2