]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsfd: introduce XMODE column, extensible variant of MODE
authorMasatake YAMATO <yamato@redhat.com>
Fri, 9 Jun 2023 12:35:55 +0000 (21:35 +0900)
committerMasatake YAMATO <yamato@redhat.com>
Thu, 22 Jun 2023 00:01:13 +0000 (09:01 +0900)
The original MODE column comes from three letters (rwx) may not be
enough for representing various aspects of file descriptors and memory
mappings. We want to add more items in the future.

However, the description of MODE in lsfd(1) doesn't wrote about its
extensibility. Adding more letters to the column can break
compatibility in someone's use case.

This change introduces XMODE column. Unlike MODE, XMODE is declared as
an extensible column in lsfd(1). Currently, it shows the same items as
the MODE column does.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
misc-utils/lsfd-file.c
misc-utils/lsfd.1.adoc
misc-utils/lsfd.c
misc-utils/lsfd.h
tests/expected/lsfd/column-xmode-MODE-r-bit [new file with mode: 0644]
tests/expected/lsfd/column-xmode-MODE-w-bit [new file with mode: 0644]
tests/expected/lsfd/column-xmode-MODE-x-bit [new file with mode: 0644]
tests/expected/lsfd/column-xmode-XMODE-r-bit [new file with mode: 0644]
tests/expected/lsfd/column-xmode-XMODE-w-bit [new file with mode: 0644]
tests/expected/lsfd/column-xmode-XMODE-x-bit [new file with mode: 0644]
tests/ts/lsfd/column-xmode [new file with mode: 0755]

index d9f8acf308622aa8bf31e61c2929855477a9b8ca..0a4af458c0fd50dba52e1597a2db5748ee2a7b17 100644 (file)
@@ -268,6 +268,18 @@ static bool file_fill_column(struct proc *proc,
                else
                        xasprintf(&str, "---");
                break;
+       case COL_XMODE: {
+               char r, w, x;
+               if (does_file_has_fdinfo_alike(file)) {
+                       r = file->mode & S_IRUSR? 'r': '-';
+                       w = file->mode & S_IWUSR? 'w': '-';
+                       x = (is_mapped_file(file)
+                            && file->mode & S_IXUSR)? 'x': '-';
+               } else
+                       r = w = x = '-';
+               xasprintf(&str, "%c%c%c", r, w, x);
+               break;
+       }
        case COL_POS:
                xasprintf(&str, "%" PRIu64,
                          (does_file_has_fdinfo_alike(file))? file->pos: 0);
index c26d2a7da71b1056cec2a25bd8134a31da876585..a72eae5626cfbaeec115ff8c045bd0bac0591cc9 100644 (file)
@@ -464,6 +464,13 @@ Filesystem pathname for UNIX domain socket.
 USER <``string``>::
 User of the process.
 
+XMODE <``string``>::
+Extended version of _MODE_.
+Currently this column shows the same items as _MODE_.
+However, the column may grow; new letters may be added to
+_XMODE_ when *lsfd* supports a new state of file descriptors
+and/or memory mappings.
+
 == FILTER EXPRESSION
 
 *lsfd* evaluates the expression passed to *--filter* option every time
index 15280407c5661ffaf169411763301214b5773225..2a88c5ec6d6761cc0049e6923b29bf7494af43ad 100644 (file)
@@ -348,6 +348,9 @@ static const struct colinfo infos[] = {
        [COL_USER]             = { "USER",
                                   0,   SCOLS_FL_RIGHT, SCOLS_JSON_STRING,
                                   N_("user of the process") },
+       [COL_XMODE]            = { "XMODE",
+                                  0,   SCOLS_FL_RIGHT, SCOLS_JSON_STRING,
+                                  N_("access mode and more (rwx)") },
 };
 
 static const int default_columns[] = {
@@ -355,7 +358,7 @@ static const int default_columns[] = {
        COL_PID,
        COL_USER,
        COL_ASSOC,
-       COL_MODE,
+       COL_XMODE,
        COL_TYPE,
        COL_SOURCE,
        COL_MNT_ID,
@@ -369,7 +372,7 @@ static const int default_threads_columns[] = {
        COL_TID,
        COL_USER,
        COL_ASSOC,
-       COL_MODE,
+       COL_XMODE,
        COL_TYPE,
        COL_SOURCE,
        COL_MNT_ID,
index 1b86b625b3c3b48a25d84d47eca7cdb9e3d2d30a..4f2c2ecf0722ef83756e105927caa0ad6939ee18 100644 (file)
@@ -113,6 +113,7 @@ enum {
        COL_UID,                /* process */
        COL_UNIX_PATH,
        COL_USER,               /* process */
+       COL_XMODE,
        LSFD_N_COLS             /* This must be at last. */
 };
 
diff --git a/tests/expected/lsfd/column-xmode-MODE-r-bit b/tests/expected/lsfd/column-xmode-MODE-r-bit
new file mode 100644 (file)
index 0000000..7f5a23d
--- /dev/null
@@ -0,0 +1,2 @@
+ r--
+MODE(r-bit):  0
diff --git a/tests/expected/lsfd/column-xmode-MODE-w-bit b/tests/expected/lsfd/column-xmode-MODE-w-bit
new file mode 100644 (file)
index 0000000..13b77f6
--- /dev/null
@@ -0,0 +1,2 @@
+ -w-
+MODE(w-bit):  0
diff --git a/tests/expected/lsfd/column-xmode-MODE-x-bit b/tests/expected/lsfd/column-xmode-MODE-x-bit
new file mode 100644 (file)
index 0000000..e5474b0
--- /dev/null
@@ -0,0 +1,2 @@
+ r-x
+MODE(x-bit):  0
diff --git a/tests/expected/lsfd/column-xmode-XMODE-r-bit b/tests/expected/lsfd/column-xmode-XMODE-r-bit
new file mode 100644 (file)
index 0000000..b0e191e
--- /dev/null
@@ -0,0 +1,2 @@
+  r--
+XMODE(r-bit):  0
diff --git a/tests/expected/lsfd/column-xmode-XMODE-w-bit b/tests/expected/lsfd/column-xmode-XMODE-w-bit
new file mode 100644 (file)
index 0000000..4318488
--- /dev/null
@@ -0,0 +1,2 @@
+  -w-
+XMODE(w-bit):  0
diff --git a/tests/expected/lsfd/column-xmode-XMODE-x-bit b/tests/expected/lsfd/column-xmode-XMODE-x-bit
new file mode 100644 (file)
index 0000000..1e97515
--- /dev/null
@@ -0,0 +1,2 @@
+  r-x
+XMODE(x-bit):  0
diff --git a/tests/ts/lsfd/column-xmode b/tests/ts/lsfd/column-xmode
new file mode 100755 (executable)
index 0000000..8e0bc67
--- /dev/null
@@ -0,0 +1,118 @@
+#!/bin/bash
+#
+# Copyright (C) 2022 Masatake YAMATO <yamato@redhat.com>
+#
+# This file is part of util-linux.
+#
+# This file 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 file is distributed in the hope that it will 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.
+#
+TS_TOPDIR="${0%/*}/../.."
+TS_DESC="MODE and XMODE columns"
+
+. "$TS_TOPDIR"/functions.sh
+ts_init "$*"
+
+ts_check_test_command "$TS_CMD_LSFD"
+ts_check_test_command "$TS_HELPER_MKFDS"
+
+ts_check_prog "stat"
+
+ts_cd "$TS_OUTDIR"
+
+INO=$(stat -c '%i' "$TS_HELPER_MKFDS")
+PID=
+FD=3
+
+
+EXPR="(FD == 3)"
+ts_init_subtest "MODE-r-bit"
+{
+    coproc MKFDS { "$TS_HELPER_MKFDS" ro-regular-file $FD; }
+    if read -r -u "${MKFDS[0]}" PID; then
+       "${TS_CMD_LSFD}" -n -o MODE -p "${PID}" -Q "${EXPR}"
+       echo "MODE(r-bit): " $?
+       kill -CONT "${PID}"
+    fi
+} > "$TS_OUTPUT" 2>&1
+wait "${MKFDS_PID}"
+ts_finalize_subtest
+
+ts_init_subtest "XMODE-r-bit"
+{
+    coproc MKFDS { "$TS_HELPER_MKFDS" ro-regular-file $FD; }
+    if read -r -u "${MKFDS[0]}" PID; then
+       "${TS_CMD_LSFD}" -n -o XMODE -p "${PID}" -Q "${EXPR}"
+       echo "XMODE(r-bit): " $?
+       kill -CONT "${PID}"
+    fi
+} > "$TS_OUTPUT" 2>&1
+wait "${MKFDS_PID}"
+ts_finalize_subtest
+
+EXPR="(FD == $((FD + 1)))"
+ts_init_subtest "MODE-w-bit"
+{
+    coproc MKFDS { "$TS_HELPER_MKFDS" pipe-no-fork $FD $((FD + 1)); }
+    if read -r -u "${MKFDS[0]}" PID; then
+       "${TS_CMD_LSFD}" -n -o MODE -p "${PID}" -Q "${EXPR}"
+       echo "MODE(w-bit): " $?
+       kill -CONT "${PID}"
+    fi
+} > "$TS_OUTPUT" 2>&1
+wait "${MKFDS_PID}"
+ts_finalize_subtest
+
+ts_init_subtest "XMODE-w-bit"
+{
+    coproc MKFDS { "$TS_HELPER_MKFDS" pipe-no-fork $FD $((FD + 1)); }
+    if read -r -u "${MKFDS[0]}" PID; then
+       "${TS_CMD_LSFD}" -n -o XMODE -p "${PID}" -Q "${EXPR}"
+       echo "XMODE(w-bit): " $?
+       kill -CONT "${PID}"
+    fi
+} > "$TS_OUTPUT" 2>&1
+wait "${MKFDS_PID}"
+ts_finalize_subtest
+
+EXPR='(ASSOC == "mem") and (INODE == '"$INO"') and (MODE != "r--") and (MODE != "rw-")'
+ts_init_subtest "MODE-x-bit"
+if [ "$QEMU_USER" == "1" ]; then
+    ts_skip_subtest "running under qemu-user emulation"
+else
+    {
+       coproc MKFDS { "$TS_HELPER_MKFDS" ro-regular-file $FD; }
+       if read -r -u "${MKFDS[0]}" PID; then
+           "${TS_CMD_LSFD}" -n -o MODE -p "${PID}" -Q "${EXPR}"
+           echo "MODE(x-bit): " $?
+           kill -CONT "${PID}"
+       fi
+    } > "$TS_OUTPUT" 2>&1
+    wait "${MKFDS_PID}"
+    ts_finalize_subtest
+fi
+
+ts_init_subtest "XMODE-x-bit"
+if [ "$QEMU_USER" == "1" ]; then
+    ts_skip_subtest "running under qemu-user emulation"
+else
+    {
+       coproc MKFDS { "$TS_HELPER_MKFDS" ro-regular-file $FD; }
+       if read -r -u "${MKFDS[0]}" PID; then
+           "${TS_CMD_LSFD}" -n -o XMODE -p "${PID}" -Q "${EXPR}"
+           echo "XMODE(x-bit): " $?
+           kill -CONT "${PID}"
+       fi
+    } > "$TS_OUTPUT" 2>&1
+    wait "${MKFDS_PID}"
+    ts_finalize_subtest
+fi
+
+ts_finalize