]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
build: tidy up curl-specific fstat calls and stat struct type
authorViktor Szakats <commit@vsz.me>
Mon, 2 Feb 2026 12:14:30 +0000 (13:14 +0100)
committerViktor Szakats <commit@vsz.me>
Mon, 2 Feb 2026 17:57:13 +0000 (18:57 +0100)
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

22 files changed:
docs/examples/.checksrc
docs/internals/CODE_STYLE.md
lib/curl_fopen.c
lib/curl_setup.h
lib/curlx/fopen.c
lib/curlx/fopen.h
lib/file.c
lib/mime.c
lib/vssh/libssh2.c
scripts/checksrc.pl
src/tool_doswin.c
src/tool_filetime.c
src/tool_formparse.c
src/tool_getparam.c
src/tool_operate.c
tests/libtest/lib505.c
tests/libtest/lib525.c
tests/libtest/lib541.c
tests/libtest/lib568.c
tests/libtest/lib572.c
tests/libtest/lib582.c
tests/server/util.c

index a9c6b4ed503ff86dd7ba8abaf7c5303fa7e2b2cc..6fbc5afcdc7ce46475e5150289c0cc993fb36518 100644 (file)
@@ -11,6 +11,7 @@ allowfunc fdopen
 allowfunc fopen
 allowfunc fprintf
 allowfunc free
+allowfunc fstat
 allowfunc gmtime
 allowfunc localtime
 allowfunc malloc
index 08a5ebef333d109bafe18f71b1421721fc6ca0c4..3f0d5a4f2bbb1a1adaf8eeff215cb4c6522fdc1d 100644 (file)
@@ -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
index edd314a5cb7d7119e4151c6f459d1801ace629cd..f875227275c329228e1e19b58f5f211263535b4e 100644 (file)
@@ -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);
index dcfa712e61cba4804a3c3a039d52692488d7a860..17928914b28704b4c661c4a16f6427695c3a3389 100644 (file)
 #  include <sys/types.h>
 #  include <sys/stat.h>
    /* 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__)
 #  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
index db4acb8ebc78b37cdbe21db860ce148463fa9505..a3e544599e2205e21baca79820b20facf5728451 100644 (file)
@@ -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;
index e78a474b975c0219dd2db61738a6f9ff477879b3..7ced9098c1417a5e30dc8ec74a6e6b26e18928ad 100644 (file)
@@ -34,6 +34,7 @@
 int curlx_fseek(void *stream, curl_off_t offset, int whence);
 
 #ifdef _WIN32
+#include <sys/stat.h>  /* 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
index fda1472dbf9470b50a3fd5e2ee13e8a4783e700f..0cd63644e855ad6b5d5c82f8c037c409da3b0a89 100644 (file)
@@ -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 */
index a80b206d9c5c15cea72a286f3e6814d5fb275dc9..5c845a2745da21d975d0678c9320b858128e833e 100644 (file)
@@ -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;
index 7b0fbd636e8e497558e61e01af210078417446b7..8dfc31a1eeef34d434c2eedfaa11c4963558b4a3 100644 (file)
@@ -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) {
index 288ff2a5e0b328a7c8cb1bbb59d7fa3a1aa5890c..f5bbab69e78ed7897f24b3fdd1491a5db820d922 100755 (executable)
@@ -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,
index f18b539b29c2618d00a496f7e2a471850cca1ac7..03c50eb69103106edcaa82af1a9dd0acb7d6174d 100644 (file)
@@ -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;
 
index afe308f8ad68532e5a38253a82b1cfec665a3615..069e87b1f2337c6f20e4c164d9bf767b628ca017 100644 (file)
@@ -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;
index 5714ae5bc113cf17cab05e3fc58e6609c382cf36..b48ac52831abae8c6268c50b4ca9f468452d998f 100644 (file)
@@ -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
index 1acb175bf47dca27c470b0426dbfd1b3fe582dc0..540c98695586fb4d05ea37ed975112d6e942014d 100644 (file)
@@ -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);
index 8eea688b02557fe59e325563e0f110ee9fbed0bf..c9c6da942d65eac7eddb3f06342d6fdb8d3425ab 100644 (file)
@@ -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: */
index 9f520c111bf2f2c749e9c572041207110c5b20b5..e920b77c2bffebff96fa5b19a8b15c7a555dc13f 100644 (file)
@@ -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",
index 1944ec71226603c3f7314f749834d9c75a5d56f2..2e3c47bd0b424093878606e9b659732342df90c8 100644 (file)
@@ -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",
index 48a954990f85de1d8437348371aade646417feb2..7da160536d1284c4a70d0608d581bd8dad3699fe 100644 (file)
@@ -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: <url> <file-to-upload>\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",
index 8c1e5dd7fa29608a5cf0635b009f2adab9120def..80287e2b555f2f8188bb3c4f5c9cd56f9155304f 100644 (file)
@@ -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");
index 38edd77ecea54a809881f153b67ef4e12cc80c4a..550bbb54dda54d23535445f1d192de8152aed925 100644 (file)
@@ -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");
index 4ac7b903bdc99556fbebe3d464f1232d643d54ca..cd794873aa17d7faafb90bcbcd75c0af2458ed7d 100644 (file)
@@ -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",
index 41fa39c61951c4346285b6515f60233e588e7044..6f179f9b8a9f270cf17392278beb8ec004130d52 100644 (file)
@@ -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