]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsfd: fill TYPE field
authorMasatake YAMATO <yamato@redhat.com>
Wed, 24 Mar 2021 22:42:15 +0000 (07:42 +0900)
committerKarel Zak <kzak@redhat.com>
Wed, 6 Oct 2021 09:01:53 +0000 (11:01 +0200)
misc-utils/Makemodule.am
misc-utils/lsfd-fd-file.c [new file with mode: 0644]
misc-utils/lsfd-file.c [new file with mode: 0644]
misc-utils/lsfd-regular-fd-file.c [new file with mode: 0644]
misc-utils/lsfd.c
misc-utils/lsfd.h [new file with mode: 0644]

index 5f162b8c72bf345e150f03c3d7da6cff2627115b..1e36b9c9c55592af803d30147427099ae8986854 100644 (file)
@@ -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 (file)
index 0000000..a9f645e
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * lsfd(1) - list file descriptors
+ *
+ * Copyright (C) 2021 Red Hat, Inc. All rights reserved.
+ * Written by Masatake YAMATO <yamato@redhat.com>
+ *
+ * Very generally based on lsof(8) by Victor A. Abell <abe@purdue.edu>
+ * 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 (file)
index 0000000..8efd1b0
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * lsfd(1) - list file descriptors
+ *
+ * Copyright (C) 2021 Red Hat, Inc. All rights reserved.
+ * Written by Masatake YAMATO <yamato@redhat.com>
+ *
+ * Very generally based on lsof(8) by Victor A. Abell <abe@purdue.edu>
+ * 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 (file)
index 0000000..1bcf896
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * lsfd(1) - list file descriptors
+ *
+ * Copyright (C) 2021 Red Hat, Inc. All rights reserved.
+ * Written by Masatake YAMATO <yamato@redhat.com>
+ *
+ * Very generally based on lsof(8) by Victor A. Abell <abe@purdue.edu>
+ * 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: &regular_fd_file_class,
+                           sb, name, fd);
+}
index 900334e955a26cb0ef9fe2e40694acf1b62e208f..0a2f46668577c5c3a9cd8b3e8730c1f19255534c 100644 (file)
 
 #include <stdio.h>
 #include <sys/types.h>
-#include <dirent.h>
 #include <inttypes.h>
 #include <pthread.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <getopt.h>
-#include <stdbool.h>
 
 #include "c.h"
 #include "nls.h"
 
 #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 (file)
index 0000000..1848518
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * lsfd(1) - list file descriptors
+ *
+ * Copyright (C) 2021 Red Hat, Inc. All rights reserved.
+ * Written by Masatake YAMATO <yamato@redhat.com>
+ *
+ * Very generally based on lsof(8) by Victor A. Abell <abe@purdue.edu>
+ * 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 <stdbool.h>
+#include <sys/stat.h>
+#include <dirent.h>
+
+#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 */