← Commit list

3d80d37cf0

Viktor Szakats
Viktor Szakats
2025-11-19
SUCCESS Duration: 141s

Subject

curlx: add and use `curlx_freopen()`

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

docs/internals/CHECKSRC.md+2 -1
@@ -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
lib/curl_setup.h+3 -0
@@ -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);
lib/curlx/fopen.c+34 -0
@@ -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;
lib/curlx/fopen.h+12 -6
@@ -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
lib/memdebug.c+14 -2
@@ -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;
}
scripts/checksrc.pl+2 -1
@@ -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",
src/tool_stderr.c+1 -1
@@ -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);