From: Masatake YAMATO Date: Thu, 6 May 2021 18:57:45 +0000 (+0900) Subject: lsfd: add PROTONAME column X-Git-Tag: v2.38-rc1~144^2~144 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2dfe2e4d1bb32f990fec987ddfc57e5f89d36971;p=thirdparty%2Futil-linux.git lsfd: add PROTONAME column Signed-off-by: Masatake YAMATO --- diff --git a/misc-utils/lsfd-sock.c b/misc-utils/lsfd-sock.c index 937db04d81..ebc6625e81 100644 --- a/misc-utils/lsfd-sock.c +++ b/misc-utils/lsfd-sock.c @@ -19,38 +19,79 @@ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include +#include + #include "xalloc.h" #include "nls.h" #include "libsmartcols.h" #include "lsfd.h" +struct sock { + struct file file; + char *protoname; +}; + static bool sock_fill_column(struct proc *proc __attribute__((__unused__)), - struct file *file __attribute__((__unused__)), + struct file *file, struct libscols_line *ln, int column_id, size_t column_index) { + struct sock *sock = (struct sock *)file; switch(column_id) { case COL_TYPE: if (scols_line_set_data(ln, column_index, "SOCK")) err(EXIT_FAILURE, _("failed to add output data")); return true; + case COL_PROTONAME: + if (sock->protoname) + if (scols_line_set_data(ln, column_index, sock->protoname)) + err(EXIT_FAILURE, _("failed to add output data")); + return true; default: return false; } } struct file *make_sock(const struct file_class *class, - struct stat *sb, const char *name, int fd) + struct stat *sb, const char *name, int fd, + struct proc *proc) +{ + struct file *file = make_file(class? class: &sock_class, + sb, name, fd); + if (fd >= 0) { + struct sock *sock = (struct sock *)file; + + char path[PATH_MAX]; + char buf[256]; + ssize_t len; + memset(path, 0, sizeof(path)); + + sprintf(path, "/proc/%d/fd/%d", proc->pid, fd); + len = getxattr(path, "system.sockprotoname", buf, sizeof(buf) - 1); + if (len > 0) { + buf[len] = '\0'; + sock->protoname = xstrdup(buf); + } + } + + return file; +} + +static void free_sock_content(struct file *file) { - return make_file(class? class: &sock_class, - sb, name, fd); + struct sock *sock = (struct sock *)file; + if (sock->protoname) { + free(sock->protoname); + sock->protoname = NULL; + } } const struct file_class sock_class = { .super = &file_class, - .size = sizeof(struct file), + .size = sizeof(struct sock), .fill_column = sock_fill_column, - .free_content = NULL, + .free_content = free_sock_content, }; diff --git a/misc-utils/lsfd.c b/misc-utils/lsfd.c index 539f77116c..17a426f9d5 100644 --- a/misc-utils/lsfd.c +++ b/misc-utils/lsfd.c @@ -117,6 +117,8 @@ static struct colinfo infos[] = { N_("PID of the process opening the file") }, [COL_POS] = { "POS", 5, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER, N_("file position") }, + [COL_PROTONAME]={ "PROTONAME",0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, + N_("protocol name") }, [COL_RDEV] = { "RDEV", 0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, N_("device ID (if special file)") }, [COL_SIZE] = { "SIZE", 4, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER, @@ -330,7 +332,7 @@ static void collect(struct list_head *procs, struct lsfd_control *ctl) run_collectors(procs); } -static struct file *collect_file(struct proc *proc __attribute__((__unused__)), +static struct file *collect_file(struct proc *proc, struct stat *sb, char *name, int assoc) { switch (sb->st_mode & S_IFMT) { @@ -339,7 +341,7 @@ static struct file *collect_file(struct proc *proc __attribute__((__unused__)), case S_IFBLK: return make_bdev(NULL, sb, name, assoc); case S_IFSOCK: - return make_sock(NULL, sb, name, assoc); + return make_sock(NULL, sb, name, assoc, proc); case S_IFLNK: case S_IFREG: case S_IFIFO: diff --git a/misc-utils/lsfd.h b/misc-utils/lsfd.h index 02929be349..7862973adb 100644 --- a/misc-utils/lsfd.h +++ b/misc-utils/lsfd.h @@ -65,6 +65,7 @@ enum { COL_NLINK, COL_PID, COL_POS, + COL_PROTONAME, COL_RDEV, COL_SIZE, COL_TID, @@ -142,7 +143,8 @@ struct file *make_cdev(const struct file_class *class, struct file *make_bdev(const struct file_class *class, struct stat *sb, const char *name, int fd); struct file *make_sock(const struct file_class *class, - struct stat *sb, const char *name, int fd); + struct stat *sb, const char *name, int fd, + struct proc *proc); struct file *make_unkn(const struct file_class *class, struct stat *sb, const char *name, int fd);