Skip to content

Commit 98c49d0

Browse files
bsach64avagin
authored andcommitted
zdtm: Check fd from pidfd_getfd is C/Red correctly
We get the read end of a pipe using `pidfd_getfd` and check if we can read from it after C/R. signed-off-by: Bhavik Sachdev <[email protected]>
1 parent 643e160 commit 98c49d0

File tree

2 files changed

+109
-0
lines changed

2 files changed

+109
-0
lines changed

test/zdtm/static/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ TST_NOFILE := \
5757
pidfd_dead \
5858
pidfd_child \
5959
pidfd_kill \
60+
fd_from_pidfd \
6061
pipe00 \
6162
pipe01 \
6263
pipe02 \

test/zdtm/static/fd_from_pidfd.c

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#include <sys/syscall.h>
2+
#include <signal.h>
3+
#include <sys/wait.h>
4+
#include <unistd.h>
5+
6+
#include "zdtmtst.h"
7+
8+
const char *test_doc = "Check if fd obtained from pidfd_get_fd is C/R correctly\n";
9+
const char *test_author = "Bhavik Sachdev <[email protected]>";
10+
11+
static int pidfd_open(pid_t pid, unsigned int flags)
12+
{
13+
return syscall(__NR_pidfd_open, pid, flags);
14+
}
15+
16+
static int pidfd_getfd(int pidfd, int targetfd, unsigned int flags)
17+
{
18+
return syscall(__NR_pidfd_getfd, pidfd, targetfd, flags);
19+
}
20+
21+
static int pidfd_send_signal(int pidfd, int sig, siginfo_t* info, unsigned int flags)
22+
{
23+
return syscall(__NR_pidfd_send_signal, pidfd, sig, info, flags);
24+
}
25+
26+
int main(int argc, char* argv[])
27+
{
28+
#define READ 0
29+
#define WRITE 1
30+
31+
int pidfd, child, p[2], child_read, read_data, status;
32+
int data = 42;
33+
34+
test_init(argc, argv);
35+
36+
if (pipe(p)) {
37+
pr_perror("pipe");
38+
return 1;
39+
}
40+
41+
child = fork();
42+
if (child < 0) {
43+
pr_perror("fork");
44+
return 1;
45+
}
46+
47+
if (child == 0) {
48+
close(p[WRITE]);
49+
test_waitsig();
50+
return 0;
51+
}
52+
53+
pidfd = pidfd_open(child, 0);
54+
if (pidfd < 0) {
55+
pr_perror("pidfd_open failed");
56+
return 1;
57+
}
58+
59+
close(p[READ]);
60+
if (write(p[WRITE], &data, sizeof(data)) != sizeof(data)) {
61+
pr_perror("write");
62+
return 1;
63+
}
64+
close(p[WRITE]);
65+
66+
child_read = pidfd_getfd(pidfd, p[READ], 0);
67+
if (child_read < 0) {
68+
pr_perror("pidfd_getfd");
69+
return 1;
70+
}
71+
72+
test_daemon();
73+
test_waitsig();
74+
75+
if (read(child_read, &read_data, sizeof(read_data)) != sizeof(read_data)) {
76+
pr_perror("read");
77+
goto err_close;
78+
}
79+
80+
if (read_data != data) {
81+
fail("data from fd obtained using pidfd_getfd incorrect");
82+
goto err_close;
83+
}
84+
85+
if (pidfd_send_signal(pidfd, SIGTERM, NULL, 0)) {
86+
pr_perror("Could not send signal");
87+
goto err_close;
88+
}
89+
90+
if (waitpid(child, &status, 0) != child) {
91+
pr_perror("waitpid()");
92+
return 1;
93+
}
94+
95+
if (status != 0) {
96+
fail("%d:%d:%d:%d", WIFEXITED(status), WEXITSTATUS(status), WIFSIGNALED(status), WTERMSIG(status));
97+
return 1;
98+
}
99+
100+
pass();
101+
close(child_read);
102+
close(pidfd);
103+
return 0;
104+
err_close:
105+
close(child_read);
106+
close(pidfd);
107+
return 1;
108+
}

0 commit comments

Comments
 (0)