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: |
adb0aafaa6b1ea06541f653a2559f099 |
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
Changes to src/os_unix.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** 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. ** | | | 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 | 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 */ | | | 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 | /* ** 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 { | | | | | 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 | return SQLITE_IOERR; } } memset(&lockKey, 0, sizeof(lockKey)); lockKey.fid.dev = statbuf.st_dev; #if OS_VXWORKS | < < < | | 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 | exit_findlockinfo: return rc; } /************************************************************************** ******************** End of the posix lock work-around ******************** **************************************************************************/ #if OS_VXWORKS | > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > | > > | | < < | > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > | | | | > > > > > > < | < | < < < | < | < < < < < < < < | < | | | | < < > > | | > > | > | > | > > > | < > > < < < | < < < < < < | < < > | < < | < < < | < | < > | | | < < < < < < < < | > > > > > > > > > | | < < > | > | < | < < < | < | | | > | 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 | /* ** 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)) | < < < < < < < < < < | 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 | int err = close(pFile->h); if( err ){ pFile->lastErrno = errno; return SQLITE_IOERR_CLOSE; } } #if OS_VXWORKS | > | | | | < | < < < < < < < < < < | 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 | OSTRACE3("OPEN %-3d %s\n", h, zFilename); pNew->h = h; pNew->dirfd = dirfd; SET_THREADID(pNew); #if OS_VXWORKS | < < | < | < | < < < < < < < < < < < < < < < < < | < < < < < < < | 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 | ** 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; | | > | 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 | ** current working directly has been unlinked. */ SimulateIOError( return SQLITE_ERROR ); assert( pVfs->mxPathname==MAX_PATHNAME ); UNUSED_PARAMETER(pVfs); | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 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 | 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 | < < < | 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 | # 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. # | | | 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 | } $::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 | | | 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 | do_test bigfile-1.5 { execsql { SELECT md5sum(x) FROM t2; } } $::MAGIC_SUM db close | | | 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 | do_test bigfile-1.10 { execsql { SELECT md5sum(x) FROM t3; } } $::MAGIC_SUM db close | | | 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 | # 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. # | | > > > | | 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 | # #*********************************************************************** # 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. # | | > | | 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 |
︙ | ︙ |