Actually prefer /dev/full over /dev/null as a replacement for stdin

* lib/stdopen.c (stdopen): Fix improper condition.
Avoid leaking extra file descriptor.
* src/tar.c (main): Set name of the stdout for diagnostics.
Bail out if stdopen fails.
This commit is contained in:
Sergey Poznyakoff
2021-01-08 17:34:19 +02:00
parent 0836a51147
commit e4d1edadef
2 changed files with 14 additions and 4 deletions

View File

@@ -52,15 +52,22 @@ stdopen (void)
static const int contrary_mode[]
= { O_WRONLY, O_RDONLY, O_RDONLY };
int mode = contrary_mode[fd];
int new_fd;
int new_fd = -1;
/* Open /dev/null with the contrary mode so that the typical
read (stdin) or write (stdout, stderr) operation will fail.
With descriptor 0, we can do even better on systems that
have /dev/full, by opening that write-only instead of
/dev/null. The only drawback is that a write-provoked
failure comes with a misleading errno value, ENOSPC. */
if (mode == O_RDONLY
|| (new_fd = open ("/dev/full", mode) != fd))
if (mode == O_WRONLY)
{
if ((new_fd = open ("/dev/full", mode)) != fd)
{
close (new_fd);
new_fd = -1;
}
}
if (new_fd == -1)
new_fd = open ("/dev/null", mode);
if (new_fd != fd)
{

View File

@@ -2751,8 +2751,11 @@ main (int argc, char **argv)
set_quoting_style (0, DEFAULT_QUOTING_STYLE);
close_stdout_set_file_name (_("stdout"));
/* Make sure we have first three descriptors available */
stdopen ();
if (!stdopen ())
FATAL_ERROR ((0, errno, "%s",
_("failed to ensure first three descriptors are available")));
/* Pre-allocate a few structures. */