commit b90db5b7f7c75ce3775e422284e6074348413739
parent acb55413b6b7123e6a8a51c18a291f6361b94da9
Author: sin <sin@2f30.org>
Date: Wed, 7 Aug 2013 11:43:55 +0100
Add insmod(8)
Diffstat:
M | Makefile | | | 5 | +++++ |
A | insmod.c | | | 70 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 75 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -16,6 +16,11 @@ SRC = \
dmesg.c \
umount.c
+ifeq ($(OS),linux)
+SRC += \
+ insmod.c
+endif
+
OBJ = $(SRC:.c=.o) $(LIB)
BIN = $(SRC:.c=)
MAN = $(SRC:.c=.1)
diff --git a/insmod.c b/insmod.c
@@ -0,0 +1,70 @@
+/* See LICENSE file for copyright and license details. */
+#include <sys/syscall.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "util.h"
+
+static void
+usage(void)
+{
+ eprintf("usage: %s filename [args]\n", argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char *buf = NULL, *opts = NULL;
+ unsigned long blen, plen = 0;
+ int i, fd;
+ ssize_t n;
+ struct stat sb;
+
+ ARGBEGIN {
+ default:
+ usage();
+ } ARGEND;
+
+ if (argc < 1)
+ usage();
+
+ fd = open(argv[0], O_RDONLY);
+ if (fd < 0)
+ eprintf("open %s:", argv[0]);
+ if (fstat(fd, &sb) < 0)
+ eprintf("stat %s:", argv[0]);
+ buf = malloc(sb.st_size);
+ if (!buf)
+ eprintf("malloc:");
+ blen = sb.st_size;
+
+ if ((n = read(fd, buf, blen)) != blen)
+ eprintf("read:");
+
+ argc--;
+ argv++;
+
+ for (i = 0; i < argc; i++)
+ plen += strlen(argv[i]);
+ if (plen > 0) {
+ plen += argc;
+ opts = malloc(plen);
+ if (!opts)
+ eprintf("malloc:");
+ for (i = 0; i < argc; i++) {
+ strcat(opts, argv[i]);
+ if (i + 1 < argc)
+ strcat(opts, " ");
+ }
+ }
+
+ if (syscall(__NR_init_module, buf, blen, opts) < 0)
+ eprintf("init_module:");
+
+ free(opts);
+ free(buf);
+ return 0;
+}