xref: /third_party/toybox/toys/other/insmod.c (revision 0f66f451)
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