Set the O_CLOEXEC flag on pipes opened with popen. Currently this is implemented by using the glibc-specific "e" mode character (which will probably be part of a future revision of POSIX), but in the future we could change to fall back to using an fcntl call if portability to other C libraries is wanted.
There are no users for the underlying fd after an exec as far as I can tell (checked by looking for calls to fileno()). There are some pipes whose fds should be inherited, but naturally enough they use pipe() instead of popen(). Signed-off-by: Jonathan Nieder <jrnie...@gmail.com> --- cpp/console/handlers/shell.cpp | 2 +- cpp/lib/include/cupt/file.hpp | 4 +++- cpp/lib/src/cache.cpp | 2 +- cpp/lib/src/config.cpp | 2 +- cpp/lib/src/file.cpp | 4 ++-- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/cpp/console/handlers/shell.cpp b/cpp/console/handlers/shell.cpp index 23b239f..a472e50 100644 --- a/cpp/console/handlers/shell.cpp +++ b/cpp/console/handlers/shell.cpp @@ -125,7 +125,7 @@ void convertLineToArgcArgv(const string& line, int& argc, char**& argv) string errorString; // 'A' - to not let echo interpret $word as an option string shellCommand = sf("(for word in %s; do echo A$word; done)", line.c_str()); - File pipe(shellCommand, "pr", errorString); + File pipe(shellCommand, "pre", errorString); if (!errorString.empty()) { fatal("unable to open internal shell pipe: %s", errorString.c_str()); diff --git a/cpp/lib/include/cupt/file.hpp b/cpp/lib/include/cupt/file.hpp index 4610c4e..0dfeb5a 100644 --- a/cpp/lib/include/cupt/file.hpp +++ b/cpp/lib/include/cupt/file.hpp @@ -44,7 +44,9 @@ class File * @warning You must not use constructed object if @a error is not empty. * * @param path path to file or shell command, see @a mode - * @param mode any value, accepted as @a mode in @c fopen(3), or @c "pr" - special value to treat @a path as shell pipe + * @param mode any value, accepted as @a mode in @c fopen(3), or + * @c "pre" - special value to treat @a path as shell pipe + * closed on exec * @param [out] error if open fails, human readable error will be placed here */ File(const string& path, const char* mode, string& error); diff --git a/cpp/lib/src/cache.cpp b/cpp/lib/src/cache.cpp index 9c0a55b..88fccea 100644 --- a/cpp/lib/src/cache.cpp +++ b/cpp/lib/src/cache.cpp @@ -353,7 +353,7 @@ bool Cache::verifySignature(const shared_ptr< const Config >& config, const stri string gpgCommand = string("gpgv --status-fd 1 --keyring ") + keyringPath + ' ' + signaturePath + ' ' + path + " 2>/dev/null || true"; string openError; - File gpgPipe(gpgCommand, "pr", openError); + File gpgPipe(gpgCommand, "pre", openError); if (!openError.empty()) { fatal("unable to open gpg pipe: %s", openError.c_str()); diff --git a/cpp/lib/src/config.cpp b/cpp/lib/src/config.cpp index 3c6f3ec..45fe22d 100644 --- a/cpp/lib/src/config.cpp +++ b/cpp/lib/src/config.cpp @@ -311,7 +311,7 @@ void ConfigImpl::readConfigs(Config* config) static string qx(const string& shellCommand) { string openError; - File file(shellCommand, "pr", openError); // reading from pipe + File file(shellCommand, "pre", openError); // reading from pipe if (!openError.empty()) { fatal("unable to open pipe '%s': %s", shellCommand.c_str(), openError.c_str()); diff --git a/cpp/lib/src/file.cpp b/cpp/lib/src/file.cpp index 0bf6a87..28f9ced 100644 --- a/cpp/lib/src/file.cpp +++ b/cpp/lib/src/file.cpp @@ -44,11 +44,11 @@ struct FileImpl FileImpl::FileImpl(const string& path_, const char* mode, string& openError) : handle(NULL), buf(NULL), bufLength(0), path(path_), isPipe(false) { - if (strcmp(mode, "pr") == 0) + if (strcmp(mode, "pre") == 0) { // need to open read pipe isPipe = true; - handle = popen(path.c_str(), "r"); + handle = popen(path.c_str(), "re"); } else { -- 1.7.4.1 -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org