diff options
Diffstat (limited to 'modutils/rmmod.c')
-rw-r--r-- | modutils/rmmod.c | 87 |
1 files changed, 17 insertions, 70 deletions
diff --git a/modutils/rmmod.c b/modutils/rmmod.c index 5129b3495..cdc690a69 100644 --- a/modutils/rmmod.c +++ b/modutils/rmmod.c | |||
@@ -3,98 +3,45 @@ | |||
3 | * Mini rmmod implementation for busybox | 3 | * Mini rmmod implementation for busybox |
4 | * | 4 | * |
5 | * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> | 5 | * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> |
6 | * Copyright (C) 2008 Timo Teras <timo.teras@iki.fi> | ||
6 | * | 7 | * |
7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 8 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
8 | */ | 9 | */ |
9 | 10 | ||
10 | #include "libbb.h" | 11 | #include "libbb.h" |
11 | 12 | #include "modutils.h" | |
12 | #ifdef __UCLIBC__ | ||
13 | extern int delete_module(const char *module, unsigned int flags); | ||
14 | #else | ||
15 | # include <sys/syscall.h> | ||
16 | # define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags) | ||
17 | #endif | ||
18 | |||
19 | #if ENABLE_FEATURE_2_6_MODULES | ||
20 | static void filename2modname(char *modname, const char *afterslash) | ||
21 | { | ||
22 | unsigned int i; | ||
23 | int kr_chk = 1; | ||
24 | |||
25 | if (ENABLE_FEATURE_2_4_MODULES | ||
26 | && get_linux_version_code() <= KERNEL_VERSION(2,6,0)) | ||
27 | kr_chk = 0; | ||
28 | |||
29 | /* Convert to underscores, stop at first . */ | ||
30 | for (i = 0; afterslash[i] && afterslash[i] != '.'; i++) { | ||
31 | if (kr_chk && (afterslash[i] == '-')) | ||
32 | modname[i] = '_'; | ||
33 | else | ||
34 | modname[i] = afterslash[i]; | ||
35 | } | ||
36 | modname[i] = '\0'; | ||
37 | } | ||
38 | #else | ||
39 | void filename2modname(char *modname, const char *afterslash); | ||
40 | #endif | ||
41 | |||
42 | // There really should be a header file for this... | ||
43 | |||
44 | int query_module(const char *name, int which, void *buf, | ||
45 | size_t bufsize, size_t *ret); | ||
46 | 13 | ||
47 | int rmmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 14 | int rmmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
48 | int rmmod_main(int argc, char **argv) | 15 | int rmmod_main(int argc UNUSED_PARAM, char **argv) |
49 | { | 16 | { |
50 | int n, ret = EXIT_SUCCESS; | 17 | int n; |
51 | unsigned int flags = O_NONBLOCK|O_EXCL; | 18 | unsigned int flags = O_NONBLOCK|O_EXCL; |
52 | 19 | ||
53 | #define misc_buf bb_common_bufsiz1 | ||
54 | |||
55 | /* Parse command line. */ | 20 | /* Parse command line. */ |
56 | n = getopt32(argv, "wfa"); | 21 | n = getopt32(argv, "wfas"); // -s ignored |
22 | argv += optind; | ||
23 | |||
57 | if (n & 1) // --wait | 24 | if (n & 1) // --wait |
58 | flags &= ~O_NONBLOCK; | 25 | flags &= ~O_NONBLOCK; |
59 | if (n & 2) // --force | 26 | if (n & 2) // --force |
60 | flags |= O_TRUNC; | 27 | flags |= O_TRUNC; |
61 | if (n & 4) { | 28 | if (n & 4) { |
62 | /* Unload _all_ unused modules via NULL delete_module() call */ | 29 | /* Unload _all_ unused modules via NULL delete_module() call */ |
63 | /* until the number of modules does not change */ | 30 | if (bb_delete_module(NULL, flags) != 0 && errno != EFAULT) |
64 | size_t nmod = 0; /* number of modules */ | 31 | bb_perror_msg_and_die("rmmod"); |
65 | size_t pnmod = -1; /* previous number of modules */ | ||
66 | |||
67 | while (nmod != pnmod) { | ||
68 | if (delete_module(NULL, flags) != 0) { | ||
69 | if (errno == EFAULT) | ||
70 | return ret; | ||
71 | bb_perror_msg_and_die("rmmod"); | ||
72 | } | ||
73 | pnmod = nmod; | ||
74 | // the 1 here is QM_MODULES. | ||
75 | if (ENABLE_FEATURE_QUERY_MODULE_INTERFACE && query_module(NULL, | ||
76 | 1, misc_buf, sizeof(misc_buf), | ||
77 | &nmod)) | ||
78 | { | ||
79 | bb_perror_msg_and_die("QM_MODULES"); | ||
80 | } | ||
81 | } | ||
82 | return EXIT_SUCCESS; | 32 | return EXIT_SUCCESS; |
83 | } | 33 | } |
84 | 34 | ||
85 | if (optind == argc) | 35 | if (!*argv) |
86 | bb_show_usage(); | 36 | bb_show_usage(); |
87 | 37 | ||
88 | for (n = optind; n < argc; n++) { | 38 | while (*argv) { |
89 | if (ENABLE_FEATURE_2_6_MODULES) { | 39 | char modname[MODULE_NAME_LEN]; |
90 | filename2modname(misc_buf, bb_basename(argv[n])); | 40 | filename2modname(bb_basename(*argv++), modname); |
91 | } | 41 | if (bb_delete_module(modname, flags)) |
92 | 42 | bb_error_msg_and_die("cannot unload '%s': %s", | |
93 | if (delete_module(ENABLE_FEATURE_2_6_MODULES ? misc_buf : argv[n], flags)) { | 43 | modname, moderror(errno)); |
94 | bb_simple_perror_msg(argv[n]); | ||
95 | ret = EXIT_FAILURE; | ||
96 | } | ||
97 | } | 44 | } |
98 | 45 | ||
99 | return ret; | 46 | return EXIT_SUCCESS; |
100 | } | 47 | } |