/ Check-in [830629d3]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merge the Cygwin directory separator fix. Also fix a C++-ism in the multiplexor code so that it will compile on MSVC.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 830629d31d171155d90ff87ae8e70094d17bb2d3
User & Date: drh 2013-11-08 17:03:50
Context
2013-11-08
17:13
Fix harmless compiler warnings. check-in: 0077c077 user: drh tags: trunk
17:03
Merge the Cygwin directory separator fix. Also fix a C++-ism in the multiplexor code so that it will compile on MSVC. check-in: 830629d3 user: drh tags: trunk
16:54
Performance improvement: Avoid unnecessary seeks on REPLACE INTO for a WITHOUT ROWID table. check-in: fd11afa5 user: drh tags: trunk
2013-11-07
22:11
Fix temporary directory separator handling for Cygwin. Closed-Leaf check-in: 9d870d5f user: mistachkin tags: cygDirSep
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os_win.c.

   113    113   ** [sometimes] not used by the code (e.g. via conditional compilation).
   114    114   */
   115    115   #ifndef UNUSED_VARIABLE_VALUE
   116    116   #  define UNUSED_VARIABLE_VALUE(x) (void)(x)
   117    117   #endif
   118    118   
   119    119   /*
   120         -** Returns the string that should be used as the directory separator.
          120  +** Returns the character that should be used as the directory separator.
   121    121   */
   122         -#ifndef winGetDirDep
   123         -#  ifdef __CYGWIN__
   124         -#    define winGetDirDep()              "/"
   125         -#  else
   126         -#    define winGetDirDep()              "\\"
   127         -#  endif
          122  +#ifndef winGetDirSep
          123  +#  define winGetDirSep()                '\\'
   128    124   #endif
   129    125   
   130    126   /*
   131    127   ** Do we need to manually define the Win32 file mapping APIs for use with WAL
   132    128   ** mode (e.g. these APIs are available in the Windows CE SDK; however, they
   133    129   ** are not present in the header file)?
   134    130   */
................................................................................
  3986   3982   #endif
  3987   3983     /* caller will handle out of memory */
  3988   3984     return zConverted;
  3989   3985   }
  3990   3986   
  3991   3987   /*
  3992   3988   ** This function returns non-zero if the specified UTF-8 string buffer
  3993         -** ends with a directory separator character.
         3989  +** ends with a directory separator character or one was successfully
         3990  +** added to it.
  3994   3991   */
  3995         -static int winEndsInDirSep(char *zBuf){
         3992  +static int winMakeEndInDirSep(int nBuf, char *zBuf){
  3996   3993     if( zBuf ){
  3997   3994       int nLen = sqlite3Strlen30(zBuf);
  3998         -    return nLen>0 && winIsDirSep(zBuf[nLen-1]);
         3995  +    if( nLen>0 ){
         3996  +      if( winIsDirSep(zBuf[nLen-1]) ){
         3997  +        return 1;
         3998  +      }else if( nLen+1<nBuf ){
         3999  +        zBuf[nLen] = winGetDirSep();
         4000  +        zBuf[nLen+1] = '\0';
         4001  +        return 1;
         4002  +      }
         4003  +    }
  3999   4004     }
  4000   4005     return 0;
  4001   4006   }
  4002   4007   
  4003   4008   /*
  4004   4009   ** Create a temporary file name and store the resulting pointer into pzBuf.
  4005   4010   ** The pointer returned in pzBuf must be freed via sqlite3_free().
................................................................................
  4019   4024     */
  4020   4025     SimulateIOError( return SQLITE_IOERR );
  4021   4026   
  4022   4027     /* Allocate a temporary buffer to store the fully qualified file
  4023   4028     ** name for the temporary file.  If this fails, we cannot continue.
  4024   4029     */
  4025   4030     nBuf = pVfs->mxPathname;
  4026         -  zBuf = sqlite3MallocZero( nBuf+2 );
         4031  +  zBuf = sqlite3MallocZero( nBuf+3 );
  4027   4032     if( !zBuf ){
  4028   4033       OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4029   4034       return SQLITE_IOERR_NOMEM;
  4030   4035     }
  4031   4036   
  4032   4037     /* Figure out the effective temporary directory.  First, check if one
  4033   4038     ** has been explicitly set by the application; otherwise, use the one
  4034   4039     ** configured by the operating system.
  4035   4040     */
  4036   4041     assert( nBuf>30 );
  4037   4042     if( sqlite3_temp_directory ){
  4038         -    sqlite3_snprintf(nBuf-30, zBuf, "%s%s", sqlite3_temp_directory,
  4039         -                     winEndsInDirSep(sqlite3_temp_directory) ? "" :
  4040         -                     winGetDirDep());
         4043  +    sqlite3_snprintf(nBuf-30, zBuf, "%s", sqlite3_temp_directory);
         4044  +    winMakeEndInDirSep(nBuf-30, zBuf);
  4041   4045     }
  4042   4046   #if defined(__CYGWIN__)
  4043   4047     else{
  4044   4048       static const char *azDirs[] = {
  4045   4049          0, /* getenv("SQLITE_TMPDIR") */
  4046   4050          0, /* getenv("TMPDIR") */
  4047   4051          0, /* getenv("TMP") */
................................................................................
  4062   4066       if( !azDirs[3] ) azDirs[3] = getenv("TEMP");
  4063   4067       if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE");
  4064   4068       for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
  4065   4069         void *zConverted;
  4066   4070         if( zDir==0 ) continue;
  4067   4071         /* If the path starts with a drive letter followed by the colon
  4068   4072         ** character, assume it is already a native Win32 path; otherwise,
  4069         -      ** it must be converted to a native Win32 path prior via the Cygwin
  4070         -      ** API prior to using it.
         4073  +      ** it must be converted to a native Win32 path via the Cygwin API
         4074  +      ** prior to using it.
  4071   4075         */
  4072   4076         if( winIsDriveLetterAndColon(zDir) ){
  4073   4077           zConverted = winConvertFromUtf8Filename(zDir);
  4074   4078           if( !zConverted ){
  4075   4079             sqlite3_free(zBuf);
  4076   4080             OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4077   4081             return SQLITE_IOERR_NOMEM;
  4078   4082           }
  4079   4083           if( winIsDir(zConverted) ){
  4080   4084             sqlite3_snprintf(nBuf-30, zBuf, "%s", zDir);
         4085  +          winMakeEndInDirSep(nBuf-30, zBuf);
  4081   4086             sqlite3_free(zConverted);
  4082   4087             break;
  4083   4088           }
  4084   4089           sqlite3_free(zConverted);
  4085   4090         }else{
  4086   4091           zConverted = sqlite3MallocZero( nBuf+1 );
  4087   4092           if( !zConverted ){
................................................................................
  4108   4113               if( !zUtf8 ){
  4109   4114                 sqlite3_free(zConverted);
  4110   4115                 sqlite3_free(zBuf);
  4111   4116                 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4112   4117                 return SQLITE_IOERR_NOMEM;
  4113   4118               }
  4114   4119               sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8);
         4120  +            winMakeEndInDirSep(nBuf-30, zBuf);
  4115   4121               sqlite3_free(zUtf8);
  4116   4122               sqlite3_free(zConverted);
  4117   4123               break;
  4118   4124             }else{
  4119   4125               sqlite3_snprintf(nBuf-30, zBuf, "%s", zConverted);
         4126  +            winMakeEndInDirSep(nBuf-30, zBuf);
  4120   4127               sqlite3_free(zConverted);
  4121   4128               break;
  4122   4129             }
  4123   4130           }
  4124   4131           sqlite3_free(zConverted);
  4125   4132         }
  4126   4133       }
................................................................................
  4140   4147         OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
  4141   4148         return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
  4142   4149                            "winGetTempname1", 0);
  4143   4150       }
  4144   4151       zMulti = winUnicodeToUtf8(zWidePath);
  4145   4152       if( zMulti ){
  4146   4153         sqlite3_snprintf(nBuf-30, zBuf, "%s", zMulti);
         4154  +      winMakeEndInDirSep(nBuf-30, zBuf);
  4147   4155         sqlite3_free(zMulti);
  4148   4156         sqlite3_free(zWidePath);
  4149   4157       }else{
  4150   4158         sqlite3_free(zWidePath);
  4151   4159         sqlite3_free(zBuf);
  4152   4160         OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4153   4161         return SQLITE_IOERR_NOMEM;
................................................................................
  4167   4175         OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
  4168   4176         return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
  4169   4177                            "winGetTempname2", 0);
  4170   4178       }
  4171   4179       zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
  4172   4180       if( zUtf8 ){
  4173   4181         sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8);
         4182  +      winMakeEndInDirSep(nBuf-30, zBuf);
  4174   4183         sqlite3_free(zUtf8);
  4175   4184       }else{
  4176   4185         sqlite3_free(zBuf);
  4177   4186         OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4178   4187         return SQLITE_IOERR_NOMEM;
  4179   4188       }
  4180   4189     }
................................................................................
  4788   4797       }
  4789   4798       if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
  4790   4799                            pVfs->mxPathname+1)<0 ){
  4791   4800         sqlite3_free(zOut);
  4792   4801         return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
  4793   4802                            "winFullPathname1", zRelative);
  4794   4803       }
  4795         -    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s",
  4796         -                     sqlite3_data_directory, winGetDirDep(), zOut);
         4804  +    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
         4805  +                     sqlite3_data_directory, winGetDirSep(), zOut);
  4797   4806       sqlite3_free(zOut);
  4798   4807     }else{
  4799   4808       if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){
  4800   4809         return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
  4801   4810                            "winFullPathname2", zRelative);
  4802   4811       }
  4803   4812     }
................................................................................
  4811   4820     if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
  4812   4821       /*
  4813   4822       ** NOTE: We are dealing with a relative path name and the data
  4814   4823       **       directory has been set.  Therefore, use it as the basis
  4815   4824       **       for converting the relative path name to an absolute
  4816   4825       **       one by prepending the data directory and a backslash.
  4817   4826       */
  4818         -    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s",
  4819         -                     sqlite3_data_directory, winGetDirDep(), zRelative);
         4827  +    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
         4828  +                     sqlite3_data_directory, winGetDirSep(), zRelative);
  4820   4829     }else{
  4821   4830       sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative);
  4822   4831     }
  4823   4832     return SQLITE_OK;
  4824   4833   #endif
  4825   4834   
  4826   4835   #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
................................................................................
  4844   4853     if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
  4845   4854       /*
  4846   4855       ** NOTE: We are dealing with a relative path name and the data
  4847   4856       **       directory has been set.  Therefore, use it as the basis
  4848   4857       **       for converting the relative path name to an absolute
  4849   4858       **       one by prepending the data directory and a backslash.
  4850   4859       */
  4851         -    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s",
  4852         -                     sqlite3_data_directory, winGetDirDep(), zRelative);
         4860  +    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
         4861  +                     sqlite3_data_directory, winGetDirSep(), zRelative);
  4853   4862       return SQLITE_OK;
  4854   4863     }
  4855   4864     zConverted = winConvertFromUtf8Filename(zRelative);
  4856   4865     if( zConverted==0 ){
  4857   4866       return SQLITE_IOERR_NOMEM;
  4858   4867     }
  4859   4868     if( osIsNT() ){

Changes to src/test_multiplex.c.

   764    764         rc = SQLITE_IOERR_READ;
   765    765       }else{
   766    766         rc = pSubOpen->pMethods->xRead(pSubOpen, pBuf, iAmt, iOfst);
   767    767       }
   768    768     }else{
   769    769       while( iAmt > 0 ){
   770    770         int i = (int)(iOfst / pGroup->szChunk);
          771  +      sqlite3_file *pSubOpen;
   771    772         if( nMutex==0 ){ multiplexEnter(); nMutex++; }
   772         -      sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL, 1);
          773  +      pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL, 1);
   773    774         multiplexLeave(); nMutex--;
   774    775         if( pSubOpen ){
   775    776           int extra = ((int)(iOfst % pGroup->szChunk) + iAmt) - pGroup->szChunk;
   776    777           if( extra<0 ) extra = 0;
   777    778           iAmt -= extra;
   778    779           rc = pSubOpen->pMethods->xRead(pSubOpen, pBuf, iAmt,
   779    780                                          iOfst % pGroup->szChunk);