3 #include <rpm/rpmstring.h>
4 #include <rpm/rpmlog.h>
5 #include "lib/rpmchroot.h"
14 /* Process global chroot state */
15 static struct rootState_s rootState = {
21 int rpmChrootSet(const char *rootDir)
25 /* Setting same rootDir again is a no-op and not an error */
26 if (rootDir && rootState.rootDir && rstreq(rootDir, rootState.rootDir))
29 /* Resetting only permitted in neutral state */
30 if (rootState.chrootDone != 0)
33 rootState.rootDir = _free(rootState.rootDir);
34 if (rootState.cwd >= 0) {
39 if (rootDir != NULL) {
40 rootState.rootDir = rstrdup(rootDir);
41 rootState.cwd = open(".", O_RDONLY);
42 if (rootState.cwd < 0) {
43 rpmlog(RPMLOG_ERR, _("Unable to open current directory: %m\n"));
55 if (rootState.rootDir == NULL || rstreq(rootState.rootDir, "/"))
58 if (rootState.cwd < 0) {
59 rpmlog(RPMLOG_ERR, _("%s: chroot directory not set\n"), __func__);
63 /* "refcounted" entry to chroot */
64 if (rootState.chrootDone > 0) {
65 rootState.chrootDone++;
66 } else if (rootState.chrootDone == 0) {
67 if (chdir("/") == 0 && chroot(rootState.rootDir) == 0) {
68 rootState.chrootDone = 1;
70 rpmlog(RPMLOG_ERR, _("Unable to change root directory: %m\n"));
77 int rpmChrootOut(void)
80 if (rootState.rootDir == NULL || rstreq(rootState.rootDir, "/"))
83 if (rootState.cwd < 0) {
84 rpmlog(RPMLOG_ERR, _("%s: chroot directory not set\n"), __func__);
88 /* "refcounted" return from chroot */
89 if (rootState.chrootDone > 1) {
90 rootState.chrootDone--;
91 } else if (rootState.chrootDone == 1) {
92 if (chroot(".") == 0 && fchdir(rootState.cwd) == 0) {
93 rootState.chrootDone = 0;
95 rpmlog(RPMLOG_ERR, _("Unable to restore root directory: %m\n"));
102 int rpmChrootDone(void)
104 return (rootState.chrootDone > 0);