← Commit list

6d0ee7b17b

Viktor Szakats
Viktor Szakats
2025-12-20
SUCCESS Duration: 210s

Subject

curlx: add `curlx_rename()`, fix to support long filenames on Windows

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/CODE_STYLE.md+4 -0
@@ -375,12 +375,16 @@ This is the full list of functions generally banned.
localtime
malloc
mbstowcs
+ MoveFileEx
+ MoveFileExA
+ MoveFileExW
msnprintf
mvsnprintf
open
printf
realloc
recv
+ rename
send
snprintf
socket
lib/Makefile.inc+0 -2
@@ -237,7 +237,6 @@ LIB_CFILES = \
psl.c \
rand.c \
ratelimit.c \
- rename.c \
request.c \
rtsp.c \
select.c \
@@ -366,7 +365,6 @@ LIB_HFILES = \
psl.h \
rand.h \
ratelimit.h \
- rename.h \
request.h \
rtsp.h \
select.h \
lib/altsvc.c+1 -2
@@ -35,7 +35,6 @@
#include "parsedate.h"
#include "sendf.h"
#include "curlx/warnless.h"
-#include "rename.h"
#include "strdup.h"
#include "curlx/inet_pton.h"
#include "curlx/strparse.h"
@@ -379,7 +378,7 @@ CURLcode Curl_altsvc_save(struct Curl_easy *data,
break;
}
curlx_fclose(out);
- if(!result && tempstore && Curl_rename(tempstore, file))
+ if(!result && tempstore && curlx_rename(tempstore, file))
result = CURLE_WRITE_ERROR;
if(result && tempstore)
lib/cookie.c+1 -2
@@ -37,7 +37,6 @@
#include "curl_get_line.h"
#include "curl_memrchr.h"
#include "parsedate.h"
-#include "rename.h"
#include "strdup.h"
#include "llist.h"
#include "bufref.h"
@@ -1534,7 +1533,7 @@ static CURLcode cookie_output(struct Curl_easy *data,
if(!use_stdout) {
curlx_fclose(out);
out = NULL;
- if(tempstore && Curl_rename(tempstore, filename)) {
+ if(tempstore && curlx_rename(tempstore, filename)) {
error = CURLE_WRITE_ERROR;
goto error;
}
lib/curlx/fopen.c+67 -0
@@ -44,6 +44,7 @@ int curlx_fseek(void *stream, curl_off_t offset, int whence)
#include <share.h> /* for _SH_DENYNO */
#include "multibyte.h"
+#include "timeval.h"
#ifdef CURLDEBUG
/*
@@ -436,6 +437,72 @@ int curlx_win32_stat(const char *path, struct_stat *buffer)
return result;
}
+#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_COOKIES) || \
+ !defined(CURL_DISABLE_ALTSVC)
+/* rename() on Windows does not overwrite, so we cannot use it here.
+ MoveFileEx() will overwrite and is usually atomic, however it fails
+ when there are open handles to the file. */
+int curlx_win32_rename(const char *oldpath, const char *newpath)
+{
+ int res = -1; /* fail */
+
+#ifdef UNICODE
+ TCHAR *tchar_oldpath = curlx_convert_UTF8_to_wchar(oldpath);
+ TCHAR *tchar_newpath = curlx_convert_UTF8_to_wchar(newpath);
+#else
+ const TCHAR *tchar_oldpath = oldpath;
+ const TCHAR *tchar_newpath = newpath;
+#endif
+
+ if(tchar_oldpath && tchar_newpath) {
+ const int max_wait_ms = 1000;
+ struct curltime start;
+
+ TCHAR *oldpath_fixed = NULL;
+ TCHAR *newpath_fixed = NULL;
+ const TCHAR *target_oldpath;
+ const TCHAR *target_newpath;
+
+ if(fix_excessive_path(tchar_oldpath, &oldpath_fixed))
+ target_oldpath = oldpath_fixed;
+ else
+ target_oldpath = tchar_oldpath;
+
+ if(fix_excessive_path(tchar_newpath, &newpath_fixed))
+ target_newpath = newpath_fixed;
+ else
+ target_newpath = tchar_newpath;
+
+ start = curlx_now();
+
+ for(;;) {
+ timediff_t diff;
+ /* !checksrc! disable BANNEDFUNC 1 */
+ if(MoveFileEx(target_oldpath, target_newpath,
+ MOVEFILE_REPLACE_EXISTING)) {
+ res = 0; /* success */
+ break;
+ }
+ diff = curlx_timediff_ms(curlx_now(), start);
+ if(diff < 0 || diff > max_wait_ms) {
+ break;
+ }
+ Sleep(1);
+ }
+
+ CURLX_FREE(oldpath_fixed);
+ CURLX_FREE(newpath_fixed);
+ }
+
+#ifdef UNICODE
+ curlx_free(tchar_oldpath);
+ curlx_free(tchar_newpath);
+#endif
+
+ return res;
+}
+#endif
+
#undef CURLX_MALLOC
#undef CURLX_FREE
lib/curlx/fopen.h+3 -0
@@ -48,15 +48,18 @@ 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, ...);
+int curlx_win32_rename(const char *oldpath, const char *newpath);
#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
+#define curlx_rename curlx_win32_rename
#else
#define CURLX_FOPEN_LOW fopen
#define CURLX_FREOPEN_LOW freopen
#define curlx_stat(fname, stp) stat(fname, stp)
#define curlx_open open
+#define curlx_rename rename
#endif
#ifdef CURLDEBUG
lib/hsts.c+1 -2
@@ -35,7 +35,6 @@
#include "curl_get_line.h"
#include "sendf.h"
#include "parsedate.h"
-#include "rename.h"
#include "curl_share.h"
#include "strdup.h"
#include "curlx/strparse.h"
@@ -362,7 +361,7 @@ CURLcode Curl_hsts_save(struct Curl_easy *data, struct hsts *h,
break;
}
curlx_fclose(out);
- if(!result && tempstore && Curl_rename(tempstore, file))
+ if(!result && tempstore && curlx_rename(tempstore, file))
result = CURLE_WRITE_ERROR;
if(result && tempstore)
lib/rename.c+0 -67
@@ -1,67 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * SPDX-License-Identifier: curl
- *
- ***************************************************************************/
-
-#include "curl_setup.h"
-
-#if (!defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_COOKIES)) || \
- !defined(CURL_DISABLE_ALTSVC)
-
-#include "curlx/multibyte.h"
-#include "curlx/timeval.h"
-#include "rename.h"
-
-/* return 0 on success, 1 on error */
-int Curl_rename(const char *oldpath, const char *newpath)
-{
-#ifdef _WIN32
- /* rename() on Windows does not overwrite, so we cannot use it here.
- MoveFileEx() will overwrite and is usually atomic, however it fails
- when there are open handles to the file. */
- const int max_wait_ms = 1000;
- struct curltime start = curlx_now();
- TCHAR *tchar_oldpath = curlx_convert_UTF8_to_tchar(oldpath);
- TCHAR *tchar_newpath = curlx_convert_UTF8_to_tchar(newpath);
- for(;;) {
- timediff_t diff;
- if(MoveFileEx(tchar_oldpath, tchar_newpath, MOVEFILE_REPLACE_EXISTING)) {
- curlx_free(tchar_oldpath);
- curlx_free(tchar_newpath);
- break;
- }
- diff = curlx_timediff_ms(curlx_now(), start);
- if(diff < 0 || diff > max_wait_ms) {
- curlx_free(tchar_oldpath);
- curlx_free(tchar_newpath);
- return 1;
- }
- Sleep(1);
- }
-#else
- if(rename(oldpath, newpath))
- return 1;
-#endif
- return 0;
-}
-
-#endif
lib/rename.h+0 -29
@@ -1,29 +0,0 @@
-#ifndef HEADER_CURL_RENAME_H
-#define HEADER_CURL_RENAME_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * SPDX-License-Identifier: curl
- *
- ***************************************************************************/
-
-int Curl_rename(const char *oldpath, const char *newpath);
-
-#endif /* HEADER_CURL_RENAME_H */
scripts/checksrc.pl+4 -0
@@ -92,12 +92,16 @@ my %banfunc = (
"localtime" => 1,
"malloc" => 1,
"mbstowcs" => 1,
+ "MoveFileEx" => 1,
+ "MoveFileExA" => 1,
+ "MoveFileExW" => 1,
"msnprintf" => 1,
"mvsnprintf" => 1,
"open" => 1,
"printf" => 1,
"realloc" => 1,
"recv" => 1,
+ "rename" => 1,
"send" => 1,
"snprintf" => 1,
"socket" => 1,