From 2a4b3f26d6ca421b809af0ff9a97dffcf83be328 Mon Sep 17 00:00:00 2001 From: Giacomo Tesio Date: Wed, 25 Oct 2017 01:02:26 +0200 Subject: [PATCH] cmds: add ns/clone usage: ns/clone pid cmd [args...] It starts cmd with provided arguments in a clone of the namespace available to pid. --- sys/src/cmd/ns/build.json | 3 +- sys/src/cmd/ns/clone.c | 63 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 sys/src/cmd/ns/clone.c diff --git a/sys/src/cmd/ns/build.json b/sys/src/cmd/ns/build.json index 5a44108..ff212ba 100644 --- a/sys/src/cmd/ns/build.json +++ b/sys/src/cmd/ns/build.json @@ -5,7 +5,8 @@ ], "Install": "/arch/$ARCH/cmd/ns/", "SourceFilesCmd": [ - "cat.c" + "cat.c", + "clone.c" ] } } diff --git a/sys/src/cmd/ns/clone.c b/sys/src/cmd/ns/clone.c new file mode 100644 index 0000000..a7592f6 --- /dev/null +++ b/sys/src/cmd/ns/clone.c @@ -0,0 +1,63 @@ +/* + * This file is part of Jehanne. + * + * Copyright (C) 2017 Giacomo Tesio + * + * This is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, version 3 of the License. + * + * Jehanne is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Jehanne. If not, see . + */ +#include +#include +#include + +void +main(int argc, char *argv[]) +{ + int fd, npaths; + char buf[256], *cmd, **args, *paths[17]; + + rfork(RFNAMEG); + if(argc < 3){ + fprint(2, "usage: ns/clone pid cmd [args...]\n"); + exits("usage"); + } + + snprint(buf, sizeof(buf), "/proc/%s/ns", argv[1]); + fd = open(buf, OWRITE); + if(fd < 0){ + print("cannot open %s\n", buf); + exits("invalid target pid"); + } + write(fd, "clone", 6); + close(fd); + + cmd = strdup(argv[2]); + args = &argv[2]; + if(cmd[0] == '/' + ||(cmd[0] == '.' && (cmd[1] == '/' || (cmd[1] == '.' && cmd[2] == '/')))){ + exec(cmd, args); + sysfatal("exec %s failed: %r", cmd); + } + + npaths = getfields(getenv(ENV_PATH), paths, nelem(paths), 1, ":"); + + if(npaths == nelem(paths)) + --npaths; // ignore last (possibly spurious) path + + fd = 0; + while(fd < npaths){ + snprint(buf, sizeof(buf), "%s/%s", paths[fd], cmd); + exec(buf, args); + ++fd; + } + sysfatal("exec %s failed: %r", cmd); +}