[LTP] [PATCH v3 6/7] syscalls/pidfd_getfd01: Add basic functional test
Yang Xu
xuyang2018.jy@fujitsu.com
Tue Feb 22 09:45:13 CET 2022
The pidfd_getfd() system call allocates a new file descriptor in the calling
process. This new file descriptor is a duplicate of an existing file descriptor,
targetfd, in the process referred to by the PID file descriptor pidfd.
pidfd_getfd was introduced since kernel 5.6 and pidfd_open was introduced since
kernel 5.3. pidfd_getfd is not similar to pidfd_send_signal because it didn't
support fd from /proc/pid directory. So we must check kernel whether support
pidfd_open because some linux distribution backports pidfd_getfd but not
backport pidfd_open.
Here we check whether the newfd set close-on-exce flag and use kcmp to check
the two fds whether point to the same open file instead of using fstat to check.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Yang Xu <xuyang2018.jy@fujitsu.com>
---
runtest/syscalls | 2 +
.../kernel/syscalls/pidfd_getfd/.gitignore | 1 +
.../kernel/syscalls/pidfd_getfd/Makefile | 6 ++
.../syscalls/pidfd_getfd/pidfd_getfd01.c | 101 ++++++++++++++++++
4 files changed, 110 insertions(+)
create mode 100644 testcases/kernel/syscalls/pidfd_getfd/.gitignore
create mode 100644 testcases/kernel/syscalls/pidfd_getfd/Makefile
create mode 100644 testcases/kernel/syscalls/pidfd_getfd/pidfd_getfd01.c
diff --git a/runtest/syscalls b/runtest/syscalls
index bc2e5f46a..126c33fc1 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -951,6 +951,8 @@ pause03 pause03
personality01 personality01
personality02 personality02
+pidfd_getfd01 pidfd_getfd01
+
pidfd_open01 pidfd_open01
pidfd_open02 pidfd_open02
pidfd_open03 pidfd_open03
diff --git a/testcases/kernel/syscalls/pidfd_getfd/.gitignore b/testcases/kernel/syscalls/pidfd_getfd/.gitignore
new file mode 100644
index 000000000..9328942ac
--- /dev/null
+++ b/testcases/kernel/syscalls/pidfd_getfd/.gitignore
@@ -0,0 +1 @@
+/pidfd_getfd01
diff --git a/testcases/kernel/syscalls/pidfd_getfd/Makefile b/testcases/kernel/syscalls/pidfd_getfd/Makefile
new file mode 100644
index 000000000..5ea7d67db
--- /dev/null
+++ b/testcases/kernel/syscalls/pidfd_getfd/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+top_srcdir ?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/pidfd_getfd/pidfd_getfd01.c b/testcases/kernel/syscalls/pidfd_getfd/pidfd_getfd01.c
new file mode 100644
index 000000000..8b5c6ea0d
--- /dev/null
+++ b/testcases/kernel/syscalls/pidfd_getfd/pidfd_getfd01.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2022 FUJITSU LIMITED. All rights reserved.
+ * Author: Yang Xu <xuyang2018.jy@fujitsu.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Basic pidfd_getfd() test:
+ *
+ * - the close-on-exec flag is set on the file descriptor returned by
+ * pidfd_getfd
+ * - use kcmp to check whether a file descriptor idx1 in the process pid1
+ * refers to the same open file description as file descriptor idx2 in
+ * the process pid2
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "tst_test.h"
+#include "lapi/kcmp.h"
+#include "tst_safe_macros.h"
+#include "tst_safe_pidfd.h"
+
+#define TESTFILE "testfile"
+
+static int fds[2] = {-1, -1};
+static int pidfd = -1;
+
+static void do_child(void)
+{
+ int fd;
+
+ SAFE_CLOSE(fds[0]);
+ fd = SAFE_CREAT(TESTFILE, 0644);
+ SAFE_WRITE(1, fds[1], &fd, sizeof(fd));
+ TST_CHECKPOINT_WAIT(0);
+ SAFE_CLOSE(fd);
+ SAFE_CLOSE(fds[1]);
+ exit(0);
+}
+
+static void run(void)
+{
+ int flag, pid, targetfd, remotefd;
+
+ SAFE_PIPE(fds);
+ pid = SAFE_FORK();
+ if (!pid)
+ do_child();
+
+ SAFE_CLOSE(fds[1]);
+ TST_PROCESS_STATE_WAIT(pid, 'S', 0);
+
+ pidfd = SAFE_PIDFD_OPEN(pid, 0);
+ SAFE_READ(1, fds[0], &targetfd, sizeof(targetfd));
+ TST_EXP_FD_SILENT(pidfd_getfd(pidfd, targetfd, 0),
+ "pidfd_getfd(%d, %d , 0)", pidfd, targetfd);
+
+ remotefd = TST_RET;
+ flag = SAFE_FCNTL(remotefd, F_GETFD);
+ if (!(flag & FD_CLOEXEC))
+ tst_res(TFAIL, "pidfd_getfd() didn't set close-on-exec flag");
+
+ TST_EXP_VAL_SILENT(kcmp(getpid(), pid, KCMP_FILE, remotefd, targetfd), 0);
+
+ tst_res(TPASS, "pidfd_getfd(%d, %d, 0) passed", pidfd, targetfd);
+
+ TST_CHECKPOINT_WAKE(0);
+ SAFE_CLOSE(remotefd);
+ SAFE_CLOSE(pidfd);
+ SAFE_CLOSE(fds[0]);
+ tst_reap_children();
+}
+
+static void setup(void)
+{
+ pidfd_open_supported();
+ pidfd_getfd_supported();
+}
+
+static void cleanup(void)
+{
+ if (fds[0] > -1)
+ SAFE_CLOSE(fds[0]);
+ if (fds[1] > -1)
+ SAFE_CLOSE(fds[1]);
+ if (pidfd > -1)
+ SAFE_CLOSE(pidfd);
+}
+
+static struct tst_test test = {
+ .needs_root = 1,
+ .needs_checkpoints = 1,
+ .forks_child = 1,
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run,
+};
--
2.31.1
More information about the ltp
mailing list