diff --git a/Makefile b/Makefile index cecc5f2..098225c 100644 --- 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 new file mode 100644 index 0000000..d92f03c --- /dev/null +++ b/insmod.c @@ -0,0 +1,70 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#include +#include +#include +#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; +}