diff --git a/docs/internals/CODE_STYLE.md b/docs/internals/CODE_STYLE.md index 9a2709885a..ee5bdbb562 100644 --- a/docs/internals/CODE_STYLE.md +++ b/docs/internals/CODE_STYLE.md @@ -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 diff --git a/lib/Makefile.inc b/lib/Makefile.inc index cdd5587ec8..bc2bdb0c36 100644 --- a/lib/Makefile.inc +++ b/lib/Makefile.inc @@ -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 \ diff --git a/lib/altsvc.c b/lib/altsvc.c index df6b2a05f6..d40b9d0e46 100644 --- a/lib/altsvc.c +++ b/lib/altsvc.c @@ -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) diff --git a/lib/cookie.c b/lib/cookie.c index 0310fb0c6d..05a49f2d5e 100644 --- a/lib/cookie.c +++ b/lib/cookie.c @@ -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; } diff --git a/lib/curlx/fopen.c b/lib/curlx/fopen.c index c1399135b3..ac2552a1c3 100644 --- a/lib/curlx/fopen.c +++ b/lib/curlx/fopen.c @@ -44,6 +44,7 @@ int curlx_fseek(void *stream, curl_off_t offset, int whence) #include /* 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 diff --git a/lib/curlx/fopen.h b/lib/curlx/fopen.h index bc10812007..4cda50df1c 100644 --- a/lib/curlx/fopen.h +++ b/lib/curlx/fopen.h @@ -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 diff --git a/lib/hsts.c b/lib/hsts.c index 2dd22a8568..e757574f51 100644 --- a/lib/hsts.c +++ b/lib/hsts.c @@ -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) diff --git a/lib/rename.c b/lib/rename.c deleted file mode 100644 index c2f979a16f..0000000000 --- a/lib/rename.c +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , 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 diff --git a/lib/rename.h b/lib/rename.h deleted file mode 100644 index 04440820c5..0000000000 --- a/lib/rename.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef HEADER_CURL_RENAME_H -#define HEADER_CURL_RENAME_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , 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 */ diff --git a/scripts/checksrc.pl b/scripts/checksrc.pl index 978959008f..33cd4bb246 100755 --- a/scripts/checksrc.pl +++ b/scripts/checksrc.pl @@ -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,