aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2020-03-09 22:07:47 -0700
committerRob Landley <rob@landley.net>2020-03-10 09:48:15 -0500
commite6b3ac496f8b72f089247e93e6892bb6fa094976 (patch)
tree6f5751e14011383f2f5e78a92e3f266ed6da6160
parentbdcb9de92aba82c13554b7d198d3fffabecd976b (diff)
downloadtoybox-e6b3ac496f8b72f089247e93e6892bb6fa094976.tar.gz
modinfo: various fixes.
I came here because the new -Wno-unreachable-code-loop-increment warning didn't like the for loop on line 86. That loop is indeed not necessary. Use strend() to do a string suffix match. Use memmem() to search. It's available on macOS and Android by default, but it's behind _GNU_SOURCE for glibc, so add that to portability.h. Output the tags in the same order as the Debian modinfo. I've left "parmtype" in even though the Debian modinfo doesn't output it at all. Also fix the tests so that they work on a device that has modules for multiple kernels installed (like my laptop) --- make sure that the two modules we pick come from the same kernel.
-rw-r--r--lib/portability.h2
-rw-r--r--tests/modinfo.test2
-rw-r--r--toys/other/modinfo.c67
3 files changed, 33 insertions, 38 deletions
diff --git a/lib/portability.h b/lib/portability.h
index d81ddead..76790f4d 100644
--- a/lib/portability.h
+++ b/lib/portability.h
@@ -103,6 +103,8 @@ char *dirname(char *path);
char *__xpg_basename(char *path);
static inline char *basename(char *path) { return __xpg_basename(path); }
char *strcasestr(const char *haystack, const char *needle);
+void *memmem(const void *haystack, size_t haystack_length,
+ const void *needle, size_t needle_length);
#endif // defined(glibc)
// getopt_long(), getopt_long_only(), and struct option.
diff --git a/tests/modinfo.test b/tests/modinfo.test
index aaa7a7bd..261acfda 100644
--- a/tests/modinfo.test
+++ b/tests/modinfo.test
@@ -19,7 +19,7 @@ testcmd "missing" "missing 2>&1" "modinfo: missing: not found\n" "" ""
# Find some modules to work with.
MODULE_PATH1=$(find $MODULE_ROOT/lib/modules -name *.ko | head -1 2>/dev/null)
MODULE1=$(basename -s .ko $MODULE_PATH1)
-MODULE_PATH2=$(find $MODULE_ROOT/lib/modules -name *.ko | tail -1 2>/dev/null)
+MODULE_PATH2=$(find $MODULE_ROOT/lib/modules -name *.ko | head -2 | tail -1 2>/dev/null)
MODULE2=$(basename -s .ko $MODULE_PATH2)
DASH_MODULE=$(basename -s .ko \
$(find $MODULE_ROOT/lib/modules -name *-*.ko | tail -1 2>/dev/null))
diff --git a/toys/other/modinfo.c b/toys/other/modinfo.c
index 286570f1..6c1e9392 100644
--- a/toys/other/modinfo.c
+++ b/toys/other/modinfo.c
@@ -40,16 +40,16 @@ static void output_field(char *field, char *value)
static void modinfo_file(char *full_name)
{
- int fd, len, i;
- char *buf = 0, *pos, *modinfo_tags[] = {
- "alias", "license", "description", "author", "firmware",
- "vermagic", "srcversion", "intree", "depends", "parm",
- "parmtype",
+ int fd, flen, i;
+ char *buf = 0, *end, *modinfo_tags[] = {
+ "license", "author", "description", "firmware", "alias", "srcversion",
+ "depends", "retpoline", "intree", "name", "vermagic", "parm", "parmtype",
};
if (-1 != (fd = open(full_name, O_RDONLY))) {
- len = fdlength(fd);
- buf = xmmap(0, len, PROT_READ, MAP_SHARED, fd, 0);
+ flen = fdlength(fd);
+ buf = xmmap(0, flen, PROT_READ, MAP_SHARED, fd, 0);
+ end = buf + flen;
close(fd);
}
@@ -61,47 +61,42 @@ static void modinfo_file(char *full_name)
TT.count++;
output_field("filename", full_name);
- for (pos = buf; pos < buf+len; pos++) {
- if (*pos) continue;
+ for (i=0; i<ARRAY_LEN(modinfo_tags); i++) {
+ char *field = modinfo_tags[i], *p = buf;
+ int slen = sprintf(toybuf, "%s=", field);
- for (i=0; i<ARRAY_LEN(modinfo_tags); i++) {
- char *str = modinfo_tags[i];
- int len = strlen(str);
-
- if (!strncmp(pos+1, str, len) && pos[len+1] == '=')
- output_field(str, pos+len+2);
+ while (p && p < end) {
+ p = memmem(p, end-p, toybuf, slen);
+ if (p) output_field(field, p += slen);
}
}
- munmap(buf, len);
+ munmap(buf, flen);
}
static int check_module(struct dirtree *new)
{
- if (!dirtree_notdotdot(new)) return 0;
+ char *s;
+ int len;
- if (S_ISREG(new->st.st_mode)) {
- char *s;
-
- for (s = toys.optargs[TT.mod]; *s; s++) {
- int len = 0;
+ if (!dirtree_notdotdot(new)) return 0;
- // The kernel treats - and _ the same, so we should too.
- for (len = 0; s[len]; len++) {
- if (s[len] == '-' && new->name[len] == '_') continue;
- if (s[len] == '_' && new->name[len] == '-') continue;
- if (s[len] != new->name[len]) break;
- }
- if (s[len] || strcmp(new->name+len, ".ko")) break;
+ if (!S_ISREG(new->st.st_mode)) return DIRTREE_RECURSE;
- modinfo_file(s = dirtree_path(new, 0));
- free(s);
+ s = toys.optargs[TT.mod];
- return DIRTREE_ABORT;
- }
+ // The kernel treats - and _ the same, so we should too.
+ for (len = 0; s[len]; len++) {
+ if (s[len] == '-' && new->name[len] == '_') continue;
+ if (s[len] == '_' && new->name[len] == '-') continue;
+ if (s[len] != new->name[len]) break;
}
+ if (s[len] || strcmp(new->name+len, ".ko")) return DIRTREE_RECURSE;
+
+ modinfo_file(s = dirtree_path(new, 0));
+ free(s);
- return DIRTREE_RECURSE;
+ return DIRTREE_ABORT;
}
void modinfo_main(void)
@@ -120,9 +115,7 @@ void modinfo_main(void)
}
for (TT.mod = 0; TT.mod<toys.optc; TT.mod++) {
- char *s = strstr(toys.optargs[TT.mod], ".ko");
-
- if (s && !s[3]) modinfo_file(toys.optargs[TT.mod]);
+ if (strend(toys.optargs[TT.mod], ".ko")) modinfo_file(toys.optargs[TT.mod]);
else {
char *path = xmprintf("%s/lib/modules/%s", TT.b, TT.k);