1 /* vi: set sw=4 ts=4: */
3 * Mini lsmod implementation for busybox
5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
7 * Modified by Alcove, Julien Gaulmin <julien.gaulmin@alcove.fr> and
8 * Nicolas Ferre <nicolas.ferre@alcove.fr> to support pre 2.1 kernels
9 * (which lack the query_module() interface).
11 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
17 #if !ENABLE_FEATURE_CHECK_TAINTED_MODULE
18 static void check_tainted(void) { bb_putchar('\n'); }
20 #define TAINT_FILENAME "/proc/sys/kernel/tainted"
21 #define TAINT_PROPRIETORY_MODULE (1<<0)
22 #define TAINT_FORCED_MODULE (1<<1)
23 #define TAINT_UNSAFE_SMP (1<<2)
25 static void check_tainted(void)
31 if ((f
= fopen(TAINT_FILENAME
, "r"))) {
32 fscanf(f
, "%d", &tainted
);
36 printf(" Tainted: %c%c%c\n",
37 tainted
& TAINT_PROPRIETORY_MODULE
? 'P' : 'G',
38 tainted
& TAINT_FORCED_MODULE
? 'F' : ' ',
39 tainted
& TAINT_UNSAFE_SMP
? 'S' : ' ');
42 printf(" Not tainted\n");
47 #if ENABLE_FEATURE_QUERY_MODULE_INTERFACE
58 int query_module(const char *name
, int which
, void *buf
, size_t bufsize
, size_t *ret
);
61 /* Values for query_module's which. */
68 /* Bits of module.flags. */
71 NEW_MOD_AUTOCLEAN
= 4,
73 NEW_MOD_USED_ONCE
= 16,
74 NEW_MOD_INITIALIZING
= 64
77 int lsmod_main(int argc
, char **argv
) MAIN_EXTERNALLY_VISIBLE
;
78 int lsmod_main(int argc
, char **argv
)
80 struct module_info info
;
81 char *module_names
, *mn
, *deps
, *dn
;
82 size_t bufsize
, depsize
, nmod
, count
, i
, j
;
84 module_names
= deps
= NULL
;
85 bufsize
= depsize
= 0;
86 while (query_module(NULL
, QM_MODULES
, module_names
, bufsize
, &nmod
)) {
87 if (errno
!= ENOSPC
) bb_perror_msg_and_die("QM_MODULES");
88 module_names
= xmalloc(bufsize
= nmod
);
91 deps
= xmalloc(depsize
= 256);
92 printf("Module\t\t\tSize Used by");
95 for (i
= 0, mn
= module_names
; i
< nmod
; mn
+= strlen(mn
) + 1, i
++) {
96 if (query_module(mn
, QM_INFO
, &info
, sizeof(info
), &count
)) {
97 if (errno
== ENOENT
) {
98 /* The module was removed out from underneath us. */
102 bb_perror_msg_and_die("module %s: QM_INFO", mn
);
104 while (query_module(mn
, QM_REFS
, deps
, depsize
, &count
)) {
105 if (errno
== ENOENT
) {
106 /* The module was removed out from underneath us. */
108 } else if (errno
!= ENOSPC
)
109 bb_perror_msg_and_die("module %s: QM_REFS", mn
);
110 deps
= xrealloc(deps
, count
);
112 printf("%-20s%8lu%4ld", mn
, info
.size
, info
.usecount
);
113 if (info
.flags
& NEW_MOD_DELETED
)
114 printf(" (deleted)");
115 else if (info
.flags
& NEW_MOD_INITIALIZING
)
116 printf(" (initializing)");
117 else if (!(info
.flags
& NEW_MOD_RUNNING
))
118 printf(" (uninitialized)");
120 if (info
.flags
& NEW_MOD_AUTOCLEAN
)
121 printf(" (autoclean) ");
122 if (!(info
.flags
& NEW_MOD_USED_ONCE
))
125 if (count
) printf(" [");
126 for (j
= 0, dn
= deps
; j
< count
; dn
+= strlen(dn
) + 1, j
++) {
127 printf("%s%s", dn
, (j
==count
-1)? "":" ");
129 if (count
) printf("]");
134 #if ENABLE_FEATURE_CLEAN_UP
141 #else /* CONFIG_FEATURE_QUERY_MODULE_INTERFACE */
143 int lsmod_main(int argc
, char **argv
) MAIN_EXTERNALLY_VISIBLE
;
144 int lsmod_main(int argc
, char **argv
)
146 FILE *file
= xfopen("/proc/modules", "r");
148 printf("Module Size Used by");
150 #if defined(CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT)
153 while ((line
= xmalloc_fgets(file
)) != NULL
) {
156 tok
= strtok(line
, " \t");
157 printf("%-19s", tok
);
158 tok
= strtok(NULL
, " \t\n");
160 tok
= strtok(NULL
, " \t\n");
161 /* Null if no module unloading support. */
164 tok
= strtok(NULL
, "\n");
167 /* New-style has commas, or -. If so,
168 truncate (other fields might follow). */
169 else if (strchr(tok
, ',')) {
170 tok
= strtok(tok
, "\t ");
171 /* Strip trailing comma. */
172 if (tok
[strlen(tok
)-1] == ',')
173 tok
[strlen(tok
)-1] = '\0';
174 } else if (tok
[0] == '-'
175 && (tok
[1] == '\0' || isspace(tok
[1]))
187 xprint_and_close_file(file
);
188 #endif /* CONFIG_FEATURE_2_6_MODULES */
192 #endif /* CONFIG_FEATURE_QUERY_MODULE_INTERFACE */