aboutsummaryrefslogtreecommitdiff
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 bb418ae06..e4b03943c 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 051236681..87190b620 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 000000000..5b9c00406
--- /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 000000000..3d3c86e50
--- /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 */