1 /* vi: set sw=4 ts=4: */
3 * Mini rmmod implementation for busybox
5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
18 #include <sys/utsname.h>
19 #include <sys/syscall.h>
21 #ifdef CONFIG_FEATURE_2_6_MODULES
22 static inline void filename2modname(char *modname, const char *afterslash)
26 #if ENABLE_FEATURE_2_4_MODULES
28 if (get_linux_version_code() <= KERNEL_VERSION(2,6,0))
34 /* Convert to underscores, stop at first . */
35 for (i = 0; afterslash[i] && afterslash[i] != '.'; i++) {
36 if (kr_chk && (afterslash[i] == '-'))
39 modname[i] = afterslash[i];
45 int rmmod_main(int argc, char **argv)
47 int n, ret = EXIT_SUCCESS;
48 unsigned int flags = O_NONBLOCK|O_EXCL;
49 #ifdef CONFIG_FEATURE_QUERY_MODULE_INTERFACE
50 /* bb_common_bufsiz1 hold the module names which we ignore
52 size_t bufsize = sizeof(bb_common_bufsiz1);
55 /* Parse command line. */
56 n = bb_getopt_ulflags(argc, argv, "wfa");
59 if((n & 2)) // --force
62 /* Unload _all_ unused modules via NULL delete_module() call */
63 /* until the number of modules does not change */
64 size_t nmod = 0; /* number of modules */
65 size_t pnmod = -1; /* previous number of modules */
67 while (nmod != pnmod) {
68 if (syscall(__NR_delete_module, NULL, flags) != 0) {
71 bb_perror_msg_and_die("rmmod");
74 #ifdef CONFIG_FEATURE_QUERY_MODULE_INTERFACE
76 if (my_query_module(NULL, 1, &bb_common_bufsiz1, &bufsize, &nmod)) {
77 bb_perror_msg_and_die("QM_MODULES");
87 for (n = optind; n < argc; n++) {
88 #ifdef CONFIG_FEATURE_2_6_MODULES
89 const char *afterslash;
92 afterslash = strrchr(argv[n], '/');
97 module_name = alloca(strlen(afterslash) + 1);
98 filename2modname(module_name, afterslash);
100 #define module_name argv[n]
102 if (syscall(__NR_delete_module, module_name, flags) != 0) {
103 bb_perror_msg("%s", argv[n]);