mirror of
https://github.com/curl/curl.git
synced 2026-04-15 01:01:41 +03:00
tool_operate: when retrying, only truncate regular files
If /dev/null or another character device etc is used for output, trying to truncate that only causes errors. Add test 1497 to verify Fixes #17371 Reported-by: Brendan Dolan-Gavitt Closes #17374
This commit is contained in:
parent
6414cc6ae1
commit
99f5c5c794
3 changed files with 99 additions and 26 deletions
|
|
@ -587,37 +587,49 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
|
|||
if(per->retry_sleep > RETRY_SLEEP_MAX)
|
||||
per->retry_sleep = RETRY_SLEEP_MAX;
|
||||
}
|
||||
|
||||
if(outs->bytes && outs->filename && outs->stream) {
|
||||
/* We have written data to an output file, we truncate file
|
||||
*/
|
||||
notef(config->global,
|
||||
"Throwing away %" CURL_FORMAT_CURL_OFF_T " bytes",
|
||||
outs->bytes);
|
||||
fflush(outs->stream);
|
||||
/* truncate file at the position where we started appending */
|
||||
#ifndef __MINGW32CE__
|
||||
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) &&
|
||||
S_ISREG(fileinfo.st_mode))
|
||||
#else
|
||||
/* Windows CE's fileno() is bad so just skip the check */
|
||||
#endif
|
||||
{
|
||||
/* We have written data to an output file, we truncate file */
|
||||
fflush(outs->stream);
|
||||
notef(config->global,
|
||||
"Throwing away %" CURL_FORMAT_CURL_OFF_T " bytes",
|
||||
outs->bytes);
|
||||
/* truncate file at the position where we started appending */
|
||||
#if defined(HAVE_FTRUNCATE) && !defined(__DJGPP__) && !defined(__AMIGA__) && \
|
||||
!defined(__MINGW32CE__)
|
||||
if(ftruncate(fileno(outs->stream), outs->init)) {
|
||||
/* when truncate fails, we cannot just append as then we will
|
||||
create something strange, bail out */
|
||||
errorf(config->global, "Failed to truncate file");
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
/* now seek to the end of the file, the position where we
|
||||
just truncated the file in a large file-safe way */
|
||||
rc = fseek(outs->stream, 0, SEEK_END);
|
||||
if(ftruncate(fileno(outs->stream), outs->init)) {
|
||||
/* when truncate fails, we cannot just append as then we will
|
||||
create something strange, bail out */
|
||||
errorf(config->global, "Failed to truncate file");
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
/* now seek to the end of the file, the position where we
|
||||
just truncated the file in a large file-safe way */
|
||||
rc = fseek(outs->stream, 0, SEEK_END);
|
||||
#else
|
||||
/* ftruncate is not available, so just reposition the file
|
||||
to the location we would have truncated it. This will not
|
||||
work properly with large files on 32-bit systems, but
|
||||
most of those will have ftruncate. */
|
||||
rc = fseek(outs->stream, (long)outs->init, SEEK_SET);
|
||||
/* ftruncate is not available, so just reposition the file
|
||||
to the location we would have truncated it. This will not
|
||||
work properly with large files on 32-bit systems, but
|
||||
most of those will have ftruncate. */
|
||||
rc = fseek(outs->stream, (long)outs->init, SEEK_SET);
|
||||
#endif
|
||||
if(rc) {
|
||||
errorf(config->global, "Failed seeking to end of file");
|
||||
return CURLE_WRITE_ERROR;
|
||||
if(rc) {
|
||||
errorf(config->global, "Failed seeking to end of file");
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
outs->bytes = 0; /* clear for next round */
|
||||
}
|
||||
outs->bytes = 0; /* clear for next round */
|
||||
}
|
||||
*retryp = TRUE;
|
||||
per->num_retries++;
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ test1460 test1461 test1462 test1463 test1464 test1465 test1466 test1467 \
|
|||
test1468 test1469 test1470 test1471 test1472 test1473 test1474 test1475 \
|
||||
test1476 test1477 test1478 test1479 test1480 test1481 test1482 test1483 \
|
||||
test1484 test1485 test1486 test1487 test1488 test1489 test1490 test1491 \
|
||||
test1492 test1493 test1494 test1495 test1496 \
|
||||
test1492 test1493 test1494 test1495 test1496 test1497 \
|
||||
\
|
||||
test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \
|
||||
test1508 test1509 test1510 test1511 test1512 test1513 test1514 test1515 \
|
||||
|
|
|
|||
61
tests/data/test1497
Normal file
61
tests/data/test1497
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
HTTP
|
||||
HTTP GET
|
||||
retry
|
||||
</keywords>
|
||||
</info>
|
||||
#
|
||||
# Server-side
|
||||
<reply>
|
||||
<data nocheck="yes">
|
||||
HTTP/1.1 503 BAD swsbounce
|
||||
Date: Tue, 09 Nov 2010 14:49:00 GMT
|
||||
Content-Length: 21
|
||||
|
||||
server not available
|
||||
</data>
|
||||
<data1 nocheck="yes">
|
||||
HTTP/1.1 200 OK
|
||||
Date: Tue, 09 Nov 2010 14:49:00 GMT
|
||||
Content-Length: 3
|
||||
Connection: close
|
||||
|
||||
ok
|
||||
</data1>
|
||||
|
||||
</reply>
|
||||
|
||||
#
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
http
|
||||
</server>
|
||||
<name>
|
||||
HTTP GET --retry on 503 error with output to /dev/null
|
||||
</name>
|
||||
<command>
|
||||
http://%HOSTIP:%HTTPPORT/%TESTNUMBER --retry 3 -o /dev/null
|
||||
</command>
|
||||
</client>
|
||||
|
||||
#
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<protocol>
|
||||
GET /%TESTNUMBER HTTP/1.1
|
||||
Host: %HOSTIP:%HTTPPORT
|
||||
User-Agent: curl/%VERSION
|
||||
Accept: */*
|
||||
|
||||
GET /%TESTNUMBER HTTP/1.1
|
||||
Host: %HOSTIP:%HTTPPORT
|
||||
User-Agent: curl/%VERSION
|
||||
Accept: */*
|
||||
|
||||
</protocol>
|
||||
|
||||
</verify>
|
||||
</testcase>
|
||||
Loading…
Add table
Add a link
Reference in a new issue