]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsfd: add PROTONAME column
authorMasatake YAMATO <yamato@redhat.com>
Thu, 6 May 2021 18:57:45 +0000 (03:57 +0900)
committerKarel Zak <kzak@redhat.com>
Wed, 6 Oct 2021 09:01:53 +0000 (11:01 +0200)
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
misc-utils/lsfd-sock.c
misc-utils/lsfd.c
misc-utils/lsfd.h

index 937db04d81737991acccf01afffa542b568dff91..ebc6625e810ccf406265a71cfba9453e0b3ad84a 100644 (file)
  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <sys/types.h>
+#include <sys/xattr.h>
+
 #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,
 };
index 539f77116cc4848a1e5eb5f3cc2636b8a2982802..17a426f9d52ec68d3a356b98cf8610462902e537 100644 (file)
@@ -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:
index 02929be3497950a22a1bfd029ae40c53ba6632b0..7862973adb9288de3fc13f0b0515e66e5d2d5ab1 100644 (file)
@@ -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);