/ Check-in [adb0aafa]
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 | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: adb0aafaa6b1ea06541f653a2559f099fb1b2795
User & Date: drh 2008-11-21 22:21:50
Context
2008-11-21
23:35
Fix testfixture linking problem by marking unix-only symbol as such. (CVS 5944) check-in: 2ca8b822 user: pweilbacher tags: trunk
22:21
Factor out and simplify the canonical pathname logic in the VxWorks OS interface. (CVS 5943) check-in: adb0aafa 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: 30a0132a user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
...
195
196
197
198
199
200
201










202
203
204
205
206
207
208
...
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
...
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
...
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
...
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
....
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
....
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
....
3684
3685
3686
3687
3688
3689
3690
3691

3692
3693
3694
3695
3696
3697
3698
....
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
....
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
**    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:
................................................................................
  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
................................................................................
*/
#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
................................................................................

/*
** 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.
**
................................................................................
      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);
  }
................................................................................
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

/*
................................................................................

/*
** 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
................................................................................
      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;
................................................................................

  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);
................................................................................
       ** 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';
        }
................................................................................
  ** 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.
................................................................................
    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 */







|







 







|







 







>
>
>
>
>
>
>
>
>
>







 







|

|

|







 







<
<
<
|







 







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

|
<
<
<
<
<
<
>
>

<
>




<
<
<
>
>
>
>
>
>
>
>
>
>
>

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

|

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







 







<
<
<
<
<
<
<
<
<
<







 







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







 







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







 







|
>







 







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












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







 







<
<
<












8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
...
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
...
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
...
662
663
664
665
666
667
668



669
670
671
672
673
674
675
676
...
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
...
924
925
926
927
928
929
930










931
932
933
934
935
936
937
....
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999

2000
2001










2002
2003
2004
2005
2006
2007
2008
....
3589
3590
3591
3592
3593
3594
3595

3596
3597
3598



3599

























3600
3601
3602
3603
3604
3605
3606
....
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
....
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
....
4324
4325
4326
4327
4328
4329
4330



4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
**    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:
................................................................................
  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
................................................................................
*/
#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
................................................................................

/*
** 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.
**
................................................................................
      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);
  }
................................................................................
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

/*
................................................................................

/*
** 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
................................................................................
      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;
................................................................................

  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);
................................................................................
       ** 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';
        }
................................................................................
  ** 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.
................................................................................
    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
..
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
...
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
...
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#    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 {
................................................................................
} $::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 {
................................................................................
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
................................................................................
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







|







 







|







 







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
...
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
...
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#    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 {
................................................................................
} $::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 {
................................................................................
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
................................................................................
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.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22



23
24
25
26
27
28
29
30
#    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







|








>
>
>
|







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
#    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