Prechádzať zdrojové kódy

Userland: Support custom programs and mount options in chroot

Sergey Bugaev 5 rokov pred
rodič
commit
8ca6e63119
1 zmenil súbory, kde vykonal 73 pridanie a 11 odobranie
  1. 73 11
      Userland/chroot.cpp

+ 73 - 11
Userland/chroot.cpp

@@ -1,14 +1,79 @@
+#include <AK/String.h>
+#include <AK/StringView.h>
 #include <stdio.h>
 #include <unistd.h>
 
-int main(int argc, char** argv)
+struct Options {
+    const char* path;
+    const char* program { "/bin/Shell" };
+    int flags { -1 };
+};
+
+void print_usage(const char* argv0)
+{
+    fprintf(
+        stderr,
+        "Usage:\n"
+        "\t%s <path> [program] [-o options]\n",
+        argv0
+    );
+}
+
+Options parse_options(int argc, char** argv)
 {
-    if (argc != 2) {
-        printf("usage: chroot <path>\n");
-        return 0;
+    Options options;
+
+    if (argc < 2) {
+        print_usage(argv[0]);
+        exit(1);
     }
 
-    if (chroot(argv[1]) < 0) {
+    options.path = argv[1];
+    int i = 2;
+    if (i < argc && argv[i][0] != '-')
+        options.program = argv[i++];
+
+    if (i >= argc)
+        return options;
+
+    if (strcmp(argv[i], "-o") != 0) {
+        print_usage(argv[0]);
+        exit(1);
+    }
+    i++;
+    if (i >= argc) {
+        print_usage(argv[0]);
+        exit(1);
+    }
+
+    options.flags = 0;
+
+    StringView arg = argv[i];
+    Vector<StringView> parts = arg.split_view(',');
+    for (auto& part : parts) {
+        if (part == "defaults")
+            continue;
+        else if (part == "nodev")
+            options.flags |= MS_NODEV;
+        else if (part == "noexec")
+            options.flags |= MS_NOEXEC;
+        else if (part == "nosuid")
+            options.flags |= MS_NOSUID;
+        else if (part == "bind")
+            fprintf(stderr, "Ignoring -o bind, as it doesn't make sense for chroot");
+        else
+            fprintf(stderr, "Ignoring invalid option: %s\n", String(part).characters());
+    }
+
+    return options;
+}
+
+int main(int argc, char** argv)
+{
+
+    Options options = parse_options(argc, argv);
+
+    if (chroot_with_mount_flags(options.path, options.flags) < 0) {
         perror("chroot");
         return 1;
     }
@@ -18,10 +83,7 @@ int main(int argc, char** argv)
         return 1;
     }
 
-    if (execl("/bin/Shell", "Shell", nullptr) < 0) {
-        perror("execl");
-        return 1;
-    }
-
-    return 0;
+    execl(options.program, options.program, nullptr);
+    perror("execl");
+    return 1;
 }