android13/external/ltp/testcases/kernel/syscalls/vmsplice/vmsplice04.c

94 lines
2.0 KiB
C

// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2019 SUSE LLC
* Author: Jorik Cronenberg <jcronenberg@suse.de>
*
* Test vmsplice() to a full pipe with SPLICE_F_NONBLOCK and without.
*
* With SPLICE_F_NONBLOCK vmsplice() should return with errno EAGAIN
* Without SPLICE_F_NONBLOCK it should block.
*/
#define _GNU_SOURCE
#include "tst_test.h"
#include "lapi/vmsplice.h"
#include "lapi/fcntl.h"
#include <stdlib.h>
static int pipes[2];
static ssize_t pipe_max_size;
static char *write_buffer;
static struct iovec iov;
static void vmsplice_test(void)
{
int status;
int pid;
TEST(vmsplice(pipes[1], &iov, 1, SPLICE_F_NONBLOCK));
if (TST_RET < 0 && TST_ERR == EAGAIN) {
tst_res(TPASS | TTERRNO,
"vmsplice(..., SPLICE_F_NONBLOCK) failed as expected");
} else if (TST_RET < 0) {
tst_res(TFAIL | TTERRNO,
"vmsplice(..., SPLICE_F_NONBLOCK) shall fail with EAGAIN");
} else {
tst_res(TFAIL,
"vmsplice(..., SPLICE_F_NONBLOCK) wrote to a full pipe");
}
pid = SAFE_FORK();
if (!pid) {
TEST(vmsplice(pipes[1], &iov, 1, 0));
if (TST_RET < 0)
tst_res(TFAIL | TTERRNO, "vmsplice(..., 0) failed");
else
tst_res(TFAIL,
"vmsplice(..., 0) wrote to a full pipe");
exit(0);
}
if (TST_PROCESS_STATE_WAIT(pid, 'S', 1000) < 0)
return;
else
tst_res(TPASS, "vmsplice(..., 0) blocked");
SAFE_KILL(pid, SIGKILL);
SAFE_WAIT(&status);
}
static void cleanup(void)
{
if (pipes[1] > 0)
SAFE_CLOSE(pipes[1]);
if (pipes[0] > 0)
SAFE_CLOSE(pipes[0]);
}
static void setup(void)
{
SAFE_PIPE(pipes);
pipe_max_size = SAFE_FCNTL(pipes[1], F_GETPIPE_SZ);
write_buffer = tst_alloc(pipe_max_size);
iov.iov_base = write_buffer;
iov.iov_len = pipe_max_size;
TEST(vmsplice(pipes[1], &iov, 1, 0));
if (TST_RET < 0) {
tst_brk(TBROK | TTERRNO,
"Initial vmsplice() to fill pipe failed");
}
}
static struct tst_test test = {
.setup = setup,
.cleanup = cleanup,
.test_all = vmsplice_test,
.min_kver = "2.6.17",
.forks_child = 1,
};