From: Masatake YAMATO Date: Wed, 24 Mar 2021 22:42:15 +0000 (+0900) Subject: lsfd: fill TYPE field X-Git-Tag: v2.38-rc1~144^2~180 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=600e6e5257ffa59c809aae66c024fbd5a026aa0e;p=thirdparty%2Futil-linux.git lsfd: fill TYPE field --- diff --git a/misc-utils/Makemodule.am b/misc-utils/Makemodule.am index 5f162b8c72..1e36b9c9c5 100644 --- a/misc-utils/Makemodule.am +++ b/misc-utils/Makemodule.am @@ -250,7 +250,11 @@ if BUILD_LSFD bin_PROGRAMS += lsfd # MANPAGES += misc-utils/lsfd.1 lsfd_SOURCES = \ - misc-utils/lsfd.c + misc-utils/lsfd.c \ + misc-utils/lsfd.h \ + misc-utils/lsfd-file.c \ + misc-utils/lsfd-fd-file.c \ + misc-utils/lsfd-regular-fd-file.c lsfd_LDADD = $(LDADD) libsmartcols.la libcommon.la lsfd_LDFLAGS = -pthread lsfd_CFLAGS = $(AM_CFLAGS) -I$(ul_libsmartcols_incdir) -pthread diff --git a/misc-utils/lsfd-fd-file.c b/misc-utils/lsfd-fd-file.c new file mode 100644 index 0000000000..a9f645edb5 --- /dev/null +++ b/misc-utils/lsfd-fd-file.c @@ -0,0 +1,69 @@ +/* + * lsfd(1) - list file descriptors + * + * Copyright (C) 2021 Red Hat, Inc. All rights reserved. + * Written by Masatake YAMATO + * + * Very generally based on lsof(8) by Victor A. Abell + * It supports multiple OSes. lsfd specializes to Linux. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "xalloc.h" +#include "nls.h" +#include "libsmartcols.h" + +#include "lsfd.h" + +static bool fd_file_fill_column(struct proc *proc __attribute__((__unused__)), + struct file *file, + struct libscols_line *ln, + int column_id, + size_t column_index) +{ + char *str = NULL; + struct fd_file * fd_file = (struct fd_file *)file; + + switch(column_id) { + case COL_FD: + xasprintf(&str, "%d", fd_file->fd); + if (!str) + err(EXIT_FAILURE, _("failed to add output data")); + if (scols_line_refer_data(ln, column_index, str)) + err(EXIT_FAILURE, _("failed to add output data")); + return true; + }; + + return false; +} + +const struct file_class fd_file_class = { + .super = &file_class, + .size = sizeof(struct fd_file), + .fill_column = fd_file_fill_column, + .free_content = NULL, +}; + +struct file *make_fd_file(const struct file_class *class, + struct stat *sb, const char *name, int fd) +{ + struct file *file = make_file(class? class: &fd_file_class, + sb, name); + + ((struct fd_file *)(file))->fd = fd; + + return file; +} diff --git a/misc-utils/lsfd-file.c b/misc-utils/lsfd-file.c new file mode 100644 index 0000000000..8efd1b0007 --- /dev/null +++ b/misc-utils/lsfd-file.c @@ -0,0 +1,110 @@ +/* + * lsfd(1) - list file descriptors + * + * Copyright (C) 2021 Red Hat, Inc. All rights reserved. + * Written by Masatake YAMATO + * + * Very generally based on lsof(8) by Victor A. Abell + * It supports multiple OSes. lsfd specializes to Linux. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "xalloc.h" +#include "nls.h" + +#include "libsmartcols.h" + +#include "lsfd.h" + +static const char *strftype(mode_t ftype) +{ + switch (ftype) { + case S_IFBLK: + return "BLK"; + case S_IFCHR: + return "CHR"; + case S_IFDIR: + return "DIR"; + case S_IFIFO: + return "FIFO"; + case S_IFLNK: + return "LINK"; + case S_IFREG: + return "REG"; + case S_IFSOCK: + return "SOCK"; + default: + return "UNKN"; + } +} + +static bool file_fill_column(struct proc *proc, + struct file *file, + struct libscols_line *ln, + int column_id, + size_t column_index) +{ + char *str = NULL; + mode_t ftype; + + switch(column_id) { + case COL_COMMAND: + if (proc->command && scols_line_set_data(ln, column_index, proc->command)) + err(EXIT_FAILURE, _("failed to add output data")); + return true; + case COL_NAME: + if (file->name && scols_line_set_data(ln, column_index, file->name)) + err(EXIT_FAILURE, _("failed to add output data")); + return true; + case COL_TYPE: + ftype = file->stat.st_mode & S_IFMT; + if (scols_line_set_data(ln, column_index, strftype(ftype))) + err(EXIT_FAILURE, _("failed to add output data")); + return true; + case COL_PID: + xasprintf(&str, "%d", (int)proc->pid); + if (!str) + err(EXIT_FAILURE, _("failed to add output data")); + if (scols_line_refer_data(ln, column_index, str)) + err(EXIT_FAILURE, _("failed to add output data")); + return true; + }; + + return false; +} + +static void file_free_content(struct file *file) +{ + free(file->name); +} + +struct file *make_file(const struct file_class *class, + struct stat *sb, const char *name) +{ + struct file *file = xcalloc(1, class->size); + + file->class = class; + file->name = xstrdup(name); + file->stat = *sb; + return file; +} + +const struct file_class file_class = { + .super = NULL, + .size = 0, + .fill_column = file_fill_column, + .free_content = file_free_content, +}; diff --git a/misc-utils/lsfd-regular-fd-file.c b/misc-utils/lsfd-regular-fd-file.c new file mode 100644 index 0000000000..1bcf8962cb --- /dev/null +++ b/misc-utils/lsfd-regular-fd-file.c @@ -0,0 +1,59 @@ +/* + * lsfd(1) - list file descriptors + * + * Copyright (C) 2021 Red Hat, Inc. All rights reserved. + * Written by Masatake YAMATO + * + * Very generally based on lsof(8) by Victor A. Abell + * It supports multiple OSes. lsfd specializes to Linux. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "xalloc.h" +#include "nls.h" +#include "libsmartcols.h" + +#include "lsfd.h" + +static bool regular_fd_file_fill_column(struct proc *proc __attribute__((__unused__)), + struct file *file __attribute__((__unused__)), + struct libscols_line *ln, + int column_id, + size_t column_index) +{ + switch(column_id) { + case COL_TYPE: + if (scols_line_set_data(ln, column_index, "REG")) + err(EXIT_FAILURE, _("failed to add output data")); + return true; + } + + return false; +} + +const struct file_class regular_fd_file_class = { + .super = &fd_file_class, + .size = sizeof(struct fd_file), + .fill_column = regular_fd_file_fill_column, + .free_content = NULL, +}; + +struct file *make_regular_fd_file(const struct file_class *class, + struct stat *sb, const char *name, int fd) +{ + return make_fd_file(class? class: ®ular_fd_file_class, + sb, name, fd); +} diff --git a/misc-utils/lsfd.c b/misc-utils/lsfd.c index 900334e955..0a2f466685 100644 --- a/misc-utils/lsfd.c +++ b/misc-utils/lsfd.c @@ -24,13 +24,11 @@ #include #include -#include #include #include #include #include #include -#include #include "c.h" #include "nls.h" @@ -43,18 +41,7 @@ #include "libsmartcols.h" -#define list_free(LIST,TYPE,MEMBER,FREEFN) \ - do { \ - struct list_head *__p, *__pnext; \ - \ - list_for_each_safe (__p, __pnext, (LIST)) { \ - TYPE *__elt = list_entry(__p, TYPE, MEMBER); \ - list_del(__p); \ - FREEFN(__elt); \ - } \ - } while (0) - -DIR *opendirf(const char *format, ...) __attribute__((format (printf, 1, 2))); +#include "lsfd.h" /* * Multi-threading related stuffs @@ -72,14 +59,6 @@ static void *fill_procs(void *arg); * Column related stuffs */ -/* column IDs */ -enum { - COL_PID, - COL_FD, - COL_NAME, - COL_COMMAND, -}; - /* column names */ struct colinfo { const char *name; @@ -94,6 +73,7 @@ static struct colinfo infos[] = { [COL_FD] = { "FD", 5, SCOLS_FL_RIGHT, N_("file descriptor for the file") }, [COL_NAME] = { "NAME", 30, 0, N_("name of the file") }, [COL_COMMAND] = { "COMMAND", 10, 0, N_("command of the process opening the file") }, + [COL_TYPE] = { "TYPE", 7, 0, N_("file type") }, }; static int columns[ARRAY_SIZE(infos) * 2] = {-1}; @@ -136,87 +116,6 @@ static const struct colinfo *get_column_info(int num) return &infos[ get_column_id(num) ]; } -struct proc { - pid_t pid; - char *command; - struct list_head procs; - struct list_head files; -}; - -/* - * File classes - */ -struct file { - struct list_head files; - const struct file_class *class; - char *name; -}; - -struct fd_file { - struct file file; - int fd; -}; - -struct file_class { - const struct file_class *super; - size_t size; - bool (*fill_column)(struct proc *proc, - struct file *file, - struct libscols_line *ln, - int column_id, - size_t column_index); - void (*free_content)(struct file *file); -}; - -static bool file_fill_column(struct proc *proc, - struct file *file, - struct libscols_line *ln, - int column_id, - size_t column_index); -static void file_free_content(struct file *file); -static const struct file_class file_class = { - .super = NULL, - .size = 0, - .fill_column = file_fill_column, - .free_content = file_free_content, -}; - -static bool fd_file_fill_column(struct proc *proc, - struct file *file, - struct libscols_line *ln, - int column_id, - size_t column_index); -static const struct file_class fd_file_class = { - .super = &file_class, - .size = sizeof(struct fd_file), - .fill_column = fd_file_fill_column, - .free_content = NULL, -}; - -static struct file *make_file(const struct file_class *class, const char *name) -{ - struct file *file = xcalloc(1, class->size); - - file->class = class; - file->name = xstrdup(name); - return file; -} - -static void file_free_content(struct file *file) -{ - free(file->name); -} - -static struct file *make_fd_file(int fd, const char *name) -{ - struct file *file = make_file(&fd_file_class, name); - - ((struct fd_file *)(file))->fd = fd; - - return file; - -} - static struct proc *make_proc(pid_t pid) { struct proc *proc = xcalloc(1, sizeof(*proc)); @@ -333,7 +232,12 @@ static struct file *collect_file(int dd, struct dirent *dp) if ((len = readlinkat(dd, dp->d_name, sym, sizeof(sym) - 1)) < 0) return NULL; - return make_fd_file((int)num, sym); + switch (sb.st_mode & S_IFMT) { + case S_IFREG: + return make_regular_fd_file(NULL, &sb, sym, (int)num); + } + + return make_fd_file(NULL, &sb, sym, (int)num); } static void enqueue_file(struct proc *proc, struct file * file) @@ -377,6 +281,7 @@ static void fill_proc(struct proc *proc) collect_files(proc); } + static void *fill_procs(void *arg) { struct list_head *procs = arg; @@ -421,57 +326,6 @@ static void *fill_procs(void *arg) return NULL; } -static bool file_fill_column(struct proc *proc, - struct file *file, - struct libscols_line *ln, - int column_id, - size_t column_index) -{ - char *str = NULL; - - switch(column_id) { - case COL_COMMAND: - if (proc->command && scols_line_set_data(ln, column_index, proc->command)) - err(EXIT_FAILURE, _("failed to add output data")); - return true; - case COL_NAME: - if (file->name && scols_line_set_data(ln, column_index, file->name)) - err(EXIT_FAILURE, _("failed to add output data")); - return true; - case COL_PID: - xasprintf(&str, "%d", (int)proc->pid); - if (!str) - err(EXIT_FAILURE, _("failed to add output data")); - if (scols_line_refer_data(ln, column_index, str)) - err(EXIT_FAILURE, _("failed to add output data")); - return true; - }; - - return false; -} - -static bool fd_file_fill_column(struct proc *proc __attribute__((__unused__)), - struct file *file, - struct libscols_line *ln, - int column_id, - size_t column_index) -{ - char *str = NULL; - struct fd_file * fd_file = (struct fd_file *)file; - - switch(column_id) { - case COL_FD: - xasprintf(&str, "%d", fd_file->fd); - if (!str) - err(EXIT_FAILURE, _("failed to add output data")); - if (scols_line_refer_data(ln, column_index, str)) - err(EXIT_FAILURE, _("failed to add output data")); - return true; - }; - - return false; -} - static void fill_column(struct proc *proc, struct file *file, struct libscols_line *ln, @@ -606,6 +460,7 @@ int main(int argc, char *argv[]) columns[ncolumns++] = COL_COMMAND; columns[ncolumns++] = COL_PID; columns[ncolumns++] = COL_FD; + columns[ncolumns++] = COL_TYPE; columns[ncolumns++] = COL_NAME; } diff --git a/misc-utils/lsfd.h b/misc-utils/lsfd.h new file mode 100644 index 0000000000..18485186fa --- /dev/null +++ b/misc-utils/lsfd.h @@ -0,0 +1,107 @@ +/* + * lsfd(1) - list file descriptors + * + * Copyright (C) 2021 Red Hat, Inc. All rights reserved. + * Written by Masatake YAMATO + * + * Very generally based on lsof(8) by Victor A. Abell + * It supports multiple OSes. lsfd specializes to Linux. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef UTIL_LINUX_LSFD_H +#define UTIL_LINUX_LSFD_H + +#include +#include +#include + +#include "list.h" + +/* + * Utilities + */ +#define list_free(LIST,TYPE,MEMBER,FREEFN) \ + do { \ + struct list_head *__p, *__pnext; \ + \ + list_for_each_safe (__p, __pnext, (LIST)) { \ + TYPE *__elt = list_entry(__p, TYPE, MEMBER); \ + list_del(__p); \ + FREEFN(__elt); \ + } \ + } while (0) + +DIR *opendirf(const char *format, ...) __attribute__((format (printf, 1, 2))); + +/* + * column IDs + */ +enum { + COL_PID, + COL_FD, + COL_NAME, + COL_COMMAND, + COL_TYPE, +}; + +/* + * Process structure + */ +struct proc { + pid_t pid; + char *command; + struct list_head procs; + struct list_head files; +}; + +/* + * File classes + */ +struct file { + struct list_head files; + const struct file_class *class; + char *name; + struct stat stat; +}; + +struct fd_file { + struct file file; + int fd; +}; + +struct file_class { + const struct file_class *super; + size_t size; + bool (*fill_column)(struct proc *proc, + struct file *file, + struct libscols_line *ln, + int column_id, + size_t column_index); + void (*free_content)(struct file *file); +}; + +extern const struct file_class +file_class, fd_file_class, regular_fd_file_class + ; + +struct file *make_file(const struct file_class *class, + struct stat *sb, const char *name); +struct file *make_fd_file(const struct file_class *class, + struct stat *sb, const char *name, int fd); +struct file *make_regular_fd_file(const struct file_class *class, + struct stat *sb, const char *name, int fd); + +#endif /* UTIL_LINUX_LSFD_H */