15
15
*/
16
16
17
17
#include < ctype.h>
18
+ #include < errno.h>
18
19
#include < getopt.h>
19
20
#include < stdlib.h>
21
+ #include < string.h>
20
22
21
23
#include < iostream>
24
+ #include < string>
22
25
23
26
#include < android-base/file.h>
24
27
#include < android-base/strings.h>
@@ -37,10 +40,11 @@ void print_usage(void) {
37
40
std::cerr << " Usage:" << std::endl;
38
41
std::cerr << std::endl;
39
42
// -d option is required on Android
40
- std::cerr << " modprobe [options] -d DIR MODULE..." << std::endl;
43
+ std::cerr << " modprobe [options] -d DIR [--all=FILE| MODULE] ..." << std::endl;
41
44
std::cerr << " modprobe [options] -d DIR MODULE [symbol=value]..." << std::endl;
42
45
std::cerr << std::endl;
43
46
std::cerr << " Options:" << std::endl;
47
+ std::cerr << " --all=FILE: FILE to acquire module names from" << std::endl;
44
48
std::cerr << " -b, --use-blocklist: Apply blocklist to module names too" << std::endl;
45
49
std::cerr << " -d, --dirname=DIR: Load modules from DIR, option may be used multiple times"
46
50
<< std::endl;
@@ -61,11 +65,23 @@ void print_usage(void) {
61
65
return EXIT_FAILURE; \
62
66
}
63
67
68
+ std::string stripComments (const std::string& str) {
69
+ for (std::string rv = str;;) {
70
+ auto comment = rv.find (' #' );
71
+ if (comment == std::string::npos) return rv;
72
+ auto end = rv.find (' \n ' , comment);
73
+ if (end != std::string::npos) end = end - comment;
74
+ rv.erase (comment, end);
75
+ }
76
+ /* NOTREACHED */
77
+ }
78
+
64
79
} // anonymous namespace
65
80
66
81
extern " C" int modprobe_main (int argc, char ** argv) {
67
82
std::vector<std::string> modules;
68
83
std::string module_parameters;
84
+ std::string mods;
69
85
std::vector<std::string> mod_dirs;
70
86
modprobe_mode mode = AddModulesMode;
71
87
bool blocklist = false ;
@@ -78,7 +94,7 @@ extern "C" int modprobe_main(int argc, char** argv) {
78
94
// OEMs to transition from toybox.
79
95
// clang-format off
80
96
static struct option long_options[] = {
81
- { " all" , no_argument, 0 , ' a' },
97
+ { " all" , optional_argument, 0 , ' a' },
82
98
{ " use-blocklist" , no_argument, 0 , ' b' },
83
99
{ " dirname" , required_argument, 0 , ' d' },
84
100
{ " show-depends" , no_argument, 0 , ' D' },
@@ -89,12 +105,24 @@ extern "C" int modprobe_main(int argc, char** argv) {
89
105
{ " verbose" , no_argument, 0 , ' v' },
90
106
};
91
107
// clang-format on
92
- while ((opt = getopt_long (argc, argv, " abd :Dhlqrv" , long_options, &option_index)) != -1 ) {
108
+ while ((opt = getopt_long (argc, argv, " a::bd :Dhlqrv" , long_options, &option_index)) != -1 ) {
93
109
switch (opt) {
94
110
case ' a' :
95
111
// toybox modprobe supported -a to load multiple modules, this
96
- // is supported here by default, ignore flag
112
+ // is supported here by default, ignore flag if no argument.
97
113
check_mode ();
114
+ if (optarg == NULL ) break ;
115
+ if (!android::base::ReadFileToString (optarg, &mods)) {
116
+ std::cerr << " Failed to open " << optarg << " : " << strerror (errno)
117
+ << std::endl;
118
+ rv = EXIT_FAILURE;
119
+ }
120
+ for (auto mod : android::base::Split (stripComments (mods), " \n " )) {
121
+ mod = android::base::Trim (mod);
122
+ if (mod == " " ) continue ;
123
+ if (std::find (modules.begin (), modules.end (), mod) != modules.end ()) continue ;
124
+ modules.emplace_back (mod);
125
+ }
98
126
break ;
99
127
case ' b' :
100
128
blocklist = true ;
0 commit comments