File 0002-lsfd-Refactor-the-pidfd-logic-into-lsfd-pidfd.c.patch of Package util-linux

From: Xi Ruoyao <xry111@xry111.site>
Date: Wed, 3 Apr 2024 15:29:34 +0800
Subject: lsfd: Refactor the pidfd logic into lsfd-pidfd.c
Git-repo: https://github.com/util-linux/util-linux.git
Git-commit: bf6645dc1edef09ad378cc5b9eb2c93861408735
Patch-mainline: yes
References: kernel 6.9

We'll reuse these logic for pidfd support on Linux >= 6.9.  This should
be a no-functional change.

Besides moving the code, this change also renames anon_pidfd_data to
pidfd_data, and removes a redundant nullity check for free (because
free(NULL) will just do nothing per the C standard).

Signed-off-by: Xi Ruoyao <xry111@xry111.site>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 misc-utils/Makemodule.am |  4 +-
 misc-utils/lsfd-pidfd.c  | 95 ++++++++++++++++++++++++++++++++++++++++
 misc-utils/lsfd-pidfd.h  | 37 ++++++++++++++++
 misc-utils/lsfd-unkn.c   | 71 +++++-------------------------
 misc-utils/meson.build   |  1 +
 5 files changed, 147 insertions(+), 61 deletions(-)
 create mode 100644 misc-utils/lsfd-pidfd.c
 create mode 100644 misc-utils/lsfd-pidfd.h

diff --git a/misc-utils/Makemodule.am b/misc-utils/Makemodule.am
index 9edf3d98..7622a5d7 100644
--- a/misc-utils/Makemodule.am
+++ b/misc-utils/Makemodule.am
@@ -298,7 +298,9 @@ lsfd_SOURCES = \
 	misc-utils/lsfd-sock.h \
 	misc-utils/lsfd-sock-xinfo.c \
 	misc-utils/lsfd-unkn.c \
-	misc-utils/lsfd-fifo.c
+	misc-utils/lsfd-fifo.c \
+	misc-utils/lsfd-pidfd.h \
+	misc-utils/lsfd-pidfd.c
 lsfd_LDADD = $(LDADD) $(MQ_LIBS) libsmartcols.la libcommon.la
 lsfd_CFLAGS = $(AM_CFLAGS) -I$(ul_libsmartcols_incdir)
 endif
diff --git a/misc-utils/lsfd-pidfd.c b/misc-utils/lsfd-pidfd.c
new file mode 100644
index 00000000..430a8028
--- /dev/null
+++ b/misc-utils/lsfd-pidfd.c
@@ -0,0 +1,95 @@
+/*
+ * lsfd-pidfd.c - handle pidfd (from anon_inode or pidfs)
+ *
+ * Copyright (C) 2024 Xi Ruoyao <xry111@xry111.site>
+ *
+ * Refactored and moved out from lsfd-unkn.c (originally authored by
+ * Masatake YAMATO <yamato@redhat.com>).
+ *
+ * This program 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 program is distributed in the hope that it would 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <string.h>
+
+#include "strutils.h"
+#include "xalloc.h"
+
+#include "lsfd.h"
+#include "lsfd-pidfd.h"
+
+int pidfd_handle_fdinfo(struct pidfd_data *data, const char *key,
+			const char *value)
+{
+	if (strcmp(key, "Pid") == 0) {
+		uint64_t pid;
+		int rc = ul_strtou64(value, &pid, 10);
+
+		if (rc < 0)
+			return 0; /* ignore -- parse failed */
+
+		data->pid = (pid_t)pid;
+		return 1;
+	} else if (strcmp(key, "NSpid") == 0) {
+		data->nspid = xstrdup(value);
+		return 1;
+	}
+
+	return 0;
+}
+
+char *pidfd_get_name(struct pidfd_data *data)
+{
+	char *str = NULL;
+	char *comm = NULL;
+	struct proc *proc = get_proc(data->pid);
+
+	if (proc)
+		comm = proc->command;
+
+	xasprintf(&str, "pid=%d comm=%s nspid=%s",
+			  data->pid,
+			  comm ? comm : "",
+			  data->nspid ? data->nspid : "");
+	return str;
+}
+
+bool pidfd_fill_column(struct pidfd_data *data, int column_id, char **str)
+{
+	switch(column_id) {
+	case COL_PIDFD_COMM: {
+		struct proc *pidfd_proc = get_proc(data->pid);
+		char *pidfd_comm = NULL;
+
+		if (pidfd_proc)
+			pidfd_comm = pidfd_proc->command;
+		if (pidfd_comm) {
+			*str = xstrdup(pidfd_comm);
+			return true;
+		}
+		break;
+	}
+	case COL_PIDFD_NSPID:
+		if (data->nspid) {
+			*str = xstrdup(data->nspid);
+			return true;
+		}
+		break;
+	case COL_PIDFD_PID:
+		xasprintf(str, "%d", (int)data->pid);
+		return true;
+	}
+
+	return false;
+}
diff --git a/misc-utils/lsfd-pidfd.h b/misc-utils/lsfd-pidfd.h
new file mode 100644
index 00000000..2f65d3b3
--- /dev/null
+++ b/misc-utils/lsfd-pidfd.h
@@ -0,0 +1,37 @@
+/*
+ * lsfd-pidfd.h - handle pidfd (from anon_inode or pidfs)
+ *
+ * Copyright (C) 2024 Xi Ruoyao <xry111@xry111.site>
+ *
+ * This program 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 program is distributed in the hope that it would 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdbool.h>
+#include <sys/types.h>
+
+struct pidfd_data {
+	pid_t pid;
+	char *nspid;
+};
+
+int pidfd_handle_fdinfo(struct pidfd_data *, const char *, const char *);
+char *pidfd_get_name(struct pidfd_data *);
+bool pidfd_fill_column(struct pidfd_data *, int, char **);
+
+static inline void __attribute__((nonnull(1)))
+pidfd_free(struct pidfd_data *data)
+{
+	free(data->nspid);
+}
diff --git a/misc-utils/lsfd-unkn.c b/misc-utils/lsfd-unkn.c
index 8f6e9084..8e257f47 100644
--- a/misc-utils/lsfd-unkn.c
+++ b/misc-utils/lsfd-unkn.c
@@ -28,6 +28,7 @@
 #include "timeutils.h"
 
 #include "lsfd.h"
+#include "lsfd-pidfd.h"
 
 #define offsetofend(TYPE, MEMBER)				\
 	(offsetof(TYPE, MEMBER)	+ sizeof_member(TYPE, MEMBER))
@@ -183,10 +184,6 @@ static int unkn_handle_fdinfo(struct file *file, const char *key, const char *va
 /*
  * pidfd
  */
-struct anon_pidfd_data {
-	pid_t pid;
-	char *nspid;
-};
 
 static bool anon_pidfd_probe(const char *str)
 {
@@ -195,51 +192,28 @@ static bool anon_pidfd_probe(const char *str)
 
 static char *anon_pidfd_get_name(struct unkn *unkn)
 {
-	char *str = NULL;
-	struct anon_pidfd_data *data = (struct anon_pidfd_data *)unkn->anon_data;
+	struct pidfd_data *data = (struct pidfd_data *)unkn->anon_data;
 
-	char *comm = NULL;
-	struct proc *proc = get_proc(data->pid);
-	if (proc)
-		comm = proc->command;
-
-	xasprintf(&str, "pid=%d comm=%s nspid=%s",
-		  data->pid,
-		  comm? comm: "",
-		  data->nspid? data->nspid: "");
-	return str;
+	return pidfd_get_name(data);
 }
 
 static void anon_pidfd_init(struct unkn *unkn)
 {
-	unkn->anon_data = xcalloc(1, sizeof(struct anon_pidfd_data));
+	unkn->anon_data = xcalloc(1, sizeof(struct pidfd_data));
 }
 
 static void anon_pidfd_free(struct unkn *unkn)
 {
-	struct anon_pidfd_data *data = (struct anon_pidfd_data *)unkn->anon_data;
+	struct pidfd_data *data = (struct pidfd_data *)unkn->anon_data;
 
-	if (data->nspid)
-		free(data->nspid);
+	pidfd_free(data);
 	free(data);
 }
 
 static int anon_pidfd_handle_fdinfo(struct unkn *unkn, const char *key, const char *value)
 {
-	if (strcmp(key, "Pid") == 0) {
-		uint64_t pid;
-
-		int rc = ul_strtou64(value, &pid, 10);
-		if (rc < 0)
-			return 0; /* ignore -- parse failed */
-		((struct anon_pidfd_data *)unkn->anon_data)->pid = (pid_t)pid;
-		return 1;
-	} else if (strcmp(key, "NSpid") == 0) {
-		((struct anon_pidfd_data *)unkn->anon_data)->nspid = xstrdup(value);
-		return 1;
-
-	}
-	return 0;
+	return pidfd_handle_fdinfo((struct pidfd_data *)unkn->anon_data,
+				   key, value);
 }
 
 static bool anon_pidfd_fill_column(struct proc *proc  __attribute__((__unused__)),
@@ -249,32 +223,9 @@ static bool anon_pidfd_fill_column(struct proc *proc  __attribute__((__unused__)
 				   size_t column_index __attribute__((__unused__)),
 				   char **str)
 {
-	struct anon_pidfd_data *data = (struct anon_pidfd_data *)unkn->anon_data;
-
-	switch(column_id) {
-	case COL_PIDFD_COMM: {
-		struct proc *pidfd_proc = get_proc(data->pid);
-		char *pidfd_comm = NULL;
-		if (pidfd_proc)
-			pidfd_comm = pidfd_proc->command;
-		if (pidfd_comm) {
-			*str = xstrdup(pidfd_comm);
-			return true;
-		}
-		break;
-	}
-	case COL_PIDFD_NSPID:
-		if (data->nspid) {
-			*str = xstrdup(data->nspid);
-			return true;
-		}
-		break;
-	case COL_PIDFD_PID:
-		xasprintf(str, "%d", (int)data->pid);
-		return true;
-	}
-
-	return false;
+	return pidfd_fill_column((struct pidfd_data *)unkn->anon_data,
+				 column_id,
+				 str);
 }
 
 static const struct anon_ops anon_pidfd_ops = {
diff --git a/misc-utils/meson.build b/misc-utils/meson.build
index 847b1012..68ea9777 100644
--- a/misc-utils/meson.build
+++ b/misc-utils/meson.build
@@ -56,6 +56,7 @@ lsfd_sources = files (
   'lsfd-sock-xinfo.c',
   'lsfd-unkn.c',
   'lsfd-fifo.c',
+  'lsfd-pidfd.c',
 )
 
 uuidgen_sources = files(
-- 
2.45.0

openSUSE Build Service is sponsored by