Skip to content

Commit

Permalink
Implement "insmod -".
Browse files Browse the repository at this point in the history
Also use finit_module if available. Given that "insmod -" requires
init_module, maybe this isn't a worthwhile optimization. Given that
"insmod /actual/file.ko" is the common use case, maybe it is.

Fix a bug in readfileat where *plen would be corrupted if you didn't supply
your own buffer (because ibuf is 0 in that case, not a pointer to the start
of the allocated space).
  • Loading branch information
enh-google authored and landley committed Feb 19, 2016
1 parent 5ec9f52 commit 81f31e4
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 16 deletions.
4 changes: 2 additions & 2 deletions lib/lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,12 +475,12 @@ char *readfileat(int dirfd, char *name, char *ibuf, off_t *plen)
rbuf = buf+rlen;
len -= rlen;
}
*plen = len = rlen+(buf-ibuf);
*plen = len = rlen+(rbuf-buf);
close(fd);

if (rlen<0) {
if (ibuf != buf) free(buf);
buf = 0;
buf = 0;
} else buf[len] = 0;

return buf;
Expand Down
32 changes: 18 additions & 14 deletions toys/other/insmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,35 @@ config INSMOD
#include "toys.h"

#include <sys/syscall.h>
#define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts)
#define finit_module(fd, opts, flags) syscall(SYS_finit_module, fd, opts, flags)
#define init_module(mod, len, opts) syscall(SYS_init_module, mod, len, opts)

void insmod_main(void)
{
char * buf = NULL;
int len, res, i;
int fd = xopen(*toys.optargs, O_RDONLY);

len = fdlength(fd);
buf = xmalloc(len);
xreadall(fd, buf, len);
int fd = !strcmp(*toys.optargs, "-") ? 0 : xopen(*toys.optargs, O_RDONLY);
int i, rc;

i = 1;
while(toys.optargs[i] &&
while (toys.optargs[i] &&
strlen(toybuf) + strlen(toys.optargs[i]) + 2 < sizeof(toybuf))
{
strcat(toybuf, toys.optargs[i++]);
strcat(toybuf, " ");
}

res = init_module(buf, len, toybuf);
if (CFG_TOYBOX_FREE) {
if (buf != toybuf) free(buf);
close(fd);
// finit_module was new in Linux 3.8, and doesn't work on stdin,
// so we fall back to init_module if necessary.
rc = finit_module(fd, toybuf, 0);
if (rc && (fd == 0 || errno == ENOSYS)) {
off_t len = 0;
char *path = !strcmp(*toys.optargs, "-") ? "/dev/stdin" : *toys.optargs;
char *buf = readfileat(AT_FDCWD, path, NULL, &len);

rc = init_module(buf, len, toybuf);
if (CFG_TOYBOX_FREE) free(buf);
}

if (res) perror_exit("failed to load %s", toys.optargs[0]);
if (rc) perror_exit("failed to load %s", toys.optargs[0]);

if (CFG_TOYBOX_FREE) close(fd);
}

0 comments on commit 81f31e4

Please sign in to comment.