From: Daniel Stenberg Date: Thu, 24 Feb 2022 09:30:10 +0000 (+0100) Subject: curl: add --remove-on-error X-Git-Tag: curl-7_83_0~162 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=08a96c6e4e6cf6a1917a117db1b5394713e3f01f;p=thirdparty%2Fcurl.git curl: add --remove-on-error If a transfer returns an error, using this option makes curl remove the leftover downloded (partial) local file before exiting. Added test 376 to verify Closes #8503 --- diff --git a/docs/cmdline-opts/Makefile.inc b/docs/cmdline-opts/Makefile.inc index afa3d7931f..3f6d00831a 100644 --- a/docs/cmdline-opts/Makefile.inc +++ b/docs/cmdline-opts/Makefile.inc @@ -203,6 +203,7 @@ DPAGES = \ remote-name-all.d \ remote-name.d \ remote-time.d \ + remove-on-error.d \ request-target.d \ request.d \ resolve.d \ diff --git a/docs/cmdline-opts/remove-on-error.d b/docs/cmdline-opts/remove-on-error.d new file mode 100644 index 0000000000..7c4b83a5c2 --- /dev/null +++ b/docs/cmdline-opts/remove-on-error.d @@ -0,0 +1,12 @@ +Long: remove-on-error +Help: Remove output file on errors +See-also: fail +Category: curl +Example: --remove-on-error -o output $URL +Added: 7.83.0 +--- +When curl returns an error when told to save output in a local file, this +option removes that saved file before exiting. This prevevents curl from +leaving a partial file in the case of an error during transfer. + +If the output is not a file, this option has no effect. diff --git a/docs/options-in-versions b/docs/options-in-versions index 5d242b8ffc..559a332760 100644 --- a/docs/options-in-versions +++ b/docs/options-in-versions @@ -191,6 +191,7 @@ --remote-name (-O) 4.0 --remote-name-all 7.19.0 --remote-time (-R) 7.9 +--remove-on-error 7.83.0 --request (-X) 6.0 --request-target 7.55.0 --resolve 7.21.3 diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h index a06ef60281..4a420db32d 100644 --- a/src/tool_cfgable.h +++ b/src/tool_cfgable.h @@ -294,6 +294,8 @@ struct OperationConfig { struct OperationConfig *prev; struct OperationConfig *next; /* Always last in the struct */ struct State state; /* for create_transfer() */ + bool rm_partial; /* on error, remove partially written output + files */ }; struct GlobalConfig { diff --git a/src/tool_getparam.c b/src/tool_getparam.c index 56964394b7..b31583299c 100644 --- a/src/tool_getparam.c +++ b/src/tool_getparam.c @@ -284,6 +284,7 @@ static const struct LongShort aliases[]= { {"fb", "styled-output", ARG_BOOL}, {"fc", "mail-rcpt-allowfails", ARG_BOOL}, {"fd", "fail-with-body", ARG_BOOL}, + {"fe", "remove-on-error", ARG_BOOL}, {"F", "form", ARG_STRING}, {"Fs", "form-string", ARG_STRING}, {"g", "globoff", ARG_BOOL}, @@ -1830,7 +1831,10 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ case 'd': /* --fail-with-body */ config->failwithbody = toggle; break; - default: /* --fail (hard on errors) */ + case 'e': /* --remove-on-error */ + config->rm_partial = toggle; + break; + default: /* --fail (hard on errors) */ config->failonerror = toggle; break; } diff --git a/src/tool_listhelp.c b/src/tool_listhelp.c index 3bca52c0e6..33ebda25fd 100644 --- a/src/tool_listhelp.c +++ b/src/tool_listhelp.c @@ -574,6 +574,9 @@ const struct helptxt helptext[] = { {"-R, --remote-time", "Set the remote file's time on the local output", CURLHELP_OUTPUT}, + {" --remove-on-error", + "Remove output file on errors", + CURLHELP_CURL}, {"-X, --request ", "Specify request method to use", CURLHELP_CONNECTION}, diff --git a/src/tool_operate.c b/src/tool_operate.c index 37ff44795f..2e576d0d0e 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -595,6 +595,10 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, if(global->showerror) fprintf(global->errors, "curl: (%d) Failed writing body\n", result); } + if(result && config->rm_partial) { + notef(global, "Removing output file: %s", per->outfile); + unlink(per->outfile); + } } /* File time can only be set _after_ the file has been closed */ diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc index 80901c7719..6a32dd6782 100644 --- a/tests/data/Makefile.inc +++ b/tests/data/Makefile.inc @@ -61,7 +61,7 @@ test334 test335 test336 test337 test338 test339 test340 test341 test342 \ test343 test344 test345 test346 test347 test348 test349 test350 test351 \ test352 test353 test354 test355 test356 test357 test358 test359 test360 \ test361 test362 test363 test364 test365 test366 test367 test368 test369 \ -test370 test371 test372 test373 test374 test375 \ +test370 test371 test372 test373 test374 test375 test376 \ \ test380 test381 test383 test384 test385 test386 \ \ diff --git a/tests/data/test376 b/tests/data/test376 new file mode 100644 index 0000000000..7406d5b247 --- /dev/null +++ b/tests/data/test376 @@ -0,0 +1,64 @@ + + + +HTTP +HTTP GET + + + +# +# Crafted to cause error 18 + + +HTTP/1.1 200 OK swsclose +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT +ETag: "21025-dc7-39462498" +Accept-Ranges: bytes +Content-Length: 75 +Connection: close +Content-Type: text/html +Funny-head: yesyes + +-foo- + + + +# +# Client-side + + +http + + +HTTP GET + + +http://%HOSTIP:%HTTPPORT/%TESTNUMBER -o log/save-%TESTNUMBER --remove-on-error + + + +# +# Verify data after the test has been "shot". hyper doesn't do error 18 + + +%if hyper +56 +%else +18 +%endif + + +GET /%TESTNUMBER HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* + + + +# the file should be empty now + + + +