From: Viktor Szakats Date: Mon, 2 Feb 2026 12:14:30 +0000 (+0100) Subject: build: tidy up curl-specific fstat calls and stat struct type X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a84b041281463315d3f8723febc97be1147964f4;p=thirdparty%2Fcurl.git build: tidy up curl-specific fstat calls and stat struct type To avoid redefining the `fstat` system symbol, and to clarify `struct_stat` is a curl symbol. - introduce `curlx_fstat()` macro and use it. - rename `struct_stat` to `curl_struct_stat`. Also: - tests: replace direct `curlx_win32_stat()` call with `curlx_stat()`. - checksrc: disallow direct `_fstati64` and `fstat()` calls, except in examples. Closes #20496 --- diff --git a/docs/examples/.checksrc b/docs/examples/.checksrc index a9c6b4ed50..6fbc5afcdc 100644 --- a/docs/examples/.checksrc +++ b/docs/examples/.checksrc @@ -11,6 +11,7 @@ allowfunc fdopen allowfunc fopen allowfunc fprintf allowfunc free +allowfunc fstat allowfunc gmtime allowfunc localtime allowfunc malloc diff --git a/docs/internals/CODE_STYLE.md b/docs/internals/CODE_STYLE.md index 08a5ebef33..3f0d5a4f2b 100644 --- a/docs/internals/CODE_STYLE.md +++ b/docs/internals/CODE_STYLE.md @@ -332,6 +332,7 @@ makes us write better code. This is the full list of functions generally banned. _access + _fstati64 _lseeki64 _mbscat _mbsncat @@ -365,6 +366,7 @@ This is the full list of functions generally banned. free freeaddrinfo freopen + fstat getaddrinfo gets gmtime diff --git a/lib/curl_fopen.c b/lib/curl_fopen.c index edd314a5cb..f875227275 100644 --- a/lib/curl_fopen.c +++ b/lib/curl_fopen.c @@ -89,7 +89,7 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename, unsigned char randbuf[41]; char *tempstore = NULL; #ifndef _WIN32 - struct_stat sb; + curl_struct_stat sb; #endif int fd = -1; char *dir = NULL; @@ -99,7 +99,7 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename, *fh = curlx_fopen(filename, FOPEN_WRITETEXT); if(!*fh) goto fail; - if(fstat(fileno(*fh), &sb) == -1 || !S_ISREG(sb.st_mode)) { + if(curlx_fstat(fileno(*fh), &sb) == -1 || !S_ISREG(sb.st_mode)) { return CURLE_OK; } curlx_fclose(*fh); diff --git a/lib/curl_setup.h b/lib/curl_setup.h index dcfa712e61..17928914b2 100644 --- a/lib/curl_setup.h +++ b/lib/curl_setup.h @@ -490,9 +490,6 @@ # include # include /* Large file (>2Gb) support using Win32 functions. */ -# undef fstat -# define fstat(fdes, stp) _fstati64(fdes, stp) -# define struct_stat struct _stati64 # define curl_lseek _lseeki64 # define LSEEK_ERROR ((__int64)-1) #elif defined(__DJGPP__) @@ -508,10 +505,6 @@ # define LSEEK_ERROR ((off_t)-1) #endif -#ifndef struct_stat -#define struct_stat struct stat -#endif - #ifndef SIZEOF_TIME_T /* assume default size of time_t to be 32 bits */ #define SIZEOF_TIME_T 4 diff --git a/lib/curlx/fopen.c b/lib/curlx/fopen.c index db4acb8ebc..a3e544599e 100644 --- a/lib/curlx/fopen.c +++ b/lib/curlx/fopen.c @@ -405,7 +405,7 @@ FILE *curlx_win32_freopen(const char *filename, const char *mode, FILE *fp) return result; } -int curlx_win32_stat(const char *path, struct_stat *buffer) +int curlx_win32_stat(const char *path, curl_struct_stat *buffer) { int result = -1; TCHAR *fixed = NULL; diff --git a/lib/curlx/fopen.h b/lib/curlx/fopen.h index e78a474b97..7ced9098c1 100644 --- a/lib/curlx/fopen.h +++ b/lib/curlx/fopen.h @@ -34,6 +34,7 @@ int curlx_fseek(void *stream, curl_off_t offset, int whence); #ifdef _WIN32 +#include /* for _fstati64, struct _stati64 */ #ifndef CURL_WINDOWS_UWP HANDLE curlx_CreateFile(const char *filename, DWORD dwDesiredAccess, @@ -43,9 +44,11 @@ HANDLE curlx_CreateFile(const char *filename, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); #endif /* !CURL_WINDOWS_UWP */ +#define curlx_fstat _fstati64 +#define curl_struct_stat struct _stati64 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_stat(const char *path, curl_struct_stat *buffer); int curlx_win32_open(const char *filename, int oflag, ...); int curlx_win32_rename(const char *oldpath, const char *newpath); #define CURLX_FOPEN_LOW(fname, mode) curlx_win32_fopen(fname, mode) @@ -56,6 +59,8 @@ int curlx_win32_rename(const char *oldpath, const char *newpath); #define curlx_close _close #define curlx_rename curlx_win32_rename #else +#define curlx_fstat fstat +#define curl_struct_stat struct stat #define CURLX_FOPEN_LOW fopen #define CURLX_FREOPEN_LOW freopen #define CURLX_FDOPEN_LOW fdopen diff --git a/lib/file.c b/lib/file.c index fda1472dbf..0cd63644e8 100644 --- a/lib/file.c +++ b/lib/file.c @@ -270,7 +270,7 @@ static CURLcode file_upload(struct Curl_easy *data, CURLcode result = CURLE_OK; char *xfer_ulbuf; size_t xfer_ulblen; - struct_stat file_stat; + curl_struct_stat file_stat; const char *sendbuf; bool eos = FALSE; @@ -311,7 +311,7 @@ static CURLcode file_upload(struct Curl_easy *data, /* treat the negative resume offset value as the case of "-" */ if(data->state.resume_from < 0) { - if(fstat(fd, &file_stat)) { + if(curlx_fstat(fd, &file_stat)) { curlx_close(fd); failf(data, "cannot get the size of %s", file->path); return CURLE_WRITE_ERROR; @@ -390,9 +390,7 @@ static CURLcode file_do(struct Curl_easy *data, bool *done) */ struct FILEPROTO *file = Curl_meta_get(data, CURL_META_FILE_EASY); CURLcode result = CURLE_OK; - struct_stat statbuf; /* struct_stat instead of struct stat just to allow the - Windows version to have a different struct without - having to redefine the simple word 'stat' */ + curl_struct_stat statbuf; curl_off_t expected_size = -1; bool size_known; bool fstated = FALSE; @@ -411,7 +409,7 @@ static CURLcode file_do(struct Curl_easy *data, bool *done) fd = file->fd; /* VMS: This only works reliable for STREAMLF files */ - if(fstat(fd, &statbuf) != -1) { + if(curlx_fstat(fd, &statbuf) != -1) { if(!S_ISDIR(statbuf.st_mode)) expected_size = statbuf.st_size; /* and store the modification time */ diff --git a/lib/mime.c b/lib/mime.c index a80b206d9c..5c845a2745 100644 --- a/lib/mime.c +++ b/lib/mime.c @@ -107,7 +107,7 @@ static const char aschex[] = * and CD/DVD images should be either a STREAM_LF format or a fixed format. * */ -curl_off_t VmsRealFileSize(const char *name, const struct_stat *stat_buf) +curl_off_t VmsRealFileSize(const char *name, const curl_struct_stat *stat_buf) { char buffer[8192]; curl_off_t count; @@ -136,7 +136,8 @@ curl_off_t VmsRealFileSize(const char *name, const struct_stat *stat_buf) * if not to call a routine to get the correct size. * */ -static curl_off_t VmsSpecialSize(const char *name, const struct_stat *stat_buf) +static curl_off_t VmsSpecialSize(const char *name, + const curl_struct_stat *stat_buf) { switch(stat_buf->st_fab_rfm) { case FAB$C_VAR: @@ -160,7 +161,7 @@ static curl_off_t VmsSpecialSize(const char *name, const struct_stat *stat_buf) */ static FILE *vmsfopenread(const char *file, const char *mode) { - struct_stat statbuf; + curl_struct_stat statbuf; int result; result = curlx_stat(file, &statbuf); @@ -1307,7 +1308,7 @@ CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename) if(filename) { char *base; - struct_stat sbuf; + curl_struct_stat sbuf; if(curlx_stat(filename, &sbuf)) result = CURLE_READ_ERROR; diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c index 7b0fbd636e..8dfc31a1ee 100644 --- a/lib/vssh/libssh2.c +++ b/lib/vssh/libssh2.c @@ -1089,7 +1089,7 @@ static CURLcode ssh_state_pkey_init(struct Curl_easy *data, /* To ponder about: should really the lib be messing about with the HOME environment variable etc? */ char *home = curl_getenv("HOME"); - struct_stat sbuf; + curl_struct_stat sbuf; /* If no private key file is specified, try some common paths. */ if(home) { diff --git a/scripts/checksrc.pl b/scripts/checksrc.pl index 288ff2a5e0..f5bbab69e7 100755 --- a/scripts/checksrc.pl +++ b/scripts/checksrc.pl @@ -49,6 +49,7 @@ my @ignore_line; my %banfunc = ( "_access" => 1, + "_fstati64" => 1, "_lseeki64" => 1, "_mbscat" => 1, "_mbsncat" => 1, @@ -82,6 +83,7 @@ my %banfunc = ( "free" => 1, "freeaddrinfo" => 1, "freopen" => 1, + "fstat" => 1, "getaddrinfo" => 1, "gets" => 1, "gmtime" => 1, diff --git a/src/tool_doswin.c b/src/tool_doswin.c index f18b539b29..03c50eb691 100644 --- a/src/tool_doswin.c +++ b/src/tool_doswin.c @@ -291,7 +291,7 @@ static SANITIZEcode rename_if_reserved_dos(char ** const sanitized, * to rename such files. */ char *p, *base, *buffer; #ifdef MSDOS - struct_stat st_buf; + curl_struct_stat st_buf; #endif size_t len, bufsize; diff --git a/src/tool_filetime.c b/src/tool_filetime.c index afe308f8ad..069e87b1f2 100644 --- a/src/tool_filetime.c +++ b/src/tool_filetime.c @@ -68,7 +68,7 @@ int getfiletime(const char *filename, curl_off_t *stamp) GetLastError()); } #else - struct_stat statbuf; + curl_struct_stat statbuf; if(curlx_stat(filename, &statbuf) != -1) { *stamp = (curl_off_t)statbuf.st_mtime; rc = 0; diff --git a/src/tool_formparse.c b/src/tool_formparse.c index 5714ae5bc1..b48ac52831 100644 --- a/src/tool_formparse.c +++ b/src/tool_formparse.c @@ -122,13 +122,13 @@ static struct tool_mime *tool_mime_new_filedata(struct tool_mime *parent, char *data = NULL; curl_off_t size; curl_off_t origin; - struct_stat sbuf; + curl_struct_stat sbuf; CURLX_SET_BINMODE(stdin); origin = ftell(stdin); /* If stdin is a regular file, do not buffer data but read it when needed. */ - if(fd >= 0 && origin >= 0 && !fstat(fd, &sbuf) && + if(fd >= 0 && origin >= 0 && !curlx_fstat(fd, &sbuf) && #ifdef __VMS sbuf.st_fab_rfm != FAB$C_VAR && sbuf.st_fab_rfm != FAB$C_VFC && #endif diff --git a/src/tool_getparam.c b/src/tool_getparam.c index 1acb175bf4..540c986955 100644 --- a/src/tool_getparam.c +++ b/src/tool_getparam.c @@ -2209,7 +2209,7 @@ static ParameterError existingfile(char **store, const struct LongShort *a, const char *filename) { - struct_stat info; + curl_struct_stat info; if(curlx_stat(filename, &info)) { errorf("The file '%s' provided to --%s does not exist", filename, a->lname); diff --git a/src/tool_operate.c b/src/tool_operate.c index 8eea688b02..c9c6da942d 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -146,7 +146,7 @@ static bool is_pkcs11_uri(const char *string) * */ static curl_off_t vms_realfilesize(const char *name, - const struct_stat *stat_buf) + const curl_struct_stat *stat_buf) { char buffer[8192]; curl_off_t count; @@ -176,7 +176,8 @@ static curl_off_t vms_realfilesize(const char *name, * if not to call a routine to get the correct size. * */ -static curl_off_t VmsSpecialSize(const char *name, const struct_stat *stat_buf) +static curl_off_t VmsSpecialSize(const char *name, + const curl_struct_stat *stat_buf) { switch(stat_buf->st_fab_rfm) { case FAB$C_VAR: @@ -247,7 +248,7 @@ static struct per_transfer *del_per_transfer(struct per_transfer *per) static CURLcode pre_transfer(struct per_transfer *per) { curl_off_t uploadfilesize = -1; - struct_stat fileinfo; + curl_struct_stat fileinfo; CURLcode result = CURLE_OK; if(per->uploadfile && !stdin_upload(per->uploadfile)) { @@ -284,7 +285,7 @@ static CURLcode pre_transfer(struct per_transfer *per) if(per->infd == -1) #else per->infd = curlx_open(per->uploadfile, O_RDONLY | CURL_O_BINARY); - if((per->infd == -1) || fstat(per->infd, &fileinfo)) + if((per->infd == -1) || curlx_fstat(per->infd, &fileinfo)) #endif { helpf("cannot open '%s'", per->uploadfile); @@ -547,11 +548,11 @@ static CURLcode retrycheck(struct OperationConfig *config, } if(truncate && outs->bytes && outs->filename && outs->stream) { - struct_stat fileinfo; + curl_struct_stat fileinfo; /* The output can be a named pipe or a character device etc that cannot be truncated. Only truncate regular files. */ - if(!fstat(fileno(outs->stream), &fileinfo) && + if(!curlx_fstat(fileno(outs->stream), &fileinfo) && S_ISREG(fileinfo.st_mode)) { int rc; /* We have written data to an output file, we truncate file */ @@ -717,7 +718,7 @@ static CURLcode post_per_transfer(struct per_transfer *per, errorf("curl: (%d) Failed writing body", result); } if(result && config->rm_partial) { - struct_stat st; + curl_struct_stat st; if(!curlx_stat(outs->filename, &st) && S_ISREG(st.st_mode)) { if(!unlink(outs->filename)) notef("Removed output file: %s", outs->filename); @@ -1039,7 +1040,7 @@ static CURLcode setup_outfile(struct OperationConfig *config, } if(config->skip_existing) { - struct_stat fileinfo; + curl_struct_stat fileinfo; if(!curlx_stat(per->outfile, &fileinfo)) { /* file is present */ notef("skips transfer, \"%s\" exists locally", per->outfile); @@ -1051,7 +1052,7 @@ static CURLcode setup_outfile(struct OperationConfig *config, if(config->resume_from_current) { /* We are told to continue from where we are now. Get the size of the file as it is now and open it for append instead */ - struct_stat fileinfo; + curl_struct_stat fileinfo; /* VMS -- Danger, the filesize is only valid for stream files */ if(curlx_stat(per->outfile, &fileinfo) == 0) /* set offset to current file size: */ diff --git a/tests/libtest/lib505.c b/tests/libtest/lib505.c index 9f520c111b..e920b77c2b 100644 --- a/tests/libtest/lib505.c +++ b/tests/libtest/lib505.c @@ -37,7 +37,7 @@ static CURLcode test_lib505(const char *URL) char errbuf[STRERROR_LEN]; FILE *hd_src; int hd; - struct_stat file_info; + curl_struct_stat file_info; struct curl_slist *hl; struct curl_slist *headerlist = NULL; @@ -59,7 +59,7 @@ static CURLcode test_lib505(const char *URL) } /* get the file size of the local file */ - hd = fstat(fileno(hd_src), &file_info); + hd = curlx_fstat(fileno(hd_src), &file_info); if(hd == -1) { /* cannot open file, bail out */ curl_mfprintf(stderr, "fstat() failed with error (%d) %s\n", diff --git a/tests/libtest/lib525.c b/tests/libtest/lib525.c index 1944ec7122..2e3c47bd0b 100644 --- a/tests/libtest/lib525.c +++ b/tests/libtest/lib525.c @@ -30,7 +30,7 @@ static CURLcode test_lib525(const char *URL) char errbuf[STRERROR_LEN]; FILE *hd_src = NULL; int hd; - struct_stat file_info; + curl_struct_stat file_info; CURLM *multi = NULL; int running; @@ -50,7 +50,7 @@ static CURLcode test_lib525(const char *URL) } /* get the file size of the local file */ - hd = fstat(fileno(hd_src), &file_info); + hd = curlx_fstat(fileno(hd_src), &file_info); if(hd == -1) { /* cannot open file, bail out */ curl_mfprintf(stderr, "fstat() failed with error (%d) %s\n", diff --git a/tests/libtest/lib541.c b/tests/libtest/lib541.c index 48a954990f..7da160536d 100644 --- a/tests/libtest/lib541.c +++ b/tests/libtest/lib541.c @@ -34,7 +34,7 @@ static CURLcode test_lib541(const char *URL) char errbuf[STRERROR_LEN]; FILE *hd_src; int hd; - struct_stat file_info; + curl_struct_stat file_info; if(!libtest_arg2) { curl_mfprintf(stderr, "Usage: \n"); @@ -50,7 +50,7 @@ static CURLcode test_lib541(const char *URL) } /* get the file size of the local file */ - hd = fstat(fileno(hd_src), &file_info); + hd = curlx_fstat(fileno(hd_src), &file_info); if(hd == -1) { /* cannot open file, bail out */ curl_mfprintf(stderr, "fstat() failed with error (%d) %s\n", diff --git a/tests/libtest/lib568.c b/tests/libtest/lib568.c index 8c1e5dd7fa..80287e2b55 100644 --- a/tests/libtest/lib568.c +++ b/tests/libtest/lib568.c @@ -35,7 +35,7 @@ static CURLcode test_lib568(const char *URL) char errbuf[STRERROR_LEN]; int sdp; FILE *sdpf = NULL; - struct_stat file_info; + curl_struct_stat file_info; char *stream_uri = NULL; int request = 1; struct curl_slist *custom_headers = NULL; @@ -74,7 +74,7 @@ static CURLcode test_lib568(const char *URL) result = TEST_ERR_MAJOR_BAD; goto test_cleanup; } - fstat(sdp, &file_info); + curlx_fstat(sdp, &file_info); curlx_close(sdp); sdpf = curlx_fopen(libtest_arg2, "rb"); diff --git a/tests/libtest/lib572.c b/tests/libtest/lib572.c index 38edd77ece..550bbb54dd 100644 --- a/tests/libtest/lib572.c +++ b/tests/libtest/lib572.c @@ -35,7 +35,7 @@ static CURLcode test_lib572(const char *URL) char errbuf[STRERROR_LEN]; int params; FILE *paramsf = NULL; - struct_stat file_info; + curl_struct_stat file_info; char *stream_uri = NULL; int request = 1; struct curl_slist *custom_headers = NULL; @@ -92,7 +92,7 @@ static CURLcode test_lib572(const char *URL) result = TEST_ERR_MAJOR_BAD; goto test_cleanup; } - fstat(params, &file_info); + curlx_fstat(params, &file_info); curlx_close(params); paramsf = curlx_fopen(libtest_arg2, "rb"); diff --git a/tests/libtest/lib582.c b/tests/libtest/lib582.c index 4ac7b903bd..cd794873aa 100644 --- a/tests/libtest/lib582.c +++ b/tests/libtest/lib582.c @@ -220,7 +220,7 @@ static CURLcode test_lib582(const char *URL) char errbuf[STRERROR_LEN]; FILE *hd_src = NULL; int hd; - struct_stat file_info; + curl_struct_stat file_info; CURLM *multi = NULL; struct t582_ReadWriteSockets sockets = { { NULL, 0, 0 }, { NULL, 0, 0 } }; int success = 0; @@ -245,7 +245,7 @@ static CURLcode test_lib582(const char *URL) } /* get the file size of the local file */ - hd = fstat(fileno(hd_src), &file_info); + hd = curlx_fstat(fileno(hd_src), &file_info); if(hd == -1) { /* cannot open file, bail out */ curl_mfprintf(stderr, "fstat() failed with error (%d) %s\n", diff --git a/tests/server/util.c b/tests/server/util.c index 41fa39c619..6f179f9b8a 100644 --- a/tests/server/util.c +++ b/tests/server/util.c @@ -670,7 +670,7 @@ int bind_unix_socket(curl_socket_t sock, const char *unix_socket, curlx_strcopy(sau->sun_path, sizeof(sau->sun_path), unix_socket, len); rc = bind(sock, (struct sockaddr *)sau, sizeof(struct sockaddr_un)); if(rc && SOCKERRNO == SOCKEADDRINUSE) { - struct_stat statbuf; + curl_struct_stat statbuf; /* socket already exists. Perhaps it is stale? */ curl_socket_t unixfd = socket(AF_UNIX, SOCK_STREAM, 0); if(CURL_SOCKET_BAD == unixfd) { @@ -690,7 +690,7 @@ int bind_unix_socket(curl_socket_t sock, const char *unix_socket, /* socket server is not alive, now check if it was actually a socket. */ #ifdef _WIN32 /* Windows does not have lstat function. */ - rc = curlx_win32_stat(unix_socket, &statbuf); + rc = curlx_stat(unix_socket, &statbuf); #else rc = lstat(unix_socket, &statbuf); #endif