about summary refs log tree commit diff
path: root/src/libutil
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2007-10-27T00·46+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2007-10-27T00·46+0000
commit9397cd30c8a6ffd65fc3b85985ea59ecfb72672b (patch)
treea3382c4031b84e518e6d8a133a98cdc84ba8e3d1 /src/libutil
parent0b4ed64d295316146fc4de8a5a2e971b771058b8 (diff)
* Support for doing builds in a chroot under Linux. The builder is
  executed in a chroot that contains just the Nix store, the temporary
  build directory, and a configurable set of additional directories
  (/dev and /proc by default).  This allows a bit more purity
  enforcement: hidden build-time dependencies on directories such as
  /usr or /nix/var/nix/profiles are no longer possible.  As an added
  benefit, accidental network downloads (cf. NIXPKGS-52) are prevented
  as well (because files such as /etc/resolv.conf are not available in
  the chroot).

  However the usefulness of chroots is diminished by the fact that
  many builders depend on /bin/sh, so you need /bin in the list of
  additional directories.  (And then on non-NixOS you need /lib as
  well...)

Diffstat (limited to 'src/libutil')
-rw-r--r--src/libutil/util.cc32
-rw-r--r--src/libutil/util.hh8
2 files changed, 28 insertions, 12 deletions
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index d8d3751a1fc3..428b1ff9a755 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -350,13 +350,16 @@ Path createTempDir(const Path & tmpRoot)
 }
 
 
-void createDirs(const Path & path)
+Paths createDirs(const Path & path)
 {
-    if (path == "/") return;
-    createDirs(dirOf(path));
-    if (!pathExists(path))
+    if (path == "/") return Paths();
+    Paths created = createDirs(dirOf(path));
+    if (!pathExists(path)) {
         if (mkdir(path.c_str(), 0777) == -1)
             throw SysError(format("creating directory `%1%'") % path);
+        created.push_back(path);
+    }
+    return created;
 }
 
 
@@ -509,14 +512,25 @@ string drainFD(int fd)
 //////////////////////////////////////////////////////////////////////
 
 
-AutoDelete::AutoDelete(const string & p) : path(p)
+AutoDelete::AutoDelete(const string & p, bool recursive) : path(p)
 {
     del = true;
+    this->recursive = recursive;
 }
 
 AutoDelete::~AutoDelete()
 {
-    if (del) deletePath(path);
+    try {
+        if (del)
+            if (recursive)
+                deletePath(path);
+            else {
+                if (remove(path.c_str()) == -1)
+                    throw SysError(format("cannot unlink `%1%'") % path);
+            }
+    } catch (...) {
+        ignoreException();
+    }
 }
 
 void AutoDelete::cancel()
@@ -752,10 +766,10 @@ void killUser(uid_t uid)
 		if (errno != EINTR)
 		    throw SysError(format("cannot kill processes for uid `%1%'") % uid);
 	    }
-        
+
         } catch (std::exception & e) {
-            std::cerr << format("killing processes beloging to uid `%1%': %1%\n")
-                % uid % e.what();
+            std::cerr << format("killing processes beloging to uid `%1%': %1%")
+                % uid % e.what() << std::endl;
             quickExit(1);
         }
         quickExit(0);
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index f72a6f82011b..0ed98118c53b 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -72,8 +72,9 @@ void makePathReadOnly(const Path & path);
 /* Create a temporary directory. */
 Path createTempDir(const Path & tmpRoot = "");
 
-/* Create a directory and all its parents, if necessary. */
-void createDirs(const Path & path);
+/* Create a directory and all its parents, if necessary.  Returns the
+   list of created directories, in order of creation. */
+Paths createDirs(const Path & path);
 
 /* Create a file and write the given text to it.  The file is written
    in binary mode (i.e., no end-of-line conversions).  The path should
@@ -166,8 +167,9 @@ class AutoDelete
 {
     Path path;
     bool del;
+    bool recursive;    
 public:
-    AutoDelete(const Path & p);
+    AutoDelete(const Path & p, bool recursive = true);
     ~AutoDelete();
     void cancel();
 };