10f66f451Sopenharmony_ci/* insmod.c - Load a module into the Linux kernel. 20f66f451Sopenharmony_ci * 30f66f451Sopenharmony_ci * Copyright 2012 Elie De Brauwer <eliedebrauwer@gmail.com> 40f66f451Sopenharmony_ci 50f66f451Sopenharmony_ciUSE_INSMOD(NEWTOY(insmod, "<1", TOYFLAG_SBIN|TOYFLAG_NEEDROOT)) 60f66f451Sopenharmony_ci 70f66f451Sopenharmony_ciconfig INSMOD 80f66f451Sopenharmony_ci bool "insmod" 90f66f451Sopenharmony_ci default y 100f66f451Sopenharmony_ci help 110f66f451Sopenharmony_ci usage: insmod MODULE [MODULE_OPTIONS] 120f66f451Sopenharmony_ci 130f66f451Sopenharmony_ci Load the module named MODULE passing options if given. 140f66f451Sopenharmony_ci*/ 150f66f451Sopenharmony_ci 160f66f451Sopenharmony_ci#include "toys.h" 170f66f451Sopenharmony_ci 180f66f451Sopenharmony_ci#include <sys/syscall.h> 190f66f451Sopenharmony_ci#ifdef SYS_finit_module 200f66f451Sopenharmony_ci#define finit_module(fd, opts, flags) syscall(SYS_finit_module, fd, opts, flags) 210f66f451Sopenharmony_ci#else 220f66f451Sopenharmony_ci#define finit_module(a, b, c) (errno = ENOSYS) 230f66f451Sopenharmony_ci#endif 240f66f451Sopenharmony_ci#define init_module(mod, len, opts) syscall(SYS_init_module, mod, len, opts) 250f66f451Sopenharmony_ci 260f66f451Sopenharmony_civoid insmod_main(void) 270f66f451Sopenharmony_ci{ 280f66f451Sopenharmony_ci int fd = xopenro(*toys.optargs); 290f66f451Sopenharmony_ci int i, rc; 300f66f451Sopenharmony_ci 310f66f451Sopenharmony_ci i = 1; 320f66f451Sopenharmony_ci while (toys.optargs[i] && 330f66f451Sopenharmony_ci strlen(toybuf) + strlen(toys.optargs[i]) + 2 < sizeof(toybuf)) 340f66f451Sopenharmony_ci { 350f66f451Sopenharmony_ci strcat(toybuf, toys.optargs[i++]); 360f66f451Sopenharmony_ci strcat(toybuf, " "); 370f66f451Sopenharmony_ci } 380f66f451Sopenharmony_ci 390f66f451Sopenharmony_ci // finit_module was new in Linux 3.8, and doesn't work on stdin, 400f66f451Sopenharmony_ci // so we fall back to init_module if necessary. 410f66f451Sopenharmony_ci rc = finit_module(fd, toybuf, 0); 420f66f451Sopenharmony_ci if (rc && (fd == 0 || errno == ENOSYS)) { 430f66f451Sopenharmony_ci off_t len = 0; 440f66f451Sopenharmony_ci char *path = !strcmp(*toys.optargs, "-") ? "/dev/stdin" : *toys.optargs; 450f66f451Sopenharmony_ci char *buf = readfileat(AT_FDCWD, path, NULL, &len); 460f66f451Sopenharmony_ci 470f66f451Sopenharmony_ci rc = init_module(buf, len, toybuf); 480f66f451Sopenharmony_ci if (CFG_TOYBOX_FREE) free(buf); 490f66f451Sopenharmony_ci } 500f66f451Sopenharmony_ci 510f66f451Sopenharmony_ci if (rc) perror_exit("failed to load %s", toys.optargs[0]); 520f66f451Sopenharmony_ci 530f66f451Sopenharmony_ci if (CFG_TOYBOX_FREE) close(fd); 540f66f451Sopenharmony_ci} 55