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

View File

@@ -2751,8 +2751,11 @@ main (int argc, char **argv)
set_quoting_style (0, DEFAULT_QUOTING_STYLE); set_quoting_style (0, DEFAULT_QUOTING_STYLE);
close_stdout_set_file_name (_("stdout"));
/* Make sure we have first three descriptors available */ /* 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. */ /* Pre-allocate a few structures. */