commit 599ecdb2636f77f0f13135adadece6c3778081ea
Author: sin <sin@2f30.org>
Date: Fri, 23 Mar 2018 11:20:49 +0000
Initial commit
Diffstat:
A | pexec.c | | | 113 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 113 insertions(+), 0 deletions(-)
diff --git a/pexec.c b/pexec.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2018 Dimitris Papastamos <sin@2f30.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * execute a program from stdin
+ *
+ * example: pexec /bin/ls -la /tmp < /bin/ls
+ *
+ * This is true cloud computing!
+ */
+
+#include <sys/syscall.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static int
+memfd_create(const char *name, unsigned int flags)
+{
+ return syscall(__NR_memfd_create, name, flags);
+}
+
+static ssize_t
+xread(int fd, void *buf, size_t nbytes)
+{
+ unsigned char *bp = buf;
+ ssize_t total = 0;
+
+ while (nbytes > 0) {
+ ssize_t n;
+
+ n = read(fd, &bp[total], nbytes);
+ if (n < 0)
+ err(1, "read");
+ else if (n == 0)
+ return total;
+ total += n;
+ nbytes -= n;
+ }
+ return total;
+}
+
+static ssize_t
+xwrite(int fd, const void *buf, size_t nbytes)
+{
+ const unsigned char *bp = buf;
+ ssize_t total = 0;
+
+ while (nbytes > 0) {
+ ssize_t n;
+
+ n = write(fd, &bp[total], nbytes);
+ if (n < 0)
+ err(1, "write");
+ else if (n == 0)
+ return total;
+ total += n;
+ nbytes -= n;
+ }
+ return total;
+}
+
+static void
+pexec(int fd, int argc, char *argv[])
+{
+ extern char **environ;
+
+ argc--, argv++;
+ if (fexecve(fd, argv, environ) < 0)
+ err(1, "fexecve");
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: pexec argv[0] [argv[1]...]\n");
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char buf[BUFSIZ];
+ ssize_t n;
+ int fd;
+
+ if (argc < 2)
+ usage();
+
+ fd = memfd_create("exec", 0);
+ if (fd < 0)
+ err(1, "memfd_create");
+
+ while ((n = xread(STDIN_FILENO, buf, BUFSIZ)) > 0)
+ xwrite(fd, buf, n);
+
+ pexec(fd, argc, argv);
+ /* unreachable */
+}