Skip to content

Commit bde3fbf

Browse files
xuyang0410wangli5665
authored andcommitted
syscalls/pipe2: Add new test for pipe2 with/without O_NONBLOCK mode
Signed-off-by: Francis Laniel <[email protected]> Reviewed-by: Yang Xu <[email protected]> Signed-off-by: Li Wang <[email protected]>
1 parent a2e1c2a commit bde3fbf

File tree

3 files changed

+107
-0
lines changed

3 files changed

+107
-0
lines changed

runtest/syscalls

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,7 @@ pipe13 pipe13
913913

914914
pipe2_01 pipe2_01
915915
pipe2_02 pipe2_02
916+
pipe2_04 pipe2_04
916917

917918
pivot_root01 pivot_root01
918919

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
/pipe2_01
22
/pipe2_02
3+
/pipe2_04
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
/*
3+
* Copyright (c) 2020 Francis Laniel. All rights reserved.
4+
* Author: Francis Laniel <[email protected]>
5+
*
6+
* Test Description:
7+
* This Program tests getting and setting the pipe size.
8+
* It also tests what happen when you write to a full pipe depending on whether
9+
* O_NONBLOCK is set or not.
10+
*/
11+
#define _GNU_SOURCE
12+
#include <stdlib.h>
13+
#include <features.h>
14+
#include <fcntl.h>
15+
#include <unistd.h>
16+
#include <stdio.h>
17+
#include "lapi/fcntl.h"
18+
#include "tst_test.h"
19+
20+
static int fds[2];
21+
static int flags;
22+
23+
static void test_pipe2(void)
24+
{
25+
int ret;
26+
pid_t pid;
27+
28+
/*
29+
* This ensures parent process is still in non-block mode when
30+
* using -i parameter. Subquent writes hould return -1 and errno
31+
* set to either EAGAIN or EWOULDBLOCK because pipe is already full.
32+
*/
33+
SAFE_FCNTL(fds[1], F_SETFL, flags | O_NONBLOCK);
34+
ret = write(fds[1], "x", 1);
35+
if (ret == -1) {
36+
if (errno == EAGAIN)
37+
tst_res(TPASS | TERRNO, "write failed as expected");
38+
else
39+
tst_brk(TFAIL | TERRNO, "write failed expected EAGAIN but got");
40+
} else {
41+
tst_res(TFAIL, "write() succeeded unexpectedly");
42+
}
43+
44+
pid = SAFE_FORK();
45+
if (!pid) {
46+
SAFE_FCNTL(fds[1], F_SETFL, flags & ~O_NONBLOCK);
47+
SAFE_WRITE(1, fds[1], "x", 1);
48+
}
49+
50+
if (TST_PROCESS_STATE_WAIT(pid, 'S', 1000) < 0)
51+
tst_res(TFAIL, "Child process is not blocked");
52+
else
53+
tst_res(TPASS, "Child process is blocked");
54+
55+
SAFE_KILL(pid, SIGKILL);
56+
SAFE_WAIT(NULL);
57+
}
58+
59+
static void setup(void)
60+
{
61+
int page_size, pipe_size;
62+
char *write_buffer;
63+
64+
SAFE_PIPE2(fds, O_NONBLOCK);
65+
page_size = SAFE_SYSCONF(_SC_PAGESIZE);
66+
67+
flags = SAFE_FCNTL(fds[1], F_GETFL);
68+
if (!(flags & O_NONBLOCK))
69+
tst_brk(TCONF, "O_NONBLOCK flag must be set");
70+
/*
71+
* A pipe has two file descriptors.
72+
* But in the kernel these two file descriptors point to the same pipe.
73+
* So setting size from first file handle set size for the pipe.
74+
*/
75+
SAFE_FCNTL(fds[0], F_SETPIPE_SZ, 0);
76+
77+
/*
78+
* So getting size from the second file descriptor return the size of
79+
* the pipe which was changed before with first file descriptor.
80+
*/
81+
pipe_size = SAFE_FCNTL(fds[1], F_GETPIPE_SZ);
82+
if (pipe_size != page_size)
83+
tst_res(TFAIL, "Pipe size (%d) must be page size (%d)",
84+
pipe_size, page_size);
85+
86+
write_buffer = SAFE_MALLOC(pipe_size);
87+
memset(write_buffer, 'x', pipe_size);
88+
SAFE_WRITE(1, fds[1], write_buffer, pipe_size);
89+
free(write_buffer);
90+
}
91+
92+
static void cleanup(void)
93+
{
94+
if (fds[0] > 0)
95+
SAFE_CLOSE(fds[0]);
96+
if (fds[1] > 0)
97+
SAFE_CLOSE(fds[1]);
98+
}
99+
100+
static struct tst_test test = {
101+
.test_all = test_pipe2,
102+
.setup = setup,
103+
.cleanup = cleanup,
104+
.forks_child = 1,
105+
};

0 commit comments

Comments
 (0)