+setup_root(void)
+{
+ umask(0022);
+
+ if (mkdir("root", 0777) < 0 && errno != EEXIST)
+ die("mkdir('root'): %m");
+
+ if (mount("none", "root", "tmpfs", 0, "mode=755") < 0)
+ die("Cannot mount root ramdisk: %m");
+
+ // FIXME: Make the list of bind-mounts configurable
+ // FIXME: Virtual dev?
+ // FIXME: Read-only mounts?
+
+ static const char * const dirs[] = { "box", "/bin", "/lib", "/usr", "/dev" };
+ for (int i=0; i < ARRAY_SIZE(dirs); i++)
+ {
+ const char *d = dirs[i];
+ char buf[1024]; // FIXME
+ sprintf(buf, "root/%s", (d[0] == '/' ? d+1 : d));
+ printf("Binding %s on %s\n", d, buf);
+ if (mkdir(buf, 0777) < 0)
+ die("mkdir(%s): %m", buf);
+ if (mount(d, buf, "none", MS_BIND | MS_NOSUID | MS_NODEV, "") < 0)
+ die("Cannot bind %s on %s: %m", d, buf);
+ }
+
+ if (mkdir("root/proc", 0777) < 0)
+ die("Cannot create proc: %m");
+ if (mount("none", "root/proc", "proc", 0, "") < 0)
+ die("Cannot mount proc: %m");
+
+ if (chroot("root") < 0)
+ die("Chroot failed: %m");
+
+ if (chdir("root/box") < 0)
+ die("Cannot change current directory: %m");
+}
+
+static int
+box_inside(void *arg)