[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
319/376: Use posix_spawn to run the pager
From: |
Ludovic Courtès |
Subject: |
319/376: Use posix_spawn to run the pager |
Date: |
Wed, 28 Jan 2015 22:05:53 +0000 |
civodul pushed a commit to tag 1.8
in repository guix.
commit d34d2b2bbf784c0bb420a50905af25e02c6e4989
Author: Eelco Dolstra <address@hidden>
Date: Fri Dec 5 20:34:41 2014 +0100
Use posix_spawn to run the pager
In low memory environments, "nix-env -qa" failed because the fork to
run the pager hit the kernel's overcommit limits. Using posix_spawn
gets around this. (Actually, you have to use posix_spawn with the
undocumented POSIX_SPAWN_USEVFORK flag, otherwise it just uses
fork/exec...)
---
src/libmain/shared.cc | 38 ++++++++++++++++++++++++++++++--------
src/libutil/types.hh | 1 +
src/libutil/util.cc | 10 ++++++++--
3 files changed, 39 insertions(+), 10 deletions(-)
diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc
index c4b5c21..d0c75a8 100644
--- a/src/libmain/shared.cc
+++ b/src/libmain/shared.cc
@@ -15,6 +15,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>
+#include <spawn.h>
namespace nix {
@@ -305,14 +306,35 @@ RunPager::RunPager()
Pipe toPager;
toPager.create();
- pid = startProcess([&]() {
- if (dup2(toPager.readSide, STDIN_FILENO) == -1)
- throw SysError("dupping stdin");
- if (!getenv("LESS"))
- setenv("LESS", "FRSXMK", 1);
- execl("/bin/sh", "sh", "-c", pager.c_str(), NULL);
- throw SysError(format("executing ‘%1%’") % pager);
- });
+ // FIXME: should do this in the child environment.
+ if (!getenv("LESS"))
+ setenv("LESS", "FRSXMK", 1);
+
+ /* Start the pager using posix_spawn. */
+ pid_t pid_;
+ const char * argv[] = { "sh", "-c", pager.c_str(), 0 };
+
+ posix_spawn_file_actions_t fileActions;
+ int err = posix_spawn_file_actions_init(&fileActions);
+ if (err) throw SysError(err, "creating POSIX file actions");
+ err = posix_spawn_file_actions_adddup2(&fileActions, toPager.readSide,
STDIN_FILENO);
+ if (err) throw SysError(err, "adding to POSIX file actions");
+
+ posix_spawnattr_t spawnAttrs;
+ err = posix_spawnattr_init(&spawnAttrs);
+ if (err) throw SysError(err, "creating POSIX spawn attrs");
+#ifdef POSIX_SPAWN_USEVFORK
+ err = posix_spawnattr_setflags(&spawnAttrs, POSIX_SPAWN_USEVFORK);
+ if (err) throw SysError(err, "setting POSIX spawn attr flag");
+#endif
+
+ err = posix_spawn(&pid_, "/bin/sh", &fileActions, &spawnAttrs, (char *
const *) argv, environ);
+
+ posix_spawn_file_actions_destroy(&fileActions);
+ posix_spawnattr_destroy(&spawnAttrs);
+
+ if (err) throw SysError(err, format("running ‘%1%’") % pager);
+ pid = pid_;
if (dup2(toPager.writeSide, STDOUT_FILENO) == -1)
throw SysError("dupping stdout");
diff --git a/src/libutil/types.hh b/src/libutil/types.hh
index 160884e..030996a 100644
--- a/src/libutil/types.hh
+++ b/src/libutil/types.hh
@@ -73,6 +73,7 @@ class SysError : public Error
public:
int errNo;
SysError(const FormatOrString & fs);
+ SysError(int errNo, const FormatOrString & fs);
};
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 305e470..60be02c 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -45,8 +45,14 @@ BaseError & BaseError::addPrefix(const FormatOrString & fs)
SysError::SysError(const FormatOrString & fs)
- : Error(format("%1%: %2%") % fs.s % strerror(errno))
- , errNo(errno)
+ : SysError(errno, fs)
+{
+}
+
+
+SysError::SysError(int errNo, const FormatOrString & fs)
+ : Error(format("%1%: %2%") % fs.s % strerror(errNo))
+ , errNo(errNo)
{
}
- 309/376: More build-cache-failures -> build-cache-failure, (continued)
- 309/376: More build-cache-failures -> build-cache-failure, Ludovic Courtès, 2015/01/28
- 310/376: forceString(): Accept pos argument, Ludovic Courtès, 2015/01/28
- 311/376: Add a primop for regular expression pattern matching, Ludovic Courtès, 2015/01/28
- 312/376: Rely on XML catalogs to find the DocBook schemas and stylesheets, Ludovic Courtès, 2015/01/28
- 313/376: Intro: Mention binary caches, Ludovic Courtès, 2015/01/28
- 303/376: Manual: Bump date, Ludovic Courtès, 2015/01/28
- 315/376: Make all ExternalValueBase functions const, Ludovic Courtès, 2015/01/28
- 318/376: Shut up a warning, Ludovic Courtès, 2015/01/28
- 317/376: Fix another operator precedence issue found by Perl 5.20, Ludovic Courtès, 2015/01/28
- 322/376: Remove Fedora 18, 19 builds, Ludovic Courtès, 2015/01/28
- 319/376: Use posix_spawn to run the pager,
Ludovic Courtès <=
- 321/376: Remove some platforms with too-old compilers, Ludovic Courtès, 2015/01/28
- 323/376: Explicitly include required C headers, Ludovic Courtès, 2015/01/28
- 316/376: Merge pull request #401 from shlevy/external-value, Ludovic Courtès, 2015/01/28
- 314/376: Allow external code using libnixexpr to add types, Ludovic Courtès, 2015/01/28
- 328/376: Provide some fallback defaults for the CA bundle, Ludovic Courtès, 2015/01/28
- 329/376: Add option to disable binary cache certificate checking, Ludovic Courtès, 2015/01/28
- 330/376: Doh, Ludovic Courtès, 2015/01/28
- 327/376: Use https://cache.nixos.org instead of http://cache.nixos.org, Ludovic Courtès, 2015/01/28
- 331/376: Fix bad comment, Ludovic Courtès, 2015/01/28
- 320/376: Define ‘environ’, Ludovic Courtès, 2015/01/28