]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Simplify the unixFullpathname() function. This adds a dependency on lstat().
authordan <dan@noemail.net>
Mon, 25 Jan 2016 18:05:49 +0000 (18:05 +0000)
committerdan <dan@noemail.net>
Mon, 25 Jan 2016 18:05:49 +0000 (18:05 +0000)
FossilOrigin-Name: f71249d3db9242b8f38955db51a7a5789d002803

manifest
manifest.uuid
src/os_unix.c

index 0b395a1661ae45dda8b720c9647e7f4de7bbc9c0..27188d419f648649706bd7777f1a1193da1f09b5 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sissues\son\sunix\swith\sopening\sdatabase\sfiles\svia\ssymlinks\sthat\sare\snot\sin\sthe\scurrent\sworking\sdirectory.\sAnd\swith\snested\ssymlinks.
-D 2016-01-25T17:04:48.546
+C Simplify\sthe\sunixFullpathname()\sfunction.\sThis\sadds\sa\sdependency\son\slstat().
+D 2016-01-25T18:05:49.964
 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9
@@ -329,7 +329,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8
 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf
 F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e
 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
-F src/os_unix.c cf524029242b4f878d6b97bad25cc2c0b66c2b31
+F src/os_unix.c 6604e7f9e5298b615f729b6bb3c22bd3545cdca6
 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811
 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
 F src/pager.c 2916c66aee50f69d9ec56a7619b62d9c6a3bee61
@@ -1419,10 +1419,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 7ac017a498b6fb28343eef2d24e400c7800660d6
-R 0289127606d03bb3b649ecbd39bb14a5
-T *branch * follow-symlinks
-T *sym-follow-symlinks *
-T -sym-trunk *
+P 80398fd44fb232193450103808e1854e0eba5652
+R 084dee05e1353887f6af0d88670b22d0
 U dan
-Z 3e18b3d01ba737d3635110839e378935
+Z 72572e009a3ce3b7747f3257ebf7dfc7
index 6dda1af216faac028352c2659cf775e278d9490a..b66c39a6ae5dc1f390606bf156d9fb32fcbd46a3 100644 (file)
@@ -1 +1 @@
-80398fd44fb232193450103808e1854e0eba5652
\ No newline at end of file
+f71249d3db9242b8f38955db51a7a5789d002803
\ No newline at end of file
index 9cd1fa19adac292ed8240b199c97b1f5542b15ed..3d113301b804beeef8c9222bbc311d21e4b42df0 100644 (file)
@@ -480,6 +480,8 @@ static struct unix_syscall {
 #endif
 #define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent)
 
+  { "lstat",         (sqlite3_syscall_ptr)lstat,       0  },
+#define osLstat      ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent)
 
 }; /* End of the overrideable system calls */
 
@@ -5933,54 +5935,24 @@ static int unixAccess(
 }
 
 /*
-** Buffer zOut contains a (possibly) relative pathname. Overwrite it with
-** the corresponding full pathname.
 **
-** Parameter nOut is the allocated size of buffer zOut. nByte is the number
-** of bytes in the nul-terminated string that it contains (not including
-** the nul-terminator itself).
-**
-** Return SQLITE_OK if successful, or an SQLite error code otherwise.
 */
 static int mkFullPathname(
-  const char *zPath,              /* Use this path to log any errors */
-  char *zOut,                     /* IN/OUT: Buffer to modify */
-  int nByte,                      /* size of nul-terminated zOut in bytes */
+  const char *zPath,              /* Input path */
+  char *zOut,                     /* Output buffer */
   int nOut                        /* Allocated size of buffer zOut */
 ){
-  /* If buffer zOut[] now contains an absolute path there is nothing more
-  ** to do. If it contains a relative path, do the following:
-  **
-  **   * move the relative path string so that it is at the end of th
-  **     zOut[] buffer.
-  **   * Call getcwd() to read the path of the current working directory 
-  **     into the start of the zOut[] buffer.
-  **   * Append a '/' character to the cwd string and move the 
-  **     relative path back within the buffer so that it immediately 
-  **     follows the '/'.
-  **
-  ** This code is written so that if the combination of the CWD and relative
-  ** path are larger than the allocated size of zOut[] the CWD is silently
-  ** truncated to make it fit. This is Ok, as SQLite refuses to open any
-  ** file for which this function returns a full path larger than (nOut-8)
-  ** bytes in size.  */
-  assert( nByte<nOut );
-  testcase( nByte==nOut-5 );
-  testcase( nByte==nOut-4 );
-  if( zOut[0]!='/' && nByte<nOut-4 ){
-    int nCwd;
-    int nRem = nOut-nByte-1;
-    memmove(&zOut[nRem], zOut, nByte+1);
-    zOut[nRem-1] = '\0';
-    if( osGetcwd(zOut, nRem-1)==0 ){
+  int nPath = sqlite3Strlen30(zPath);
+  int iOff = 0;
+  if( zPath[0]!='/' ){
+    if( osGetcwd(zOut, nOut-2)==0 ){
       return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
     }
-    nCwd = sqlite3Strlen30(zOut);
-    assert( nCwd<=nRem-1 );
-    zOut[nCwd] = '/';
-    memmove(&zOut[nCwd+1], &zOut[nRem], nByte+1);
+    iOff = sqlite3Strlen30(zOut);
+    zOut[iOff++] = '/';
   }
-
+  if( (iOff+nPath+1)>nOut ) return SQLITE_CANTOPEN_BKPT;
+  sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath);
   return SQLITE_OK;
 }
 
@@ -6000,13 +5972,11 @@ static int unixFullPathname(
   char *zOut                    /* Output buffer */
 ){
 #if !defined(HAVE_READLINK)
-  sqlite3_snprintf(nOut, zOut, "%s", zIn);
-  nByte = sqlite3Strlen30(zOut);
-  return mkFullPathname(zPath, zOut, sqlite3Strlen30(zOut), nOut);
+  return mkFullPathname(zPath, zOut, nOut);
 #else
   int rc = SQLITE_OK;
   int nByte;
-  int nLink = 0;                /* Number of symbolic links followed so far */
+  int nLink = 1;                /* Number of symbolic links followed so far */
   int bLink;                    /* True for a symbolic link */
   const char *zIn = zPath;      /* Input path for each iteration of loop */
   char *zDel = 0;
@@ -6023,55 +5993,54 @@ static int unixFullPathname(
 
   do {
 
-    /* Attempt to resolve the path as if it were a symbolic link. If it is
-    ** a symbolic link, the resolved path is stored in buffer zOut[]. Or, if
-    ** the identified file is not a symbolic link or does not exist, then
-    ** zPath is copied directly into zOut. Either way, nByte is left set to
-    ** the size of the string copied into zOut[] in bytes.  */
-    assert( (zDel==0 && zIn==zPath) || (zDel!=0 && zIn==zDel) );
-    if( zDel ){
-      assert( zIn==zDel );
-      sqlite3_snprintf(nOut, zDel, "%s", zOut);
-    }
-    nByte = osReadlink(zIn, zOut, nOut-1);
-    if( nByte<0 ){
-      if( errno!=EINVAL && errno!=ENOENT ){
-        rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zPath);
-      }else{
-        sqlite3_snprintf(nOut, zOut, "%s", zIn);
-        nByte = sqlite3Strlen30(zOut);
+    /* Call stat() on path zIn. Set bLink to true if the path is a symbolic
+    ** link, or false otherwise.  */
+    int bLink = 0;
+    struct stat buf;
+    if( osLstat(zIn, &buf)!=0 ){
+      if( errno!=ENOENT ){
+        rc = unixLogError(SQLITE_CANTOPEN_BKPT, "stat", zIn);
       }
-      bLink = 0;
-    }else if( ++nLink>SQLITE_MAX_SYMLINKS ){
-      sqlite3_log(SQLITE_CANTOPEN, 
-          "too many symbolic links (max=%d)", SQLITE_MAX_SYMLINKS
-      );
-      rc = SQLITE_CANTOPEN_BKPT;
     }else{
-      zOut[nByte] = '\0';
-      if( zOut[0]!='/' ){
-        int n;
-        for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--);
-        if( nByte+n+1>nOut ){
-          rc = SQLITE_CANTOPEN_BKPT;
-        }else{
-          memmove(&zOut[n], zOut, nByte+1);
-          memcpy(zOut, zIn, n);
-          nByte += n;
-        }
-      }
+      bLink = S_ISLNK(buf.st_mode);
+    }
+
+    if( bLink ){
       if( zDel==0 ){
         zDel = sqlite3_malloc(nOut);
         if( zDel==0 ) rc = SQLITE_NOMEM;
-        zIn = (const char*)zDel;
+      }else if( ++nLink>SQLITE_MAX_SYMLINKS ){
+        rc = SQLITE_CANTOPEN_BKPT;
       }
-      bLink = 1;
+
+      if( rc==SQLITE_OK ){
+        nByte = osReadlink(zIn, zDel, nOut-1);
+        if( nByte<0 ){
+          rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn);
+        }else if( zDel[0]!='/' ){
+          int n;
+          for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--);
+          if( nByte+n+1>nOut ){
+            rc = SQLITE_CANTOPEN_BKPT;
+          }else{
+            memmove(&zDel[n], zDel, nByte+1);
+            memcpy(zDel, zIn, n);
+            nByte += n;
+          }
+          zDel[nByte] = '\0';
+        }
+      }
+
+      zIn = zDel;
     }
 
     if( rc==SQLITE_OK ){
-      rc = mkFullPathname(zPath, zOut, nByte, nOut);
+      assert( zIn!=zOut || zIn[0]=='/' );
+      rc = mkFullPathname(zIn, zOut, nOut);
     }
-  }while( bLink && rc==SQLITE_OK );
+    if( bLink==0 ) break;
+    zIn = zOut;
+  }while( rc==SQLITE_OK );
 
   sqlite3_free(zDel);
   return rc;
@@ -7574,7 +7543,7 @@ int sqlite3_os_init(void){
 
   /* Double-check that the aSyscall[] array has been constructed
   ** correctly.  See ticket [bb3a86e890c8e96ab] */
-  assert( ArraySize(aSyscall)==27 );
+  assert( ArraySize(aSyscall)==28 );
 
   /* Register all VFSes defined in the aVfs[] array */
   for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){