int pidof_main(const struct cmd_pidof_info* info) { const char* name = info->name; DIR* procdir = xopendir("/proc"); struct dirent* ent; unsigned long found_pid = 0; bool found = false; while ((ent = readdir(procdir)) != NULL) { SCOPED_RESLIST(rl); char* endptr = NULL; errno = 0; unsigned long pid = strtoul(ent->d_name, &endptr, 10); if (pid == 0 || errno != 0 || *endptr != '\0') continue; int cmdline_fd = try_xopen(xaprintf("/proc/%lu/cmdline", pid), O_RDONLY, 0); if (cmdline_fd == -1) continue; char* name = slurp_fd(cmdline_fd, NULL); if (strcmp(name, info->name) == 0) { if (found) die(EINVAL, "more than one process has name `%s'", name); found = true; found_pid = pid; } } if (!found) die(ENOENT, "no process has name `%s'", name); xprintf(xstdout, "%lu%s", found_pid, info->pidof.zero ? "" : "\n"); xflush(xstdout); return 0; }
static char * slurp_file(const char *path) { int fd; char *ret; fd = open(path, O_RDONLY); if (fd < 0) { error("Cannot open '%s': %s", path, strerror(errno)); return NULL; } ret = slurp_fd(fd); if (!ret) error("Cannot read '%s': %s", path, strerror(errno)); return ret; }
static int parse_dir(const char *dname, parser_fn *parse) { DIR *dir; struct dirent *e; dir = opendir(dname); if (!dir) { if (errno != ENOENT) error("Cannot open '%s': %s", dname, strerror(errno)); return -1; } while ( (e = readdir(dir)) ) { size_t len = strlen(e->d_name); char *endp = e->d_name + len; int fd; char *args; if (len < CONF_SUFFIX_LEN || strcmp(endp - CONF_SUFFIX_LEN, CONF_SUFFIX)) continue; fd = openat(dirfd(dir), e->d_name, O_RDONLY); if (fd < 0) { error("Cannot open '%s': %s", e->d_name, strerror(errno)); continue; } args = slurp_fd(fd); if (!args) { error("Cannot read '%s': %s", e->d_name, strerror(errno)); continue; } parse_args(args, parse); free(args); } closedir(dir); return 0; }