📄 depmod.c
字号:
for (i = 0; i < module->num_deps; i++) if (has_dep_loop(module->deps[i], &traverse)) return 1; return 0;}/* Uniquifies and orders a dependency list. */static void order_dep_list(struct module *start, struct module *mod){ unsigned int i; for (i = 0; i < mod->num_deps; i++) { /* If it was previously depended on, move it to the tail. ie. if a needs b and c, and c needs b, we must order b after c. */ list_del(&mod->deps[i]->dep_list); list_add_tail(&mod->deps[i]->dep_list, &start->dep_list); order_dep_list(start, mod->deps[i]); }}static void del_module(struct module **modules, struct module *delme){ struct module **i; /* Find pointer to it. */ for (i = modules; *i != delme; i = &(*i)->next); *i = delme->next;}static void output_deps(struct module *modules, FILE *out){ struct module *i; for (i = modules; i; i = i->next) i->ops->calculate_deps(i, verbose); /* Strip out loops. */ again: for (i = modules; i; i = i->next) { if (has_dep_loop(i, NULL)) { warn("Module %s ignored, due to loop\n", i->pathname + skipchars); del_module(&modules, i); goto again; } } /* Now dump them out. */ for (i = modules; i; i = i->next) { struct list_head *j, *tmp; order_dep_list(i, i); fprintf(out, "%s:", i->pathname + skipchars); list_for_each_safe(j, tmp, &i->dep_list) { struct module *dep = list_entry(j, struct module, dep_list); fprintf(out, " %s", dep->pathname + skipchars); list_del_init(j); } fprintf(out, "\n"); }}static int smells_like_module(const char *name){ return ends_in(name,".ko") || ends_in(name, ".ko.gz");}static struct module *grab_dir(const char *dirname, struct module *next){ DIR *dir; struct dirent *dirent; dir = opendir(dirname); if (!dir) { warn("Couldn't open directory %s: %s\n", dirname, strerror(errno)); return next; } while ((dirent = readdir(dir)) != NULL) { if (smells_like_module(dirent->d_name)) next = grab_module(dirname, dirent->d_name, next); else if (!streq(dirent->d_name, ".") && !streq(dirent->d_name, "..")) { struct stat st; char subdir[strlen(dirname) + 1 + strlen(dirent->d_name) + 1]; sprintf(subdir, "%s/%s", dirname, dirent->d_name); if (lstat(subdir, &st) != 0) warn("Couldn't stat %s: %s\n", subdir, strerror(errno)); else if (S_ISDIR(st.st_mode)) next = grab_dir(subdir, next); } } closedir(dir); return next;}/* Convert filename to the module name. Works if filename == modname, too. */static void filename2modname(char *modname, const char *filename){ const char *afterslash; unsigned int i; afterslash = strrchr(filename, '/'); if (!afterslash) afterslash = filename; else afterslash++; /* Convert to underscores, stop at first . */ for (i = 0; afterslash[i] && afterslash[i] != '.'; i++) { if (afterslash[i] == '-') modname[i] = '_'; else modname[i] = afterslash[i]; } modname[i] = '\0';}/* Simply dump hash table. */static void output_symbols(struct module *unused, FILE *out){ unsigned int i; fprintf(out, "# Aliases for symbols, used by symbol_request().\n"); for (i = 0; i < SYMBOL_HASH_SIZE; i++) { struct symbol *s; for (s = symbolhash[i]; s; s = s->next) { if (s->owner) { char modname[strlen(s->owner->pathname)+1]; filename2modname(modname, s->owner->pathname); fprintf(out, "alias symbol:%s %s\n", s->name, modname); } } }}static const char *next_string(const char *string, unsigned long *secsize){ /* Skip non-zero chars */ while (string[0]) { string++; if ((*secsize)-- <= 1) return NULL; } /* Skip any zero padding. */ while (!string[0]) { string++; if ((*secsize)-- <= 1) return NULL; } return string;}static void output_aliases(struct module *modules, FILE *out){ struct module *i; const char *p; long size; fprintf(out, "# Aliases extracted from modules themselves.\n"); for (i = modules; i; i = i->next) { char modname[strlen(i->pathname)+1]; filename2modname(modname, i->pathname); /* Grab from old-style .modalias section. */ for (p = i->ops->get_aliases(i, &size); p; p = next_string(p, &size)) fprintf(out, "alias %s %s\n", p, modname); /* Grab form new-style .modinfo section. */ for (p = i->ops->get_modinfo(i, &size); p; p = next_string(p, &size)) { if (strncmp(p, "alias=", strlen("alias=")) == 0) fprintf(out, "alias %s %s\n", p + strlen("alias="), modname); } }}struct depfile { char *name; void (*func)(struct module *, FILE *);};static struct depfile depfiles[] = { { "modules.dep", output_deps }, /* This is what we check for '-A'. */ { "modules.pcimap", output_pci_table }, { "modules.usbmap", output_usb_table }, { "modules.ccwmap", output_ccw_table }, { "modules.ieee1394map", output_ieee1394_table }, { "modules.isapnpmap", output_isapnp_table }, { "modules.inputmap", output_input_table }, { "modules.alias", output_aliases }, { "modules.symbols", output_symbols },};/* If we can't figure it out, it's safe to say "true". */static int any_modules_newer(const char *dirname, time_t mtime){ DIR *dir; struct dirent *dirent; dir = opendir(dirname); if (!dir) return 1; while ((dirent = readdir(dir)) != NULL) { struct stat st; char file[strlen(dirname) + 1 + strlen(dirent->d_name) + 1]; if (streq(dirent->d_name, ".") || streq(dirent->d_name, "..")) continue; sprintf(file, "%s/%s", dirname, dirent->d_name); if (lstat(file, &st) != 0) return 1; if (smells_like_module(dirent->d_name)) { if (st.st_mtime > mtime) return 1; } else if (S_ISDIR(st.st_mode)) { if (any_modules_newer(file, mtime)) return 1; } } closedir(dir); return 0;}static int depfile_out_of_date(const char *dirname){ struct stat st; char depfile[strlen(dirname) + 1 + strlen(depfiles[0].name) + 1]; sprintf(depfile, "%s/%s", dirname, depfiles[0].name); if (stat(depfile, &st) != 0) return 1; return any_modules_newer(dirname, st.st_mtime);}int main(int argc, char *argv[]){ int opt, all = 0, maybe_all = 0, doing_stdout = 0; char *basedir = "", *dirname, *version, *badopt = NULL, *system_map = NULL; struct module *list = NULL; int i; /* Don't print out any errors just yet, we might want to exec backwards compat version. */ opterr = 0; while ((opt = getopt_long(argc, argv, "ab:ArehnqruvVF:C:", options, NULL)) != -1) { switch (opt) { case 'a': all = 1; break; case 'b': basedir = optarg; skipchars = strlen(basedir); break; case 'A': maybe_all = 1; break; case 'F': system_map = optarg; break; case 'e': print_unknown = 1; break; case 'v': verbose = 1; break; case 'u': case 'q': case 'r': case 'C': /* Ignored. */ break; case 'h': print_usage(argv[0]); break; case 'n': doing_stdout = 1; break; case 'V': printf("%s %s\n", PACKAGE, VERSION); exit(0); default: badopt = argv[optind-1]; } } /* We can't print unknowns without a System.map */ if (!system_map) print_unknown = 0; else load_system_map(system_map); /* They can specify the version naked on the command line */ if (optind < argc && is_version_number(argv[optind])) { version = strdup(argv[optind]); optind++; } else { struct utsname buf; uname(&buf); version = strdup(buf.release); } /* Run old version if required. */ if (old_module_version(version)) exec_old_depmod(argv); if (badopt) { fprintf(stderr, "%s: malformed/unrecognized option '%s'\n", argv[0], badopt); print_usage(argv[0]); exit(1); } /* Depmod -a by default if no names. */ if (optind == argc) all = 1; dirname = malloc(strlen(basedir) + strlen(MODULE_DIR) + strlen(version) + 1); sprintf(dirname, "%s%s%s", basedir, MODULE_DIR, version); if (maybe_all) { if (!doing_stdout && !depfile_out_of_date(dirname)) exit(0); all = 1; } if (!all) { /* Do command line args. */ for (opt = optind + 1; opt < argc; opt++) list = grab_module("", argv[opt], list); } else { list = grab_dir(dirname, list); } for (i = 0; i < sizeof(depfiles)/sizeof(depfiles[0]); i++) { FILE *out; struct depfile *d = &depfiles[i]; char depname[strlen(dirname) + 1 + strlen(d->name) + 1]; char tmpname[strlen(dirname) + 1 + strlen(d->name) + strlen(".temp") + 1]; sprintf(depname, "%s/%s", dirname, d->name); sprintf(tmpname, "%s/%s.temp", dirname, d->name); if (!doing_stdout) { out = fopen(tmpname, "w"); if (!out) fatal("Could not open %s for writing: %s\n", tmpname, strerror(errno)); } else out = stdout; d->func(list, out); if (!doing_stdout) { fclose(out); if (rename(tmpname, depname) < 0) fatal("Could not rename %s into %s: %s\n", tmpname, depname, strerror(errno)); } } free(dirname); free(version); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -