curlx: add `curlx_rename()`, fix to support long filenames on Windows
No binary (build failed)
—
(log yok)
| @@ -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 | |
| @@ -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 \ | |
| @@ -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) | |
| @@ -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; | |
| } | |
| @@ -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 | |
| @@ -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 | |
| @@ -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) | |
| @@ -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 |
| @@ -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 */ |
| @@ -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, | |