pragma database_list returns win32 paths on Cygwin

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

pragma database_list returns win32 paths on Cygwin

Jan Nijtmans
Compiling fossil trunk as-is on Cygwin gives:

    $ ./fossil status
    repository:   /cygdrive/c/fossil/fossil.fossil
    local-root:   /Localdata/workspace/fossil/
    ......
    $ ./fossil sqlite3
    SQLite version 3.8.3.1 2014-02-11 14:52:19
    Enter ".help" for usage hints.
    sqlite> .databases
    seq  name             file
    ---  ---------------
----------------------------------------------------------
    0    main             C:\fossil\fossil.fossil
    sqlite> pragma database_list;
    0|main|C:\fossil\fossil.fossil
    sqlite> .exit

Note that the repository name is reported by fossil as Cygwin path
(which it really is!) but SQLite reports it as win32 path.

This is not as expected, as the fact that the win32 VFS uses win32
paths internally should be transparent. See:
   <http://www.sqlite.org/pragma.html#pragma_database_list>
Workaround: compile fossil with --disable-internal-sqlite
(Cygwin's SQLite fork has this problem fixed already, the suggested
winConvertFromUtf8Filename modification is derived from this fix).

Suggested patch below. Using this modified winConvertFromUtf8Filename()
allows various code simplifications in other places, but that's for another day.

Regards,
         Jan Nijtmans

Index: src/os_win.c
==================================================================
--- src/os_win.c
+++ src/os_win.c
@@ -4127,14 +4127,51 @@
 /*
 ** 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.
+**
+** On Cygwin 1.7 and higher, 3 possible input forms are accepted:
+** - If the filename starts with "<drive>:/" or "<drive>:\",
+**   it is converted to UTF-16 as-is.
+** - If the filename contains '/', it is assumed to be a
+**   Cygwin absolute path, it is converted to a win32
+**   absolute path in UTF-16.
+** - Otherwise it must be a filename only, the win32 filename
+**   is returned in UTF-16.
+** Note: The function cygwin_conv_path does not exist in
+**   Cygwin 1.5. Cygwin 1.7 does not run in Windows 95/98/ME.
+**   Therefore the !osIsNT() case does not need special handling.
+** Note 2: If the function cygwin_conv_path() fails, only
+**   UTF-8 -> UTF-16 conversion will be done. This can only
+**   happen when the file path >32k, in which case winUtf8ToUnicode()
+**   will fail too.
 */
 static void *winConvertFromUtf8Filename(const char *zFilename){
   void *zConverted = 0;
   if( osIsNT() ){
+#ifdef __CYGWIN__
+    if( !(winIsDriveLetterAndColon(zFilename)
+        && winIsDirSep(zFilename[2])) ){
+      int nByte;
+      int convertflag = CCP_POSIX_TO_WIN_W;
+      if( !strchr(zFilename, '/') ) convertflag |= CCP_RELATIVE;
+      nByte = cygwin_conv_path(convertflag,
+          zFilename, 0, 0);
+      if( nByte>0 ){
+        zConverted = sqlite3MallocZero(nByte);
+        if ( zConverted==0 ){
+          return zConverted;
+        }
+        if( cygwin_conv_path(convertflag, zFilename,
+                             zConverted, nByte)==0 ){
+          return zConverted;
+        }
+        sqlite3_free(zConverted);
+      }
+    }
+#endif
     zConverted = winUtf8ToUnicode(zFilename);
   }
 #ifdef SQLITE_WIN32_HAS_ANSI
   else{
     zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);
@@ -4961,11 +4998,13 @@

 #if defined(__CYGWIN__)
   SimulateIOError( return SQLITE_ERROR );
   UNUSED_PARAMETER(nFull);
   assert( nFull>=pVfs->mxPathname );
-  if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
+  if( winIsDirSep(zRelative[0]) ){
+    sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative);
+  }else if( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
     /*
     ** NOTE: We are dealing with a relative path name and the data
     **       directory has been set.  Therefore, use it as the basis
     **       for converting the relative path name to an absolute
     **       one by prepending the data directory and a slash.
_______________________________________________
sqlite-users mailing list
[hidden email]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users