]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add support for Cygwin when handling temporary file names. Improve error codes and...
authormistachkin <mistachkin@noemail.net>
Fri, 30 Aug 2013 21:52:38 +0000 (21:52 +0000)
committermistachkin <mistachkin@noemail.net>
Fri, 30 Aug 2013 21:52:38 +0000 (21:52 +0000)
FossilOrigin-Name: a411df725153119acb3bcf44fb71deecaa307887

manifest
manifest.uuid
src/main.c
src/os_unix.c
src/os_win.c
src/sqlite.h.in

index 9b210d3d889806b93322da2821f6bbd38ece0645..40a9efb0be69233a0295b92beb84d25fb1344bbe 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\scompiler\swarnings\sin\sanalyze.c.
-D 2013-08-30T20:19:52.698
+C Add\ssupport\sfor\sCygwin\swhen\shandling\stemporary\sfile\snames.\s\sImprove\serror\scodes\sand\sdiagnostic\smessages\sfor\stemporary\sfile\sname\shandling\son\sWindows.\s\sRename\swinConvertUtf8Filename\sto\swinConvertFromUtf8Filename.\s\sImprove\splacement\sand\scomments\sfor\sforward\sfunction\sdeclarations.
+D 2013-08-30T21:52:38.235
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -185,7 +185,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
 F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
 F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303
-F src/main.c dc02c7c118d58049e0cccc6c9c47c0a4d3e2bcda
+F src/main.c c4c781b06faa2ce4040c32a75fd931a07ba7054e
 F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6
 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
 F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa
@@ -202,8 +202,8 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
 F src/os.c b4ad71336fd96f97776f75587cd9e8218288f5be
 F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
-F src/os_unix.c 7d5f3c51db561804e3ff3d47970a58bc6ea4d662
-F src/os_win.c 26d752736dff0c7e4e384ab65b353cce1e7e19c5
+F src/os_unix.c 243fb37f47dc072fc59839ea241ff0a17c8d76e6
+F src/os_win.c 8e87c2718975bc3cd8d86bf3ff2cc3bbafbc7eaf
 F src/pager.c 2aa4444ffe86e9282d03bc349a4a5e49bd77c0e8
 F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c
 F src/parse.y 27c6b4138497d6f8360ba7847da6ed48033f957f
@@ -218,7 +218,7 @@ F src/resolve.c 9d53899cc6e1f4ec0b4632d07e97d57827bf63b9
 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
 F src/select.c 8b148eb851f384412aea57091659d14b369918ca
 F src/shell.c dbe064d404bb497acd8a44c066cd6b8460a71236
-F src/sqlite.h.in bd1451ba1ab681022a53bccc3c39580ba094a3ff
+F src/sqlite.h.in ec40aa958a270416fb04b4f72210357bf163d2c5
 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
 F src/sqliteInt.h 600086a5082e2291b0aeeefcfbb546f2bbda67b2
@@ -1109,7 +1109,10 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P dbc31750440226702fbf88f1bf6140ef403c9be1
-R 5df52e9a380e1241cf1df8d1d5fbe7ea
-U dan
-Z 33fcbfc1bf7d299e3e7e4e929460c0cd
+P 5bbd2ccb3d2d6286fd667dac2ab658d6b89640a6
+R 72dd46cadd0f990a967d544f6edf59de
+T *branch * cygwinTempPath
+T *sym-cygwinTempPath *
+T -sym-trunk *
+U mistachkin
+Z 23133362076223f26c27390373169480
index e0a1d443370aeef354e85dda2542d3e94d6176a8..44a442d40d1d3ce55aedfee2cdbfa65e5c9a1db8 100644 (file)
@@ -1 +1 @@
-5bbd2ccb3d2d6286fd667dac2ab658d6b89640a6
\ No newline at end of file
+a411df725153119acb3bcf44fb71deecaa307887
\ No newline at end of file
index 7e817e5953743c1b6e053012c16ec19dea852b97..4697009666bb9cace33aa190856ae8b8794fb767 100644 (file)
@@ -1107,6 +1107,7 @@ const char *sqlite3ErrName(int rc){
       case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break;
       case SQLITE_IOERR_MMAP:         zName = "SQLITE_IOERR_MMAP";        break;
       case SQLITE_IOERR_GETTEMPPATH:  zName = "SQLITE_IOERR_GETTEMPPATH"; break;
+      case SQLITE_IOERR_CONVPATH:     zName = "SQLITE_IOERR_CONVPATH";    break;
       case SQLITE_CORRUPT:            zName = "SQLITE_CORRUPT";           break;
       case SQLITE_CORRUPT_VTAB:       zName = "SQLITE_CORRUPT_VTAB";      break;
       case SQLITE_NOTFOUND:           zName = "SQLITE_NOTFOUND";          break;
@@ -1115,6 +1116,7 @@ const char *sqlite3ErrName(int rc){
       case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break;
       case SQLITE_CANTOPEN_ISDIR:     zName = "SQLITE_CANTOPEN_ISDIR";    break;
       case SQLITE_CANTOPEN_FULLPATH:  zName = "SQLITE_CANTOPEN_FULLPATH"; break;
+      case SQLITE_CANTOPEN_CONVPATH:  zName = "SQLITE_CANTOPEN_CONVPATH"; break;
       case SQLITE_PROTOCOL:           zName = "SQLITE_PROTOCOL";          break;
       case SQLITE_EMPTY:              zName = "SQLITE_EMPTY";             break;
       case SQLITE_SCHEMA:             zName = "SQLITE_SCHEMA";            break;
index 797ace031d073f3248742d78af9c2abbee2a4429..cd8cec0046b69ad298bc791ff77e4f77c708f376 100644 (file)
@@ -5338,6 +5338,7 @@ static int fillInUnixFile(
 */
 static const char *unixTempFileDir(void){
   static const char *azDirs[] = {
+     0,
      0,
      0,
      "/var/tmp",
@@ -5350,7 +5351,8 @@ static const char *unixTempFileDir(void){
   const char *zDir = 0;
 
   azDirs[0] = sqlite3_temp_directory;
-  if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
+  if( !azDirs[1] ) azDirs[1] = getenv("SQLITE_TMPDIR");
+  if( !azDirs[2] ) azDirs[2] = getenv("TMPDIR");
   for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
     if( zDir==0 ) continue;
     if( osStat(zDir, &buf) ) continue;
index 89e64aa431d7c88ec0748b6059a5988496e8f405..ab33b52a4767fda6571a18c2d1bf19baccc9740d 100644 (file)
@@ -161,7 +161,7 @@ WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
 #endif
 
 #ifndef SQLITE_OMIT_WAL
-/* Forward references */
+/* Forward references to structures used for WAL */
 typedef struct winShm winShm;           /* A connection to shared-memory */
 typedef struct winShmNode winShmNode;   /* A region of shared-memory */
 #endif
@@ -2132,7 +2132,8 @@ static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){
 }
 
 #if SQLITE_MAX_MMAP_SIZE>0
-/* Forward references to VFS methods */
+/* Forward references to VFS helper methods used for memory mapped files */
+static int winMapfile(winFile*, sqlite3_int64);
 static int winUnmapfile(winFile*);
 #endif
 
@@ -2870,11 +2871,10 @@ static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){
   }
 }
 
-/* Forward declaration */
+/* Forward references to VFS helper methods used for temporary files */
 static int winGetTempname(sqlite3_vfs *, char **);
-#if SQLITE_MAX_MMAP_SIZE>0
-static int winMapfile(winFile*, sqlite3_int64);
-#endif
+static int winIsDir(const void *);
+static BOOL winIsDriveLetterAndColon(const char *);
 
 /*
 ** Control and query of the open file handle.
@@ -3909,13 +3909,32 @@ static const sqlite3_io_methods winIoMethod = {
 ** sqlite3_vfs object.
 */
 
+/*
+** Convert a filename from whatever the underlying operating system
+** supports for filenames into UTF-8.  Space to hold the result is
+** obtained from malloc and must be freed by the calling function.
+*/
+static char *winConvertToUtf8Filename(const void *zFilename){
+  char *zConverted = 0;
+  if( osIsNT() ){
+    zConverted = winUnicodeToUtf8(zFilename);
+  }
+#ifdef SQLITE_WIN32_HAS_ANSI
+  else{
+    zConverted = sqlite3_win32_mbcs_to_utf8(zFilename);
+  }
+#endif
+  /* caller will handle out of memory */
+  return zConverted;
+}
+
 /*
 ** Convert a UTF-8 filename into whatever form the underlying
 ** operating system wants filenames in.  Space to hold the result
 ** is obtained from malloc and must be freed by the calling
 ** function.
 */
-static void *winConvertUtf8Filename(const char *zFilename){
+static void *winConvertFromUtf8Filename(const char *zFilename){
   void *zConverted = 0;
   if( osIsNT() ){
     zConverted = winUtf8ToUnicode(zFilename);
@@ -3980,7 +3999,90 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
                      winEndsInDirSep(sqlite3_temp_directory) ? "" :
                      winGetDirDep());
   }
-#if !SQLITE_OS_WINRT
+#if defined(__CYGWIN__)
+  else{
+    static const char *azDirs[] = {
+       0, /* getenv("SQLITE_TMPDIR") */
+       0, /* getenv("TMPDIR") */
+       0, /* getenv("TMP") */
+       0, /* getenv("TEMP") */
+       0, /* getenv("USERPROFILE") */
+       "/var/tmp",
+       "/usr/tmp",
+       "/tmp",
+       0        /* List terminator */
+    };
+    unsigned int i;
+    const char *zDir = 0;
+
+    if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
+    if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
+    if( !azDirs[2] ) azDirs[2] = getenv("TMP");
+    if( !azDirs[3] ) azDirs[3] = getenv("TEMP");
+    if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE");
+    for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
+      void *zConverted;
+      if( zDir==0 ) continue;
+      /* If the path starts with a drive letter followed by the colon
+      ** character, assume it is already a native Win32 path; otherwise,
+      ** it must be converted to a native Win32 path prior via the Cygwin
+      ** API prior to using it.
+      */
+      if( winIsDriveLetterAndColon(zDir) ){
+        zConverted = winConvertFromUtf8Filename(zDir);
+        if( !zConverted ){
+          OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+          return SQLITE_IOERR_NOMEM;
+        }
+        if( winIsDir(zConverted) ){
+          sqlite3_snprintf(nBuf-30, zBuf, "%s", zDir);
+          sqlite3_free(zConverted);
+          break;
+        }
+        sqlite3_free(zConverted);
+      }else{
+        zConverted = sqlite3MallocZero( nBuf+1 );
+        if( !zConverted ){
+          OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+          return SQLITE_IOERR_NOMEM;
+        }
+        if( cygwin_conv_path(
+                osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir,
+                zConverted, nBuf+1)<0 ){
+          sqlite3_free(zConverted);
+          winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno,
+                      "cygwin_conv_path", zDir);
+          OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n"));
+          return SQLITE_IOERR_CONVPATH;
+        }
+        if( winIsDir(zConverted) ){
+          /* At this point, we know the candidate directory exists and should
+          ** be used.  However, we may need to convert the string containing
+          ** its name into UTF-8 (i.e. if it is UTF-16 right now).
+          */
+          if( osIsNT() ){
+            char *zUtf8 = winUnicodeToUtf8(zConverted);
+            if( !zUtf8 ){
+              sqlite3_free(zConverted);
+              OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+              return SQLITE_IOERR_NOMEM;
+            }
+            sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8);
+            sqlite3_free(zUtf8);
+            sqlite3_free(zConverted);
+            break;
+          }else{
+            sqlite3_snprintf(nBuf-30, zBuf, "%s", zConverted);
+            sqlite3_free(zConverted);
+            break;
+          }
+        }
+        sqlite3_free(zConverted);
+      }
+      break;
+    }
+  }
+#elif !SQLITE_OS_WINRT && !defined(__CYGWIN__)
   else if( osIsNT() ){
     char *zMulti;
     LPWSTR zWidePath = sqlite3MallocZero( nBuf*sizeof(WCHAR) );
@@ -3992,6 +4094,8 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
     if( osGetTempPathW(nBuf, zWidePath)==0 ){
       sqlite3_free(zWidePath);
       sqlite3_free(zBuf);
+      winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
+                  "winGetTempname", 0);
       OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
       return SQLITE_IOERR_GETTEMPPATH;
     }
@@ -4018,6 +4122,8 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
     }
     if( osGetTempPathA(nBuf, zMbcsPath)==0 ){
       sqlite3_free(zBuf);
+      winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
+                  "winGetTempname", 0);
       OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
       return SQLITE_IOERR_GETTEMPPATH;
     }
@@ -4198,7 +4304,7 @@ static int winOpen(
        zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 );
 
   /* Convert the filename to the system encoding. */
-  zConverted = winConvertUtf8Filename(zUtf8Name);
+  zConverted = winConvertFromUtf8Filename(zUtf8Name);
   if( zConverted==0 ){
     sqlite3_free(zTmpname);
     OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name));
@@ -4399,7 +4505,7 @@ static int winDelete(
   SimulateIOError(return SQLITE_IOERR_DELETE);
   OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir));
 
-  zConverted = winConvertUtf8Filename(zFilename);
+  zConverted = winConvertFromUtf8Filename(zFilename);
   if( zConverted==0 ){
     OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
     return SQLITE_IOERR_NOMEM;
@@ -4508,7 +4614,7 @@ static int winAccess(
   OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n",
            zFilename, flags, pResOut));
 
-  zConverted = winConvertUtf8Filename(zFilename);
+  zConverted = winConvertFromUtf8Filename(zFilename);
   if( zConverted==0 ){
     OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
     return SQLITE_IOERR_NOMEM;
@@ -4566,6 +4672,15 @@ static int winAccess(
   return SQLITE_OK;
 }
 
+/*
+** Returns non-zero if the specified path name starts with a drive letter
+** followed by a colon character.
+*/
+static BOOL winIsDriveLetterAndColon(
+  const char *zPathname
+){
+  return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' );
+}
 
 /*
 ** Returns non-zero if the specified path name should be used verbatim.  If
@@ -4593,7 +4708,7 @@ static BOOL winIsVerbatimPathname(
   ** attempt to treat it as a relative path name (i.e. they should simply use
   ** it verbatim).
   */
-  if ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ){
+  if ( winIsDriveLetterAndColon(zPathname) ){
     return TRUE;
   }
 
@@ -4634,19 +4749,19 @@ static int winFullPathname(
     }
     if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
                          pVfs->mxPathname+1)<0 ){
-      winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path",
+      winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, "winFullPathname",
                   zRelative);
       sqlite3_free(zOut);
-      return SQLITE_CANTOPEN_FULLPATH;
+      return SQLITE_CANTOPEN_CONVPATH;
     }
     sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s",
                      sqlite3_data_directory, winGetDirDep(), zOut);
     sqlite3_free(zOut);
   }else{
     if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){
-      winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path",
+      winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, "winFullPathname",
                   zRelative);
-      return SQLITE_CANTOPEN_FULLPATH;
+      return SQLITE_CANTOPEN_CONVPATH;
     }
   }
   return SQLITE_OK;
@@ -4700,7 +4815,7 @@ static int winFullPathname(
                      sqlite3_data_directory, winGetDirDep(), zRelative);
     return SQLITE_OK;
   }
-  zConverted = winConvertUtf8Filename(zRelative);
+  zConverted = winConvertFromUtf8Filename(zRelative);
   if( zConverted==0 ){
     return SQLITE_IOERR_NOMEM;
   }
@@ -4781,7 +4896,7 @@ static int winFullPathname(
 */
 static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
   HANDLE h;
-  void *zConverted = winConvertUtf8Filename(zFilename);
+  void *zConverted = winConvertFromUtf8Filename(zFilename);
   UNUSED_PARAMETER(pVfs);
   if( zConverted==0 ){
     return 0;
index fc76029bcba4d96e393f9b56af40282213197ddb..1e5a3f22a4e84443e79de8e0a81ed33a62a1d3c5 100644 (file)
@@ -474,12 +474,14 @@ int sqlite3_exec(
 #define SQLITE_IOERR_DELETE_NOENT      (SQLITE_IOERR | (23<<8))
 #define SQLITE_IOERR_MMAP              (SQLITE_IOERR | (24<<8))
 #define SQLITE_IOERR_GETTEMPPATH       (SQLITE_IOERR | (25<<8))
+#define SQLITE_IOERR_CONVPATH          (SQLITE_IOERR | (26<<8))
 #define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
 #define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
 #define SQLITE_BUSY_SNAPSHOT           (SQLITE_BUSY   |  (2<<8))
 #define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
 #define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
 #define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))
+#define SQLITE_CANTOPEN_CONVPATH       (SQLITE_CANTOPEN | (4<<8))
 #define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
 #define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
 #define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))