From: Masatake YAMATO Date: Fri, 9 Jun 2023 12:35:55 +0000 (+0900) Subject: lsfd: introduce XMODE column, extensible variant of MODE X-Git-Tag: v2.40-rc1~351^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=92c00d7215bab642dc90f069a50161ee27219a89;p=thirdparty%2Futil-linux.git lsfd: introduce XMODE column, extensible variant of MODE 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 --- diff --git a/misc-utils/lsfd-file.c b/misc-utils/lsfd-file.c index d9f8acf308..0a4af458c0 100644 --- a/misc-utils/lsfd-file.c +++ b/misc-utils/lsfd-file.c @@ -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); diff --git a/misc-utils/lsfd.1.adoc b/misc-utils/lsfd.1.adoc index c26d2a7da7..a72eae5626 100644 --- a/misc-utils/lsfd.1.adoc +++ b/misc-utils/lsfd.1.adoc @@ -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 diff --git a/misc-utils/lsfd.c b/misc-utils/lsfd.c index 15280407c5..2a88c5ec6d 100644 --- a/misc-utils/lsfd.c +++ b/misc-utils/lsfd.c @@ -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, diff --git a/misc-utils/lsfd.h b/misc-utils/lsfd.h index 1b86b625b3..4f2c2ecf07 100644 --- a/misc-utils/lsfd.h +++ b/misc-utils/lsfd.h @@ -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 index 0000000000..7f5a23d621 --- /dev/null +++ b/tests/expected/lsfd/column-xmode-MODE-r-bit @@ -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 index 0000000000..13b77f6c47 --- /dev/null +++ b/tests/expected/lsfd/column-xmode-MODE-w-bit @@ -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 index 0000000000..e5474b0e7d --- /dev/null +++ b/tests/expected/lsfd/column-xmode-MODE-x-bit @@ -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 index 0000000000..b0e191e31f --- /dev/null +++ b/tests/expected/lsfd/column-xmode-XMODE-r-bit @@ -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 index 0000000000..4318488fda --- /dev/null +++ b/tests/expected/lsfd/column-xmode-XMODE-w-bit @@ -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 index 0000000000..1e9751574e --- /dev/null +++ b/tests/expected/lsfd/column-xmode-XMODE-x-bit @@ -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 index 0000000000..8e0bc67a5f --- /dev/null +++ b/tests/ts/lsfd/column-xmode @@ -0,0 +1,118 @@ +#!/bin/bash +# +# Copyright (C) 2022 Masatake YAMATO +# +# 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