]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsfd: revise the code disabling hyperlinks
authorMasatake YAMATO <yamato@redhat.com>
Sat, 30 Aug 2025 18:18:32 +0000 (03:18 +0900)
committerMasatake YAMATO <yamato@redhat.com>
Mon, 1 Sep 2025 02:51:02 +0000 (11:51 +0900)
In the original code, the code was at file.c.  This change lifts up
the code to upper layer.  As a result the fill_column method of struct
file becomes simple.

As a side effect. this change disables hyperlinks for the entries of
UNKN type (e.g. eventpool, or pidfd). This is a bug fix.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
lsfd-cmd/bdev.c
lsfd-cmd/cdev.c
lsfd-cmd/fifo.c
lsfd-cmd/file.c
lsfd-cmd/lsfd.c
lsfd-cmd/lsfd.h
lsfd-cmd/sock.c
lsfd-cmd/unkn.c
tests/expected/lsfd/option-hyperlink-UNKN-type-file [new file with mode: 0644]
tests/ts/lsfd/option-hyperlink

index fc1bb68807d8763fca83ca3da2d7af54c960f1ec..934c73335cbb214d592f26cb1fbea4b493f43b1b 100644 (file)
@@ -33,8 +33,7 @@ static bool bdev_fill_column(struct proc *proc __attribute__((__unused__)),
                             struct file *file __attribute__((__unused__)),
                             struct libscols_line *ln,
                             int column_id,
-                            size_t column_index,
-                            const char *uri __attribute__((__unused__)))
+                            size_t column_index)
 {
        char *str = NULL;
        const char *partition, *devdrv;
index 0f4d34fe716193cf1514999d1ad2ed5ae0078ad9..1405f4c65cd5021aa148061f4915854cdce9be3c 100644 (file)
@@ -67,8 +67,7 @@ static bool cdev_fill_column(struct proc *proc __attribute__((__unused__)),
                             struct file *file,
                             struct libscols_line *ln,
                             int column_id,
-                            size_t column_index,
-                            const char *uri __attribute__((__unused__)))
+                            size_t column_index)
 {
        struct cdev *cdev = (struct cdev *)file;
        const struct cdev_ops *ops = cdev->cdev_ops;
index 45821630c09d717307713ebd2a8cc5a27e5e0937..b78e6d4875cb85170bebc6df8a4dccb07a568093 100644 (file)
@@ -45,8 +45,7 @@ static bool fifo_fill_column(struct proc *proc __attribute__((__unused__)),
                             struct file *file,
                             struct libscols_line *ln,
                             int column_id,
-                            size_t column_index,
-                            const char *uri __attribute__((__unused__)))
+                            size_t column_index)
 {
        char *str = NULL;
 
index 841991e6e54cbf641382cf83277e85006405f985..2857c941039d85fb64ac8e088e2fff54fdd51694 100644 (file)
@@ -116,8 +116,7 @@ static bool abst_fill_column(struct proc *proc,
                             struct file *file,
                             struct libscols_line *ln,
                             int column_id,
-                            size_t column_index,
-                            const char *uri __attribute__((__unused__)))
+                            size_t column_index)
 {
        char *str = NULL;
 
@@ -261,8 +260,7 @@ static bool error_fill_column(struct proc *proc __attribute__((__unused__)),
                              struct file *file __attribute__((__unused__)),
                              struct libscols_line *ln,
                              int column_id,
-                             size_t column_index,
-                             const char *uri __attribute__((__unused__)))
+                             size_t column_index)
 {
        char *str = NULL;
        const char *ename;
@@ -303,8 +301,7 @@ static bool readlink_error_fill_column(struct proc *proc __attribute__((__unused
                                       struct file *file __attribute__((__unused__)),
                                       struct libscols_line *ln __attribute__((__unused__)),
                                       int column_id,
-                                      size_t column_index __attribute__((__unused__)),
-                                      const char *uri __attribute__((__unused__)))
+                                      size_t column_index __attribute__((__unused__)))
 {
        switch(column_id) {
        case COL_NAME:
@@ -405,8 +402,7 @@ static bool file_fill_column(struct proc *proc __attribute__((__unused__)),
                             struct file *file,
                             struct libscols_line *ln,
                             int column_id,
-                            size_t column_index,
-                            const char *uri __attribute__((__unused__)))
+                            size_t column_index)
 {
        char *str = NULL;
        mode_t ftype;
@@ -424,11 +420,6 @@ static bool file_fill_column(struct proc *proc __attribute__((__unused__)),
                                *d = '(';
                                if (r)
                                        err(EXIT_FAILURE, _("failed to add output data"));
-                               if (uri) {
-                                       struct libscols_cell *ce = scols_line_get_cell(ln, column_index);
-                                       if (ce)
-                                               scols_cell_disable_uri(ce, 1);
-                               }
                                return true;
                        }
                }
@@ -437,15 +428,6 @@ static bool file_fill_column(struct proc *proc __attribute__((__unused__)),
                if (file->name
                    && scols_line_set_data(ln, column_index, file->name))
                        err(EXIT_FAILURE, _("failed to add output data"));
-
-               ftype = file->stat.st_mode & S_IFMT;
-               if (uri && (!file->name || *file->name != '/'
-                           || (ftype != S_IFREG && ftype != S_IFDIR)
-                           || file->stat.st_nlink == 0)) {
-                       struct libscols_cell *ce = scols_line_get_cell(ln, column_index);
-                       if (ce)
-                               scols_cell_disable_uri(ce, 1);
-               }
                return true;
        case COL_STTYPE:
        case COL_TYPE:
@@ -815,8 +797,7 @@ static bool nsfs_file_fill_column(struct proc *proc __attribute__((__unused__)),
                                  struct file *file,
                                  struct libscols_line *ln,
                                  int column_id,
-                                 size_t column_index,
-                                 const char *uri __attribute__((__unused__)))
+                                 size_t column_index)
 {
        struct nsfs_file *nsfs_file = (struct nsfs_file *)file;
        char *name = NULL;
@@ -893,8 +874,7 @@ static bool mqueue_file_fill_column(struct proc *proc __attribute__((__unused__)
                                    struct file *file __attribute__((__unused__)),
                                    struct libscols_line *ln,
                                    int column_id,
-                                   size_t column_index,
-                                   const char *uri __attribute__((__unused__)))
+                                   size_t column_index)
 {
        switch (column_id) {
        case COL_TYPE:
@@ -1006,8 +986,7 @@ static bool pidfs_file_fill_column(struct proc *proc __attribute__((__unused__))
                                   struct file *file,
                                   struct libscols_line *ln,
                                   int column_id,
-                                  size_t column_index,
-                                  const char *uri __attribute__((__unused__)))
+                                  size_t column_index)
 {
        struct pidfs_file *pidfs_file = (struct pidfs_file *)file;
        char *buf = NULL;
index bca615abd6af6ead64b64fa2461ebdbc8a4d3007..d6d6a4f013b10e06ae5589148d1a98bc0ecb4c10 100644 (file)
@@ -171,6 +171,7 @@ struct colinfo {
        int flags;
        int json_type;
        const char *help;
+       bool hyperlink;
 };
 
 /* columns descriptions */
@@ -264,7 +265,8 @@ static const struct colinfo infos[] = {
                                   N_("list of monitoring inodes (raw, don't decode devices)") },
        [COL_KNAME]            = { "KNAME",
                                   0.4, SCOLS_FL_TRUNC, SCOLS_JSON_STRING,
-                                  N_("name of the file (raw)") },
+                                  N_("name of the file (raw)"),
+                                  .hyperlink = true },
        [COL_KTHREAD]          = { "KTHREAD",
                                   0,   SCOLS_FL_RIGHT, SCOLS_JSON_BOOLEAN,
                                   N_("opened by a kernel thread") },
@@ -285,7 +287,8 @@ static const struct colinfo infos[] = {
                                   N_("access mode (rwx)") },
        [COL_NAME]             = { "NAME",
                                   0.4, SCOLS_FL_TRUNC, SCOLS_JSON_STRING,
-                                  N_("name of the file (cooked)") },
+                                  N_("name of the file (cooked)"),
+                                  .hyperlink = true },
        [COL_NETLINK_GROUPS]   = { "NETLINK.GROUPS",
                                   0,   SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER,
                                   N_("netlink multicast groups") },
@@ -575,7 +578,7 @@ static const struct counter_spec default_counter_specs[] = {
 struct filler_data {
        struct proc *proc;
        struct file *file;
-       const char *uri;
+       bool hyperlink_enabled;
 };
 
 struct lsfd_control {
@@ -664,7 +667,7 @@ static struct libscols_column *add_column(struct libscols_table *tb,
                        scols_column_set_safechars(cl, "\n");
                }
                if (!(extra & SCOLS_FL_HIDDEN) && uri &&
-                   (id == COL_NAME || id == COL_KNAME))
+                   col->hyperlink)
                        scols_column_set_uri(cl, uri);
        }
 
@@ -1482,20 +1485,40 @@ void add_endpoint(struct ipc_endpoint *endpoint, struct ipc *ipc)
 }
 
 
+static bool should_disable_hyperlink(const struct file * file)
+{
+       mode_t ftype = file->stat.st_mode & S_IFMT;
+
+       return (file->name == NULL
+               || file->stat.st_nlink == 0
+               || *file->name != '/'
+               || (ftype != S_IFREG && ftype != S_IFDIR));
+}
+
 static void fill_column(struct proc *proc,
                        struct file *file,
                        struct libscols_line *ln,
                        int column_id,
                        size_t column_index,
-                       const char *uri __attribute__((__unused__)))
+                       bool hyperlink_enabled)
 {
        const struct file_class *class = file->class;
 
        while (class) {
                if (class->fill_column
                    && class->fill_column(proc, file, ln,
-                                         column_id, column_index, uri))
+                                         column_id, column_index)) {
+
+                       if (hyperlink_enabled
+                           && infos[column_id].hyperlink
+                           && should_disable_hyperlink(file)) {
+                               struct libscols_cell *ce = scols_line_get_cell(ln, column_index);
+                               if (ce)
+                                       scols_cell_disable_uri(ce, 1);
+                       }
+
                        break;
+               }
                class = class->super;
        }
 }
@@ -1509,14 +1532,14 @@ static int filter_filler_cb(
        struct filler_data *fid = (struct filler_data *) userdata;
 
        fill_column(fid->proc, fid->file, ln, get_column_id(colnum), colnum,
-                   fid->uri);
+                   fid->hyperlink_enabled);
        return 0;
 }
 
 static void convert_file(struct proc *proc,
                     struct file *file,
                     struct libscols_line *ln,
-                    const char *uri __attribute__((__unused__)))
+                    bool hyperlink_enabled)
 
 {
        size_t i;
@@ -1524,13 +1547,14 @@ static void convert_file(struct proc *proc,
        for (i = 0; i < ncolumns; i++) {
                if (scols_line_is_filled(ln, i))
                        continue;
-               fill_column(proc, file, ln, get_column_id(i), i, uri);
+               fill_column(proc, file, ln, get_column_id(i), i, hyperlink_enabled);
        }
 }
 
 static void convert(struct list_head *procs, struct lsfd_control *ctl)
 {
        struct list_head *p;
+       bool hyperlink_enabled = (ctl->uri != NULL);
 
        list_for_each (p, procs) {
                struct proc *proc = list_entry(p, struct proc, procs);
@@ -1548,7 +1572,7 @@ static void convert(struct list_head *procs, struct lsfd_control *ctl)
                                struct filler_data fid = {
                                        .proc = proc,
                                        .file = file,
-                                       .uri = ctl->uri,
+                                       .hyperlink_enabled = hyperlink_enabled,
                                };
 
                                scols_filter_set_filler_cb(ctl->filter,
@@ -1561,7 +1585,7 @@ static void convert(struct list_head *procs, struct lsfd_control *ctl)
                                }
                        }
 
-                       convert_file(proc, file, ln, ctl->uri);
+                       convert_file(proc, file, ln, hyperlink_enabled);
 
                        if (!ctl->ct_filters)
                                continue;
index 4aa7bf2bb55bb180576bd5883af46ae69b996770..916ad2d76525bf3404e0fab3b5a9266bcc287b5c 100644 (file)
@@ -235,8 +235,7 @@ struct file_class {
                            struct file *file,
                            struct libscols_line *ln,
                            int column_id,
-                           size_t column_index,
-                           const char *uri);
+                           size_t column_index);
        int  (*handle_fdinfo)(struct file *file, const char *key, const char* value);
        void (*attach_xinfo)(struct file *file);
        void (*initialize_content)(struct file *file);
index db789bbb346d6ea52a014c1816eb6ae6251299eb..2780c9f34255829826e1c6e8f2ed4975af8a7b63 100644 (file)
@@ -51,8 +51,7 @@ static bool sock_fill_column(struct proc *proc __attribute__((__unused__)),
                             struct file *file,
                             struct libscols_line *ln,
                             int column_id,
-                            size_t column_index,
-                            const char *uri __attribute__((__unused__)))
+                            size_t column_index)
 {
        char *str = NULL;
        struct sock *sock = (struct sock *)file;
index 76731d29147c4272916c9c5134919795e8889335..efd6d402c084901dfbdda4b6a01d0297dede219e 100644 (file)
@@ -82,8 +82,7 @@ static bool unkn_fill_column(struct proc *proc,
                             struct file *file,
                             struct libscols_line *ln,
                             int column_id,
-                            size_t column_index,
-                            const char *uri __attribute__((__unused__)))
+                            size_t column_index)
 {
        char *str = NULL;
        struct unkn *unkn = (struct unkn *)file;
diff --git a/tests/expected/lsfd/option-hyperlink-UNKN-type-file b/tests/expected/lsfd/option-hyperlink-UNKN-type-file
new file mode 100644 (file)
index 0000000..90c5845
--- /dev/null
@@ -0,0 +1,7 @@
+# NAME
+00000000  74 66 64 73 3d 34 2c 35  0a                       |tfds=4,5.|
+00000009
+# KNAME
+00000000  61 6e 6f 6e 5f 69 6e 6f  64 65 3a 5b 65 76 65 6e  |anon_inode:[even|
+00000010  74 70 6f 6c 6c 5d 0a                              |tpoll].|
+00000017
index 4529d2f005527eb4320eb85c5cc5efff92607d5a..12e9caa0352c9e19deedb35c4ac9eabd60a4dbc8 100755 (executable)
@@ -95,4 +95,22 @@ ts_init_subtest "deleted-file"
 wait "${MKFDS_PID}"
 ts_finalize_subtest
 
+ts_init_subtest "UNKN-type-file"
+{
+    coproc MKFDS { "$TS_HELPER_MKFDS" eventpoll $FD $((FD + 1)) $((FD + 2)); }
+    if read -r -u "${MKFDS[0]}" PID; then
+       for o in NAME KNAME; do
+           echo "# $o"
+           "${TS_CMD_LSFD}" -n --hyperlink=always -o "$o" -p "${PID}" -Q "$EXPR" \
+               | replace_hostname \
+               | replace_filename \
+               | "$TS_CMD_HEXDUMP" -C
+       done
+       echo DONE >&"${MKFDS[1]}"
+    fi
+} > "$TS_OUTPUT" 2>&1
+wait "${MKFDS_PID}"
+ts_finalize_subtest
+
+
 ts_finalize