From: Paul Eggert Date: Thu, 17 Aug 2017 15:03:57 +0000 (-0700) Subject: sort: file descriptor discipline X-Git-Tag: v8.28~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=717f1d02e1707b18271a83812989e778c6f5cb77;p=thirdparty%2Fcoreutils.git sort: file descriptor discipline Use O_CLOEXEC when creating file descriptors, so that subsidiary processes do not inherit file descriptors that they do not need. This is helpful for ‘sort’, as it is a multithreaded program that forks and execs. * bootstrap.conf (gnulib_modules): Add mkostemp, open, pipe2. * src/sort.c (create_temp_file): Open temporary file with O_CLOEXEC. (stream_open): Open the stream with O_CLOEXEC. (pipe_fork): Create the pipe with O_CLOEXEC. (check_output): Open the output file with O_CLOEXEC. (main): Use xfopen/xfclose to handle --files0-from, so that O_CLOEXEC is used properly. This is simpler anyway. * tests/misc/sort-files0-from.pl: Adjust to change in diagnostic wording. --- diff --git a/bootstrap.conf b/bootstrap.conf index f8f65f746f..53c52f28ef 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -171,6 +171,7 @@ gnulib_modules=" mkdir-p mkfifo mknod + mkostemp mkstemp mktime modechange @@ -180,11 +181,13 @@ gnulib_modules=" non-recursive-gnulib-prefix-hack nproc obstack + open parse-datetime pathmax perl physmem pipe-posix + pipe2 posix-shell posixtm posixver diff --git a/src/sort.c b/src/sort.c index ba6ceac276..47b915fcc4 100644 --- a/src/sort.c +++ b/src/sort.c @@ -868,7 +868,7 @@ create_temp_file (int *pfd, bool survive_fd_exhaustion) /* Create the temporary file in a critical section, to avoid races. */ cs = cs_enter (); - fd = mkstemp (file); + fd = mkostemp (file, O_CLOEXEC); if (0 <= fd) { *temptail = node; @@ -951,7 +951,10 @@ stream_open (char const *file, char const *how) fp = stdin; } else - fp = fopen (file, how); + { + int fd = open (file, O_RDONLY | O_CLOEXEC); + fp = fd < 0 ? NULL : fdopen (fd, how); + } fadvise (fp, FADVISE_SEQUENTIAL); } else if (*how == 'w') @@ -1031,7 +1034,7 @@ pipe_fork (int pipefds[2], size_t tries) pid_t pid IF_LINT ( = -1); struct cs_status cs; - if (pipe (pipefds) < 0) + if (pipe2 (pipefds, O_CLOEXEC) < 0) return -1; /* At least NMERGE + 1 subprocesses are needed. More could be created, but @@ -3764,7 +3767,8 @@ check_output (char const *outfile) { if (outfile) { - int outfd = open (outfile, O_WRONLY | O_CREAT | O_BINARY, MODE_RW_UGO); + int oflags = O_WRONLY | O_BINARY | O_CLOEXEC | O_CREAT; + int outfd = open (outfile, oflags, MODE_RW_UGO); if (outfd < 0) sort_die (_("open failed"), outfile); move_fd_or_die (outfd, STDOUT_FILENO); @@ -4578,8 +4582,6 @@ main (int argc, char **argv) if (files_from) { - FILE *stream; - /* When using --files0-from=F, you may not specify any files on the command-line. */ if (nfiles) @@ -4590,21 +4592,14 @@ main (int argc, char **argv) usage (SORT_FAILURE); } - if (STREQ (files_from, "-")) - stream = stdin; - else - { - stream = fopen (files_from, "r"); - if (stream == NULL) - die (SORT_FAILURE, errno, _("cannot open %s for reading"), - quoteaf (files_from)); - } + FILE *stream = xfopen (files_from, "r"); readtokens0_init (&tok); - if (! readtokens0 (stream, &tok) || fclose (stream) != 0) + if (! readtokens0 (stream, &tok)) die (SORT_FAILURE, 0, _("cannot read file names from %s"), quoteaf (files_from)); + xfclose (stream, files_from); if (tok.n_tok) { diff --git a/tests/misc/sort-files0-from.pl b/tests/misc/sort-files0-from.pl index 366f59ff31..a7ec676aad 100755 --- a/tests/misc/sort-files0-from.pl +++ b/tests/misc/sort-files0-from.pl @@ -37,7 +37,7 @@ my @Tests = # missing input file ['missing', '--files0-from=missing', {EXIT=>2}, - {ERR => "$prog: cannot open 'missing' for reading: " + {ERR => "$prog: open failed: missing: " . "No such file or directory\n"}], # input file name of '-'