src: use ftruncate() unconditionally

Systems without it need to provide a custom alternative just like we
have have for Windows. This adds an MSDOS version that fails if trying
to truncate a too large file.

Closes #21109
This commit is contained in:
Daniel Stenberg 2026-03-26 23:03:53 +01:00
parent d63432d1f8
commit 6041b9b11b
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
4 changed files with 23 additions and 12 deletions

View File

@ -272,15 +272,9 @@ static size_t save_etag(const char *etag_h, const char *endp,
/*
* Truncate regular files to avoid stale etag content.
*/
#ifdef HAVE_FTRUNCATE
if(ftruncate(fileno(etag_save->stream), 0))
return CURL_WRITEFUNC_ERROR;
#else
if(fseek(etag_save->stream, 0, SEEK_SET))
return CURL_WRITEFUNC_ERROR;
#endif
}
fwrite(etag_h, 1, etag_length, etag_save->stream);
/* terminate with newline */
fputc('\n', etag_save->stream);

View File

@ -558,7 +558,7 @@ static CURLcode retrycheck(struct OperationConfig *config,
fflush(outs->stream);
notef("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__)
if(ftruncate(fileno(outs->stream), outs->init)) {
/* when truncate fails, we cannot append as then we
create something strange, bail out */
@ -568,11 +568,7 @@ static CURLcode retrycheck(struct OperationConfig *config,
/* now seek to the end of the file, the position where we
truncated the file in a large file-safe way */
rc = fseek(outs->stream, 0, SEEK_END);
#else
/* ftruncate is not available, so reposition the file to the location
we would have truncated it. */
rc = curlx_fseek(outs->stream, outs->init, SEEK_SET);
#endif
if(rc) {
errorf("Failed seeking to end of file");
return CURLE_WRITE_ERROR;

View File

@ -108,6 +108,14 @@ int tool_ftruncate64(int fd, curl_off_t where);
#endif /* !HAVE_FTRUNCATE */
#endif /* _WIN32 */
#ifdef __DJGPP__
int msdos_ftruncate(int fd, curl_off_t where);
#undef HAVE_FTRUNCATE
#undef ftruncate /* to be sure */
#define ftruncate(fd, where) msdos_ftruncate(fd, where)
#define USE_MSDOS_FTRUNCATE 1
#endif
#ifdef CURL_CA_EMBED
extern const unsigned char curl_ca_embed[];
#endif

View File

@ -96,6 +96,19 @@ int tool_ftruncate64(int fd, curl_off_t where)
}
#endif /* USE_TOOL_FTRUNCATE */
#ifdef USE_MSDOS_FTRUNCATE
/*
* Only supports 'off_t' (signed 32 bit) as file size.
*/
int msdos_ftruncate(int fd, curl_off_t where)
{
if(where > INT_MAX)
return -1;
return ftruncate(fd, (off_t) where);
}
#endif /* USE_MSDOS_FTRUNCATE */
#ifdef _WIN32
FILE *tool_execpath(const char *filename, char **pathp)
{