about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/nix-env/Makefile.am3
-rw-r--r--src/nix-env/main.cc57
-rw-r--r--src/nix-env/profiles.cc57
-rw-r--r--src/nix-env/profiles.hh14
4 files changed, 74 insertions, 57 deletions
diff --git a/src/nix-env/Makefile.am b/src/nix-env/Makefile.am
index bb418ae06c..e4b03943c5 100644
--- a/src/nix-env/Makefile.am
+++ b/src/nix-env/Makefile.am
@@ -1,6 +1,7 @@
 bin_PROGRAMS = nix-env
 
-nix_env_SOURCES = main.cc names.cc names.hh help.txt
+nix_env_SOURCES = main.cc names.cc names.hh \
+ profiles.cc profiles.hh help.txt
 nix_env_LDADD = ../libmain/libmain.a ../libexpr/libexpr.a \
  ../libstore/libstore.a ../libutil/libutil.a \
  ../boost/format/libformat.a -L../../externals/inst/lib -ldb_cxx \
diff --git a/src/nix-env/main.cc b/src/nix-env/main.cc
index 0512366818..87190b6209 100644
--- a/src/nix-env/main.cc
+++ b/src/nix-env/main.cc
@@ -1,5 +1,6 @@
 #include <cerrno>
 
+#include "profiles.hh"
 #include "names.hh"
 #include "globals.hh"
 #include "normalise.hh"
@@ -138,62 +139,6 @@ void queryInstalled(EvalState & state, DrvInfos & drvs,
 }
 
 
-Path createGeneration(Path profile, Path outPath, Path drvPath)
-{
-    Path profileDir = dirOf(profile);
-    string profileName = baseNameOf(profile);
-    
-    unsigned int num = 0;
-    
-    Strings names = readDirectory(profileDir);
-    for (Strings::iterator i = names.begin(); i != names.end(); ++i) {
-        if (string(*i, 0, profileName.size() + 1) != profileName + "-") continue;
-        string s = string(*i, profileName.size() + 1);
-        int p = s.find("-link");
-        if (p == string::npos) continue;
-        istringstream str(string(s, 0, p));
-        unsigned int n;
-        if (str >> n && str.eof() && n >= num) num = n + 1;
-    }
-
-    Path generation, gcrootSrc;
-
-    while (1) {
-        Path prefix = (format("%1%-%2%") % profile % num).str();
-        generation = prefix + "-link";
-        gcrootSrc = prefix + "-src.gcroot";
-        if (symlink(outPath.c_str(), generation.c_str()) == 0) break;
-        if (errno != EEXIST)
-            throw SysError(format("creating symlink `%1%'") % generation);
-        /* Somebody beat us to it, retry with a higher number. */
-        num++;
-    }
-
-    writeStringToFile(gcrootSrc, drvPath);
-
-    return generation;
-}
-
-
-void switchLink(Path link, Path target)
-{
-    /* Hacky. */
-    if (dirOf(target) == dirOf(link)) target = baseNameOf(target);
-    
-    Path tmp = canonPath(dirOf(link) + "/.new_" + baseNameOf(link));
-    if (symlink(target.c_str(), tmp.c_str()) != 0)
-        throw SysError(format("creating symlink `%1%'") % tmp);
-    /* The rename() system call is supposed to be essentially atomic
-       on Unix.  That is, if we have links `current -> X' and
-       `new_current -> Y', and we rename new_current to current, a
-       process accessing current will see X or Y, but never a
-       file-not-found or other error condition.  This is sufficient to
-       atomically switch user environments. */
-    if (rename(tmp.c_str(), link.c_str()) != 0)
-        throw SysError(format("renaming `%1%' to `%2%'") % tmp % link);
-}
-
-
 void createUserEnv(EvalState & state, const DrvInfos & drvs,
     const Path & profile)
 {
diff --git a/src/nix-env/profiles.cc b/src/nix-env/profiles.cc
new file mode 100644
index 0000000000..5b9c004066
--- /dev/null
+++ b/src/nix-env/profiles.cc
@@ -0,0 +1,57 @@
+#include "profiles.hh"
+
+
+Path createGeneration(Path profile, Path outPath, Path drvPath)
+{
+    Path profileDir = dirOf(profile);
+    string profileName = baseNameOf(profile);
+    
+    unsigned int num = 0;
+    
+    Strings names = readDirectory(profileDir);
+    for (Strings::iterator i = names.begin(); i != names.end(); ++i) {
+        if (string(*i, 0, profileName.size() + 1) != profileName + "-") continue;
+        string s = string(*i, profileName.size() + 1);
+        int p = s.find("-link");
+        if (p == string::npos) continue;
+        istringstream str(string(s, 0, p));
+        unsigned int n;
+        if (str >> n && str.eof() && n >= num) num = n + 1;
+    }
+
+    Path generation, gcrootSrc;
+
+    while (1) {
+        Path prefix = (format("%1%-%2%") % profile % num).str();
+        generation = prefix + "-link";
+        gcrootSrc = prefix + "-src.gcroot";
+        if (symlink(outPath.c_str(), generation.c_str()) == 0) break;
+        if (errno != EEXIST)
+            throw SysError(format("creating symlink `%1%'") % generation);
+        /* Somebody beat us to it, retry with a higher number. */
+        num++;
+    }
+
+    writeStringToFile(gcrootSrc, drvPath);
+
+    return generation;
+}
+
+
+void switchLink(Path link, Path target)
+{
+    /* Hacky. */
+    if (dirOf(target) == dirOf(link)) target = baseNameOf(target);
+    
+    Path tmp = canonPath(dirOf(link) + "/.new_" + baseNameOf(link));
+    if (symlink(target.c_str(), tmp.c_str()) != 0)
+        throw SysError(format("creating symlink `%1%'") % tmp);
+    /* The rename() system call is supposed to be essentially atomic
+       on Unix.  That is, if we have links `current -> X' and
+       `new_current -> Y', and we rename new_current to current, a
+       process accessing current will see X or Y, but never a
+       file-not-found or other error condition.  This is sufficient to
+       atomically switch user environments. */
+    if (rename(tmp.c_str(), link.c_str()) != 0)
+        throw SysError(format("renaming `%1%' to `%2%'") % tmp % link);
+}
diff --git a/src/nix-env/profiles.hh b/src/nix-env/profiles.hh
new file mode 100644
index 0000000000..3d3c86e50b
--- /dev/null
+++ b/src/nix-env/profiles.hh
@@ -0,0 +1,14 @@
+#ifndef __PROFILES_H
+#define __PROFILES_H
+
+#include <string>
+
+#include "util.hh"
+
+
+Path createGeneration(Path profile, Path outPath, Path drvPath);
+
+void switchLink(Path link, Path target);
+
+
+#endif /* !__PROFILES_H */