From: Masatake YAMATO Date: Fri, 16 Apr 2021 21:50:00 +0000 (+0900) Subject: lsfd: add cwd, exe, and root associations X-Git-Tag: v2.38-rc1~144^2~172 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a4778cb5f35150f7c983945cefffc09020139bdf;p=thirdparty%2Futil-linux.git lsfd: add cwd, exe, and root associations Signed-off-by: Masatake YAMATO --- diff --git a/misc-utils/lsfd-cdev-file.c b/misc-utils/lsfd-cdev-file.c index 1d05dcff4b..3bcf1bd911 100644 --- a/misc-utils/lsfd-cdev-file.c +++ b/misc-utils/lsfd-cdev-file.c @@ -55,7 +55,7 @@ static bool cdev_file_fill_column(struct proc *proc __attribute__((__unused__)), const struct file_class cdev_file_class = { .super = &file_class, - .size = sizeof (struct file), + .size = sizeof(struct file), .fill_column = cdev_file_fill_column, .free_content = NULL, }; diff --git a/misc-utils/lsfd-file.c b/misc-utils/lsfd-file.c index d554030210..9e94b81729 100644 --- a/misc-utils/lsfd-file.c +++ b/misc-utils/lsfd-file.c @@ -29,6 +29,14 @@ #include "lsfd.h" +static const char *assocstr[N_ASSOCS] = { + [ASSOC_CWD] = "cwd", + [ASSOC_EXE] = "exe", + /* "root" appears as user names, too. + * So we use "rtd" here instead of "root". */ + [ASSOC_ROOT] = "rtd", +}; + static const char *strftype(mode_t ftype) { switch (ftype) { @@ -88,7 +96,14 @@ static bool file_fill_column(struct proc *proc, return false; /* FALL THROUGH */ case COL_ASSOC: - xasprintf(&str, "%d", file->association); + if (file->association >= 0) + xasprintf(&str, "%d", file->association); + else { + int assoc = file->association * -1; + if (assoc >= N_ASSOCS) + return false; /* INTERNAL ERROR */ + xasprintf(&str, "%s", assocstr[assoc]); + } break; case COL_INODE: xasprintf(&str, "%llu", (unsigned long long)file->stat.st_ino); @@ -137,7 +152,7 @@ struct file *make_file(const struct file_class *class, const struct file_class file_class = { .super = NULL, - .size = sizeof (struct file), + .size = sizeof(struct file), .fill_column = file_fill_column, .free_content = file_free_content, }; diff --git a/misc-utils/lsfd.c b/misc-utils/lsfd.c index 4c53224e28..629e0cf8df 100644 --- a/misc-utils/lsfd.c +++ b/misc-utils/lsfd.c @@ -225,7 +225,21 @@ static void collect(struct list_head *procs) run_collectors(procs); } -static struct file *collect_file(int dd, struct dirent *dp) +static struct file *collect_file(struct stat *sb, char *name, int assoc) +{ + switch (sb->st_mode & S_IFMT) { + case S_IFREG: + return make_regular_file(NULL, sb, name, assoc); + case S_IFCHR: + return make_cdev_file(NULL, sb, name, assoc); + case S_IFBLK: + return make_bdev_file(NULL, sb, name, assoc); + } + + return make_file(NULL, sb, name, assoc); +} + +static struct file *collect_fd_file(int dd, struct dirent *dp) { long num; char *endptr = NULL; @@ -245,16 +259,7 @@ static struct file *collect_file(int dd, struct dirent *dp) if ((len = readlinkat(dd, dp->d_name, sym, sizeof(sym) - 1)) < 0) return NULL; - switch (sb.st_mode & S_IFMT) { - case S_IFREG: - return make_regular_file(NULL, &sb, sym, (int)num); - case S_IFCHR: - return make_cdev_file(NULL, &sb, sym, (int)num); - case S_IFBLK: - return make_bdev_file(NULL, &sb, sym, (int)num); - } - - return make_file(NULL, &sb, sym, (int)num); + return collect_file(&sb, sym, (int)num); } static void enqueue_file(struct proc *proc, struct file * file) @@ -263,7 +268,7 @@ static void enqueue_file(struct proc *proc, struct file * file) list_add_tail(&file->files, &proc->files); } -static void collect_files(struct proc *proc) +static void collect_fd_files(struct proc *proc) { DIR *dirp; int dd; @@ -279,7 +284,55 @@ static void collect_files(struct proc *proc) while ((dp = xreaddir(dirp))) { struct file *file; - if ((file = collect_file(dd, dp)) == NULL) + if ((file = collect_fd_file(dd, dp)) == NULL) + continue; + + enqueue_file(proc, file); + } + closedir(dirp); +} + +static struct file *collect_outofbox_file(int dd, const char *name, int association) +{ + struct stat sb; + ssize_t len; + char sym[PATH_MAX]; + + if (fstatat(dd, name, &sb, 0) < 0) + return NULL; + + memset(sym, 0, sizeof(sym)); + if ((len = readlinkat(dd, name, sym, sizeof(sym) - 1)) < 0) + return NULL; + + return collect_file(&sb, sym, association); +} + +static void collect_outofbox_files(struct proc *proc) +{ + DIR *dirp; + int dd; + + dirp = opendirf("/proc/%d", proc->pid); + if (!dirp) + return; + + if ((dd = dirfd(dirp)) < 0 ) + return; + + enum association assocs[] = { ASSOC_CWD, ASSOC_EXE, ASSOC_ROOT }; + const char* assoc_names[] = { + [ASSOC_CWD] = "cwd", + [ASSOC_EXE] = "exe", + [ASSOC_ROOT] = "root", + }; + + for (unsigned int i = 0; i < ARRAY_SIZE(assocs); i++) { + struct file *file; + + if ((file = collect_outofbox_file(dd, + assoc_names[assocs[i]], + assocs[i] * -1)) == NULL) continue; enqueue_file(proc, file); @@ -295,7 +348,8 @@ static void fill_proc(struct proc *proc) if (!proc->command) err(EXIT_FAILURE, _("failed to get command name")); - collect_files(proc); + collect_outofbox_files(proc); + collect_fd_files(proc); } diff --git a/misc-utils/lsfd.h b/misc-utils/lsfd.h index 896bbf58af..839660a10c 100644 --- a/misc-utils/lsfd.h +++ b/misc-utils/lsfd.h @@ -66,6 +66,13 @@ enum { /* * Process structure */ +enum association { + ASSOC_CWD = 1, + ASSOC_EXE, + ASSOC_ROOT, + N_ASSOCS, +}; + struct proc { pid_t pid; char *command;