Better file-existence test on Unix.

Now we don't annoyingly print the 'askappend' prompt if you ask a
PuTTY tool to write its packet log to something that's not a regular
file, such as /dev/fd/1 or /dev/tty or a named pipe.

(In the case of a named pipe, another annoyance fixed by this change
is that we also don't open it for reading in the course of the
existence test.)
This commit is contained in:
Simon Tatham 2018-02-07 07:27:57 +00:00
Родитель bbebdc8280
Коммит b4fde270c6
1 изменённых файлов: 30 добавлений и 5 удалений

Просмотреть файл

@ -352,11 +352,36 @@ char *make_dir_path(const char *path, mode_t mode)
int open_for_write_would_lose_data(const Filename *fn)
{
FILE *fp;
if ((fp = f_open(fn, "r", FALSE)) != NULL) {
fclose(fp);
return TRUE;
} else {
struct stat st;
if (stat(fn->path, &st) < 0) {
/*
* If the file doesn't even exist, we obviously want to return
* false. If we failed to stat it for any other reason,
* ignoring the precise error code and returning false still
* doesn't seem too unreasonable, because then we'll try to
* open the file for writing and report _that_ error, which is
* likely to be more to the point.
*/
return FALSE;
}
/*
* OK, something exists at this pathname and we've found out
* something about it. But an open-for-write will only
* destructively truncate it if it's a regular file with nonzero
* size. If it's empty, or some other kind of special thing like a
* character device (e.g. /dev/tty) or a named pipe, then opening
* it for write is already non-destructive and it's pointless and
* annoying to warn about it just because the same file can be
* opened for reading. (Indeed, if it's a named pipe, opening it
* for reading actually _causes inconvenience_ in its own right,
* even before the question of whether it gives misleading
* information.)
*/
if (S_ISREG(st.st_mode) && st.st_size > 0) {
return TRUE;
}
return FALSE;
}