Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Use _wfopen() instead of fopen() on Windows in the CLI. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | cli-stdlib |
Files: | files | file ages | folders |
SHA3-256: |
21a8cac5e9a0d5ead29ca1114be7520d |
User & Date: | drh 2024-09-24 10:30:07.376 |
Context
2024-09-24
| ||
13:46 | Add the sqlite3_stdio.h library for Windows console I/O. (check-in: fcd0ecffc9 user: drh tags: cli-stdlib) | |
10:30 | Use _wfopen() instead of fopen() on Windows in the CLI. (check-in: 21a8cac5e9 user: drh tags: cli-stdlib) | |
09:51 | Always use fputws() for output to a Windows command-line prompt. (check-in: 33950a8c3f user: drh tags: cli-stdlib) | |
Changes
Changes to src/shell.c.in.
︙ | ︙ | |||
339 340 341 342 343 344 345 346 347 348 349 350 351 352 | va_end(ap); } } #else /* library version works for everybody else */ # define cli_fprintf fprintf #endif /* Use console I/O package as a direct INCLUDE. */ #define SQLITE_INTERNAL_LINKAGE static #ifdef SQLITE_SHELL_FIDDLE /* Deselect most features from the console I/O package for Fiddle. */ # define SQLITE_CIO_NO_REDIRECT | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 | va_end(ap); } } #else /* library version works for everybody else */ # define cli_fprintf fprintf #endif #ifdef _WIN32 /* fopen() for windows */ static FILE *cli_fopen(const char *zFilename, const char *zMode){ FILE *fp = 0; wchar_t *b1, *b2; int sz1, sz2; sz1 = (int)strlen(zFilename); sz2 = (int)strlen(zMode); b1 = malloc( (sz1+1)*sizeof(b1[0]) ); b2 = malloc( (sz2+1)*sizeof(b1[0]) ); if( b1 && b2 ){ sz1 = MultiByteToWideChar(CP_UTF8, 0, zFilename, sz1, b1, sz1); b1[sz1] = 0; sz2 = MultiByteToWideChar(CP_UTF8, 0, zMode, sz2, b2, sz2); b2[sz2] = 0; fp = _wfopen(b1, b2); } free(b1); free(b2); return fp; } #else /* library version works for everybody else */ # define cli_fopen fopen #endif /* Use console I/O package as a direct INCLUDE. */ #define SQLITE_INTERNAL_LINKAGE static #ifdef SQLITE_SHELL_FIDDLE /* Deselect most features from the console I/O package for Fiddle. */ # define SQLITE_CIO_NO_REDIRECT |
︙ | ︙ | |||
823 824 825 826 827 828 829 | static FILE * openChrSource(const char *zFile){ #if defined(_WIN32) || defined(WIN32) struct __stat64 x = {0}; # define STAT_CHR_SRC(mode) ((mode & (_S_IFCHR|_S_IFIFO|_S_IFREG))!=0) /* On Windows, open first, then check the stream nature. This order ** is necessary because _stat() and sibs, when checking a named pipe, ** effectively break the pipe as its supplier sees it. */ | | | | 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 | static FILE * openChrSource(const char *zFile){ #if defined(_WIN32) || defined(WIN32) struct __stat64 x = {0}; # define STAT_CHR_SRC(mode) ((mode & (_S_IFCHR|_S_IFIFO|_S_IFREG))!=0) /* On Windows, open first, then check the stream nature. This order ** is necessary because _stat() and sibs, when checking a named pipe, ** effectively break the pipe as its supplier sees it. */ FILE *rv = cli_fopen(zFile, "rb"); if( rv==0 ) return 0; if( _fstat64(_fileno(rv), &x) != 0 || !STAT_CHR_SRC(x.st_mode)){ fclose(rv); rv = 0; } return rv; #else struct stat x = {0}; int rc = stat(zFile, &x); # define STAT_CHR_SRC(mode) (S_ISREG(mode)||S_ISFIFO(mode)||S_ISCHR(mode)) if( rc!=0 ) return 0; if( STAT_CHR_SRC(x.st_mode) ){ return cli_fopen(zFile, "rb"); }else{ return 0; } #endif #undef STAT_CHR_SRC } |
︙ | ︙ | |||
1677 1678 1679 1680 1681 1682 1683 | sqlite3_result_error_nomem(context); return; } } bBin = sqlite3_value_type(argv[0])==SQLITE_BLOB; /* When writing the file to be edited, do \n to \r\n conversions on systems ** that want \r\n line endings */ | | | 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 | sqlite3_result_error_nomem(context); return; } } bBin = sqlite3_value_type(argv[0])==SQLITE_BLOB; /* When writing the file to be edited, do \n to \r\n conversions on systems ** that want \r\n line endings */ f = cli_fopen(zTempFile, bBin ? "wb" : "w"); if( f==0 ){ sqlite3_result_error(context, "edit() cannot open temp file", -1); goto edit_func_end; } sz = sqlite3_value_bytes(argv[0]); if( bBin ){ x = fwrite(sqlite3_value_blob(argv[0]), 1, (size_t)sz, f); |
︙ | ︙ | |||
1708 1709 1710 1711 1712 1713 1714 | } rc = system(zCmd); sqlite3_free(zCmd); if( rc ){ sqlite3_result_error(context, "EDITOR returned non-zero", -1); goto edit_func_end; } | | | 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 | } rc = system(zCmd); sqlite3_free(zCmd); if( rc ){ sqlite3_result_error(context, "EDITOR returned non-zero", -1); goto edit_func_end; } f = cli_fopen(zTempFile, "rb"); if( f==0 ){ sqlite3_result_error(context, "edit() cannot reopen temp file after edit", -1); goto edit_func_end; } fseek(f, 0, SEEK_END); sz = ftell(f); |
︙ | ︙ | |||
3109 3110 3111 3112 3113 3114 3115 | /* ** Attempt to display I/O stats on Linux using /proc/PID/io */ static void displayLinuxIoStats(void){ FILE *in; char z[200]; sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid()); | | | 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 | /* ** Attempt to display I/O stats on Linux using /proc/PID/io */ static void displayLinuxIoStats(void){ FILE *in; char z[200]; sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid()); in = cli_fopen(z, "rb"); if( in==0 ) return; while( cli_fgets(z, sizeof(z), in)!=0 ){ static const struct { const char *zPattern; const char *zDesc; } aTrans[] = { { "rchar: ", "Bytes received by read():" }, |
︙ | ︙ | |||
5166 5167 5168 5169 5170 5171 5172 | ** from the file before the buffer is returned. This byte is not included in ** the final value of (*pnByte), if applicable. ** ** NULL is returned if any error is encountered. The final value of *pnByte ** is undefined in this case. */ static char *readFile(const char *zName, int *pnByte){ | | | 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 | ** from the file before the buffer is returned. This byte is not included in ** the final value of (*pnByte), if applicable. ** ** NULL is returned if any error is encountered. The final value of *pnByte ** is undefined in this case. */ static char *readFile(const char *zName, int *pnByte){ FILE *in = cli_fopen(zName, "rb"); long nIn; size_t nRead; char *pBuf; int rc; if( in==0 ) return 0; rc = fseek(in, 0, SEEK_END); if( rc!=0 ){ |
︙ | ︙ | |||
5256 5257 5258 5259 5260 5261 5262 | ** ** If the file does not exist or is empty but its name looks like a ZIP ** archive and the dfltZip flag is true, then assume it is a ZIP archive. ** Otherwise, assume an ordinary database regardless of the filename if ** the type cannot be determined from content. */ int deduceDatabaseType(const char *zName, int dfltZip){ | | | 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 | ** ** If the file does not exist or is empty but its name looks like a ZIP ** archive and the dfltZip flag is true, then assume it is a ZIP archive. ** Otherwise, assume an ordinary database regardless of the filename if ** the type cannot be determined from content. */ int deduceDatabaseType(const char *zName, int dfltZip){ FILE *f = cli_fopen(zName, "rb"); size_t n; int rc = SHELL_OPEN_UNSPEC; char zBuf[100]; if( f==0 ){ if( dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){ return SHELL_OPEN_ZIPFILE; }else{ |
︙ | ︙ | |||
5309 5310 5311 5312 5313 5314 5315 | int j, k; int rc; FILE *in; const char *zDbFilename = p->pAuxDb->zDbFilename; unsigned int x[16]; char zLine[1000]; if( zDbFilename ){ | | | 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 | int j, k; int rc; FILE *in; const char *zDbFilename = p->pAuxDb->zDbFilename; unsigned int x[16]; char zLine[1000]; if( zDbFilename ){ in = cli_fopen(zDbFilename, "r"); if( in==0 ){ eputf("cannot open \"%s\" for reading\n", zDbFilename); return 0; } nLine = 0; }else{ in = p->in; |
︙ | ︙ | |||
5796 5797 5798 5799 5800 5801 5802 | if( cli_strcmp(zFile,"stdout")==0 ){ f = stdout; }else if( cli_strcmp(zFile, "stderr")==0 ){ f = stderr; }else if( cli_strcmp(zFile, "off")==0 ){ f = 0; }else{ | | | 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 | if( cli_strcmp(zFile,"stdout")==0 ){ f = stdout; }else if( cli_strcmp(zFile, "stderr")==0 ){ f = stderr; }else if( cli_strcmp(zFile, "off")==0 ){ f = 0; }else{ f = cli_fopen(zFile, bTextMode ? "w" : "wb"); if( f==0 ){ eputf("Error: cannot open \"%s\"\n", zFile); } } return f; } |
︙ | ︙ | |||
9025 9026 9027 9028 9029 9030 9031 | goto meta_command_exit; #else sCtx.in = popen(sCtx.zFile+1, "r"); sCtx.zFile = "<pipe>"; sCtx.xCloser = pclose; #endif }else{ | | | 9052 9053 9054 9055 9056 9057 9058 9059 9060 9061 9062 9063 9064 9065 9066 | goto meta_command_exit; #else sCtx.in = popen(sCtx.zFile+1, "r"); sCtx.zFile = "<pipe>"; sCtx.xCloser = pclose; #endif }else{ sCtx.in = cli_fopen(sCtx.zFile, "rb"); sCtx.xCloser = fclose; } if( sCtx.in==0 ){ eputf("Error: cannot open \"%s\"\n", zFile); goto meta_command_exit; } if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){ |
︙ | ︙ | |||
9354 9355 9356 9357 9358 9359 9360 | iotrace = 0; if( nArg<2 ){ sqlite3IoTrace = 0; }else if( cli_strcmp(azArg[1], "-")==0 ){ sqlite3IoTrace = iotracePrintf; iotrace = stdout; }else{ | | | 9381 9382 9383 9384 9385 9386 9387 9388 9389 9390 9391 9392 9393 9394 9395 | iotrace = 0; if( nArg<2 ){ sqlite3IoTrace = 0; }else if( cli_strcmp(azArg[1], "-")==0 ){ sqlite3IoTrace = iotracePrintf; iotrace = stdout; }else{ iotrace = cli_fopen(azArg[1], "w"); if( iotrace==0 ){ eputf("Error: cannot open \"%s\"\n", azArg[1]); sqlite3IoTrace = 0; rc = 1; }else{ sqlite3IoTrace = iotracePrintf; } |
︙ | ︙ | |||
10323 10324 10325 10326 10327 10328 10329 | if( cli_strcmp(azCmd[0],"changeset")==0 || cli_strcmp(azCmd[0],"patchset")==0 ){ FILE *out = 0; failIfSafeMode(p, "cannot run \".session %s\" in safe mode", azCmd[0]); if( nCmd!=2 ) goto session_syntax_error; if( pSession->p==0 ) goto session_not_open; | | | 10350 10351 10352 10353 10354 10355 10356 10357 10358 10359 10360 10361 10362 10363 10364 | if( cli_strcmp(azCmd[0],"changeset")==0 || cli_strcmp(azCmd[0],"patchset")==0 ){ FILE *out = 0; failIfSafeMode(p, "cannot run \".session %s\" in safe mode", azCmd[0]); if( nCmd!=2 ) goto session_syntax_error; if( pSession->p==0 ) goto session_not_open; out = cli_fopen(azCmd[1], "wb"); if( out==0 ){ eputf("ERROR: cannot open \"%s\" for writing\n", azCmd[1]); }else{ int szChng; void *pChng; if( azCmd[0][0]=='c' ){ |
︙ | ︙ | |||
12263 12264 12265 12266 12267 12268 12269 | " cannot read ~/.sqliterc\n"); return; } zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir); shell_check_oom(zBuf); sqliterc = zBuf; } | | | 12290 12291 12292 12293 12294 12295 12296 12297 12298 12299 12300 12301 12302 12303 12304 | " cannot read ~/.sqliterc\n"); return; } zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir); shell_check_oom(zBuf); sqliterc = zBuf; } p->in = cli_fopen(sqliterc,"rb"); if( p->in ){ if( stdin_is_interactive ){ eputf("-- Loading resources from %s\n", sqliterc); } if( process_input(p) && bail_on_error ) exit(1); fclose(p->in); }else if( sqliterc_override!=0 ){ |
︙ | ︙ |