mirror of
https://github.com/curl/curl.git
synced 2026-04-11 12:01:42 +08:00
curlx: add and use curlx_freopen()
To complement the existing `curlx_fopen()` internal API.
It's used by the curl's `--stderr` option.
`curlx_freopen()` adds two features to the bare `freopen()`:
- tracing for debug-enabled builds.
- Unicode and long-filename support for Windows builds.
In effect this adds long-filename and enables Unicode support for
the `--stderr <filename>` curl command-line option on Windows.
Also add to checksrc.
Follow-up to 2f17a9b654 #10673
Closes #19598
This commit is contained in:
parent
2decbb1c1f
commit
3d80d37cf0
@ -76,7 +76,8 @@ warnings are:
|
||||
|
||||
- `EXCLAMATIONSPACE`: space found after exclamations mark
|
||||
|
||||
- `FOPENMODE`: `curlx_fopen()` needs a macro for the mode string, use it
|
||||
- `FOPENMODE`: `curlx_fopen()`, `curlx_freopen()` need a macro for the mode
|
||||
string, use it
|
||||
|
||||
- `INDENTATION`: detected a wrong start column for code. Note that this
|
||||
warning only checks some specific places and can certainly miss many bad
|
||||
|
||||
@ -1041,6 +1041,9 @@ CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *source);
|
||||
CURL_EXTERN ALLOC_FUNC
|
||||
FILE *curl_dbg_fopen(const char *file, const char *mode,
|
||||
int line, const char *source);
|
||||
CURL_EXTERN ALLOC_FUNC
|
||||
FILE *curl_dbg_freopen(const char *file, const char *mode, FILE *fh,
|
||||
int line, const char *source);
|
||||
CURL_EXTERN ALLOC_FUNC
|
||||
FILE *curl_dbg_fdopen(int filedes, const char *mode,
|
||||
int line, const char *source);
|
||||
|
||||
@ -282,6 +282,40 @@ FILE *curlx_win32_fopen(const char *filename, const char *mode)
|
||||
return result;
|
||||
}
|
||||
|
||||
FILE *curlx_win32_freopen(const char *filename, const char *mode, FILE *fp)
|
||||
{
|
||||
FILE *result = NULL;
|
||||
TCHAR *fixed = NULL;
|
||||
const TCHAR *target = NULL;
|
||||
|
||||
#ifdef _UNICODE
|
||||
wchar_t *filename_w = curlx_convert_UTF8_to_wchar(filename);
|
||||
wchar_t *mode_w = curlx_convert_UTF8_to_wchar(mode);
|
||||
if(filename_w && mode_w) {
|
||||
if(fix_excessive_path(filename_w, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = filename_w;
|
||||
result = _wfreopen(target, mode_w, fp);
|
||||
}
|
||||
else
|
||||
/* !checksrc! disable ERRNOVAR 1 */
|
||||
errno = EINVAL;
|
||||
curlx_unicodefree(filename_w);
|
||||
curlx_unicodefree(mode_w);
|
||||
#else
|
||||
if(fix_excessive_path(filename, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = filename;
|
||||
/* !checksrc! disable BANNEDFUNC 1 */
|
||||
result = freopen(target, mode, fp);
|
||||
#endif
|
||||
|
||||
(free)(fixed);
|
||||
return result;
|
||||
}
|
||||
|
||||
int curlx_win32_stat(const char *path, struct_stat *buffer)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
@ -36,23 +36,29 @@ int curlx_fseek(void *stream, curl_off_t offset, int whence);
|
||||
|
||||
#ifdef _WIN32
|
||||
FILE *curlx_win32_fopen(const char *filename, const char *mode);
|
||||
FILE *curlx_win32_freopen(const char *filename, const char *mode, FILE *fh);
|
||||
int curlx_win32_stat(const char *path, struct_stat *buffer);
|
||||
int curlx_win32_open(const char *filename, int oflag, ...);
|
||||
#define CURLX_FOPEN_LOW(fname, mode) curlx_win32_fopen(fname, mode)
|
||||
#define curlx_stat(fname, stp) curlx_win32_stat(fname, stp)
|
||||
#define curlx_open curlx_win32_open
|
||||
#define CURLX_FOPEN_LOW(fname, mode) curlx_win32_fopen(fname, mode)
|
||||
#define CURLX_FREOPEN_LOW(fname, mode, fh) curlx_win32_freopen(fname, mode, fh)
|
||||
#define curlx_stat(fname, stp) curlx_win32_stat(fname, stp)
|
||||
#define curlx_open curlx_win32_open
|
||||
#else
|
||||
#define CURLX_FOPEN_LOW fopen
|
||||
#define curlx_stat(fname, stp) stat(fname, stp)
|
||||
#define curlx_open open
|
||||
#define CURLX_FOPEN_LOW fopen
|
||||
#define CURLX_FREOPEN_LOW freopen
|
||||
#define curlx_stat(fname, stp) stat(fname, stp)
|
||||
#define curlx_open open
|
||||
#endif
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
#define curlx_fopen(file,mode) curl_dbg_fopen(file,mode,__LINE__,__FILE__)
|
||||
#define curlx_freopen(file,mode,fh) \
|
||||
curl_dbg_freopen(file,mode,fh,__LINE__,__FILE__)
|
||||
#define curlx_fdopen(file,mode) curl_dbg_fdopen(file,mode,__LINE__,__FILE__)
|
||||
#define curlx_fclose(file) curl_dbg_fclose(file,__LINE__,__FILE__)
|
||||
#else
|
||||
#define curlx_fopen CURLX_FOPEN_LOW
|
||||
#define curlx_freopen CURLX_FREOPEN_LOW
|
||||
#define curlx_fdopen fdopen
|
||||
#define curlx_fclose fclose
|
||||
#endif
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "curlx/fopen.h" /* for CURLX_FOPEN_LOW() */
|
||||
#include "curlx/fopen.h" /* for CURLX_FOPEN_LOW(), CURLX_FREOPEN_LOW() */
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
@ -424,7 +424,19 @@ FILE *curl_dbg_fopen(const char *file, const char *mode,
|
||||
FILE *res = CURLX_FOPEN_LOW(file, mode);
|
||||
if(source)
|
||||
curl_dbg_log("FILE %s:%d fopen(\"%s\",\"%s\") = %p\n",
|
||||
source, line, file, mode, (void *)res);
|
||||
source, line, file, mode, (void *)res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
ALLOC_FUNC
|
||||
FILE *curl_dbg_freopen(const char *file, const char *mode, FILE *fh,
|
||||
int line, const char *source)
|
||||
{
|
||||
FILE *res = CURLX_FREOPEN_LOW(file, mode, fh);
|
||||
if(source)
|
||||
curl_dbg_log("FILE %s:%d freopen(\"%s\",\"%s\",%p) = %p\n",
|
||||
source, line, file, mode, (void *)fh, (void *)res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -106,6 +106,7 @@ my %banfunc = (
|
||||
"fclose" => 1,
|
||||
"fdopen" => 1,
|
||||
"fopen" => 1,
|
||||
"freopen" => 1,
|
||||
"open" => 1,
|
||||
"stat" => 1,
|
||||
);
|
||||
@ -961,7 +962,7 @@ sub scanfile {
|
||||
}
|
||||
|
||||
# scan for use of non-binary fopen without the macro
|
||||
if($l =~ /^(.*\W)(curlx_fopen|CURLX_FOPEN_LOW)\s*\([^,]*, *\"([^"]*)/) {
|
||||
if($l =~ /^(.*\W)(curlx_fopen|CURLX_FOPEN_LOW|curlx_freopen|CURLX_FREOPEN_LOW)\s*\([^,]*, *\"([^"]*)/) {
|
||||
my $mode = $3;
|
||||
if($mode !~ /b/) {
|
||||
checkwarn("FOPENMODE",
|
||||
|
||||
@ -60,7 +60,7 @@ void tool_set_stderr_file(const char *filename)
|
||||
/* freopen the actual stderr (stdio.h stderr) instead of tool_stderr since
|
||||
the latter may be set to stdout. */
|
||||
/* !checksrc! disable STDERR 1 */
|
||||
fp = freopen(filename, FOPEN_WRITETEXT, stderr);
|
||||
fp = curlx_freopen(filename, FOPEN_WRITETEXT, stderr);
|
||||
if(!fp) {
|
||||
/* stderr may have been closed by freopen. there is nothing to be done. */
|
||||
DEBUGASSERT(0);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user