Fossil

Check-in [963de841f2]
Login

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

Overview
Comment:Refactor the previous commit by adding a wrapper for `freopen()', and use the Cygwin-aware routines to convert path names to/from UTF-16.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | win32-temppath-mojibake
Files: files | file ages | folders
SHA3-256: 963de841f2e2dfd54d977f745eba44c4df9d6b9f1c3b50740d2f7714ed10b6e1
User & Date: florian 2021-08-31 10:39:00.000
Context
2021-09-03
12:07
On windows, make sure temporary pathnames containing non-ASCII characters are handled correctly. Add the fossil_freopen() wrapper around freopen() for portability. check-in: f48e48f664 user: drh tags: trunk
2021-08-31
10:39
Refactor the previous commit by adding a wrapper for `freopen()', and use the Cygwin-aware routines to convert path names to/from UTF-16. Closed-Leaf check-in: 963de841f2 user: florian tags: win32-temppath-mojibake
07:01
On Windows, make sure temporary path names containing non-ASCII characters are accessible, for example if the default temporary path "C:\Users\«Username»\AppData\Local\Temp" contains a user name with extended characters, of if the %TEMP% environment variable points to a directory name with extended characters. check-in: 102339828b user: florian tags: win32-temppath-mojibake
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/diffcmd.c.
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
** hold the result.  Make arrangements to delete that temporary
** file if the diff is interrupted.
**
** For --browser and --webpage, output the HTML header.
*/
void diff_begin(u64 diffFlags){
  if( (diffFlags & DIFF_BROWSER)!=0 ){
#ifdef _WIN32
    LPWSTR tempDiffFilenameW;
#endif
    tempDiffFilename = fossil_temp_filename();
    tempDiffFilename = sqlite3_mprintf("%z.html", tempDiffFilename);
#ifndef _WIN32
    diffOut = freopen(tempDiffFilename,"wb",stdout);
#else
    tempDiffFilenameW = fossil_utf8_to_unicode(tempDiffFilename);
    diffOut = _wfreopen(tempDiffFilenameW,L"wb",stdout);
    fossil_unicode_free(tempDiffFilenameW);
#endif
    if( diffOut==0 ){
      fossil_fatal("unable to create temporary file \"%s\"", 
                   tempDiffFilename);
    }
#ifndef _WIN32
    signal(SIGINT, diff_www_interrupt);
#else







<
<
<


<
|
<
<
<
<
<







278
279
280
281
282
283
284



285
286

287





288
289
290
291
292
293
294
** hold the result.  Make arrangements to delete that temporary
** file if the diff is interrupted.
**
** For --browser and --webpage, output the HTML header.
*/
void diff_begin(u64 diffFlags){
  if( (diffFlags & DIFF_BROWSER)!=0 ){



    tempDiffFilename = fossil_temp_filename();
    tempDiffFilename = sqlite3_mprintf("%z.html", tempDiffFilename);

    diffOut = fossil_freopen(tempDiffFilename,"wb",stdout);





    if( diffOut==0 ){
      fossil_fatal("unable to create temporary file \"%s\"", 
                   tempDiffFilename);
    }
#ifndef _WIN32
    signal(SIGINT, diff_www_interrupt);
#else
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
      fossil_print("<script>\n%s</script>\n", zJs);
    }
    fossil_print("%s", zWebpageEnd);
  }
  if( (diffFlags & DIFF_BROWSER)!=0 && nErr==0 ){
    char *zCmd = mprintf("%s %$", fossil_web_browser(), tempDiffFilename);
    fclose(diffOut);
    diffOut = freopen(NULL_DEVICE, "wb", stdout);
    fossil_system(zCmd);
    fossil_free(zCmd);
    diffOut = 0;
    sqlite3_sleep(FOSSIL_BROWSER_DIFF_DELAY);
    file_delete(tempDiffFilename);
    sqlite3_free(tempDiffFilename);
    tempDiffFilename = 0;







|







324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
      fossil_print("<script>\n%s</script>\n", zJs);
    }
    fossil_print("%s", zWebpageEnd);
  }
  if( (diffFlags & DIFF_BROWSER)!=0 && nErr==0 ){
    char *zCmd = mprintf("%s %$", fossil_web_browser(), tempDiffFilename);
    fclose(diffOut);
    diffOut = fossil_freopen(NULL_DEVICE, "wb", stdout);
    fossil_system(zCmd);
    fossil_free(zCmd);
    diffOut = 0;
    sqlite3_sleep(FOSSIL_BROWSER_DIFF_DELAY);
    file_delete(tempDiffFilename);
    sqlite3_free(tempDiffFilename);
    tempDiffFilename = 0;
Changes to src/file.c.
2158
2159
2160
2161
2162
2163
2164
















2165
2166
2167
2168
2169
2170
2171
  fossil_path_free(uName);
  fossil_unicode_free(uMode);
#else
  FILE *f = fopen(zName, zMode);
#endif
  return f;
}

















/*
** Works like fclose() except that:
**
** 1) is a no-op if f is 0 or if it is stdin.
**
** 2) If f is one of (stdout, stderr), it is flushed but not closed.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
  fossil_path_free(uName);
  fossil_unicode_free(uMode);
#else
  FILE *f = fopen(zName, zMode);
#endif
  return f;
}

/*
** Wrapper for freopen() that understands UTF8 arguments.
*/
FILE *fossil_freopen(const char *zName, const char *zMode, FILE *stream){
#ifdef _WIN32
  wchar_t *uMode = fossil_utf8_to_unicode(zMode);
  wchar_t *uName = fossil_utf8_to_path(zName, 0);
  FILE *f = _wfreopen(uName, uMode, stream);
  fossil_path_free(uName);
  fossil_unicode_free(uMode);
#else
  FILE *f = freopen(zName, zMode, stream);
#endif
  return f;
}

/*
** Works like fclose() except that:
**
** 1) is a no-op if f is 0 or if it is stdin.
**
** 2) If f is one of (stdout, stderr), it is flushed but not closed.
Changes to src/util.c.
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
    if( zTFile ) return zTFile;
  }
  sqlite3_randomness(sizeof(r), &r);
#if _WIN32
  cDirSep = '\\';
  dwTempLenW = GetTempPathW(dwTempSizeW, zTempDirW);
  if( dwTempLenW>0 && dwTempLenW<dwTempSizeW
      && ( zTempDirA = fossil_unicode_to_utf8(zTempDirW) )){
    zDir = zTempDirA;
  }else{
    zDir = fossil_getenv("LOCALAPPDATA");
    if( zDir==0 ) zDir = ".";
  }
#else
  for(i=0; i<sizeof(azTmp)/sizeof(azTmp[0]); i++){







|







669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
    if( zTFile ) return zTFile;
  }
  sqlite3_randomness(sizeof(r), &r);
#if _WIN32
  cDirSep = '\\';
  dwTempLenW = GetTempPathW(dwTempSizeW, zTempDirW);
  if( dwTempLenW>0 && dwTempLenW<dwTempSizeW
      && ( zTempDirA = fossil_path_to_utf8(zTempDirW) )){
    zDir = zTempDirA;
  }else{
    zDir = fossil_getenv("LOCALAPPDATA");
    if( zDir==0 ) zDir = ".";
  }
#else
  for(i=0; i<sizeof(azTmp)/sizeof(azTmp[0]); i++){
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
  cDirSep = '/';
#endif
  nDir = strlen(zDir);
  zSep[1] = 0;
  zSep[0] = (nDir && zDir[nDir-1]==cDirSep) ? 0 : cDirSep;
  zTFile = sqlite3_mprintf("%s%sfossil%016llx%016llx", zDir,zSep,r[0],r[1]);
#ifdef _WIN32
  if( zTempDirA ) fossil_unicode_free(zTempDirA);
#endif
  return zTFile;
}

/*
** Turn memory limits for stack and heap on and off.  The argument
** is true to turn memory limits on and false to turn them off.







|







691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
  cDirSep = '/';
#endif
  nDir = strlen(zDir);
  zSep[1] = 0;
  zSep[0] = (nDir && zDir[nDir-1]==cDirSep) ? 0 : cDirSep;
  zTFile = sqlite3_mprintf("%s%sfossil%016llx%016llx", zDir,zSep,r[0],r[1]);
#ifdef _WIN32
  if( zTempDirA ) fossil_path_free(zTempDirA);
#endif
  return zTFile;
}

/*
** Turn memory limits for stack and heap on and off.  The argument
** is true to turn memory limits on and false to turn them off.