|
Packit Service |
63ea89 |
/* SPDX-License-Identifier: MIT */
|
|
Packit Service |
63ea89 |
/*
|
|
Packit Service |
63ea89 |
* Description: check that STDOUT write works
|
|
Packit Service |
63ea89 |
*/
|
|
Packit Service |
63ea89 |
#include <errno.h>
|
|
Packit Service |
63ea89 |
#include <stdio.h>
|
|
Packit Service |
63ea89 |
#include <unistd.h>
|
|
Packit Service |
63ea89 |
#include <stdlib.h>
|
|
Packit Service |
63ea89 |
#include <string.h>
|
|
Packit Service |
63ea89 |
#include <fcntl.h>
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
#include "liburing.h"
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
static int test_pipe_io_fixed(struct io_uring *ring)
|
|
Packit Service |
63ea89 |
{
|
|
Packit Service |
63ea89 |
const char str[] = "This is a fixed pipe test\n";
|
|
Packit Service |
63ea89 |
struct io_uring_cqe *cqe;
|
|
Packit Service |
63ea89 |
struct io_uring_sqe *sqe;
|
|
Packit Service |
63ea89 |
struct iovec vecs[2];
|
|
Packit Service |
63ea89 |
char buffer[128];
|
|
Packit Service |
63ea89 |
int i, ret, fds[2];
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
if (posix_memalign(&vecs[0].iov_base, 4096, 4096)) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "Failed to alloc mem\n");
|
|
Packit Service |
63ea89 |
return 1;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
memcpy(vecs[0].iov_base, str, strlen(str));
|
|
Packit Service |
63ea89 |
vecs[0].iov_len = strlen(str);
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
if (pipe(fds) < 0) {
|
|
Packit Service |
63ea89 |
perror("pipe");
|
|
Packit Service |
63ea89 |
return 1;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
ret = io_uring_register_buffers(ring, vecs, 1);
|
|
Packit Service |
63ea89 |
if (ret) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "Failed to register buffers: %d\n", ret);
|
|
Packit Service |
63ea89 |
return 1;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
sqe = io_uring_get_sqe(ring);
|
|
Packit Service |
63ea89 |
if (!sqe) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "get sqe failed\n");
|
|
Packit Service |
63ea89 |
goto err;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
io_uring_prep_write_fixed(sqe, fds[1], vecs[0].iov_base,
|
|
Packit Service |
63ea89 |
vecs[0].iov_len, 0, 0);
|
|
Packit Service |
63ea89 |
sqe->user_data = 1;
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
sqe = io_uring_get_sqe(ring);
|
|
Packit Service |
63ea89 |
if (!sqe) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "get sqe failed\n");
|
|
Packit Service |
63ea89 |
goto err;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
vecs[1].iov_base = buffer;
|
|
Packit Service |
63ea89 |
vecs[1].iov_len = sizeof(buffer);
|
|
Packit Service |
63ea89 |
io_uring_prep_readv(sqe, fds[0], &vecs[1], 1, 0);
|
|
Packit Service |
63ea89 |
sqe->user_data = 2;
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
ret = io_uring_submit(ring);
|
|
Packit Service |
63ea89 |
if (ret < 0) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "sqe submit failed: %d\n", ret);
|
|
Packit Service |
63ea89 |
goto err;
|
|
Packit Service |
63ea89 |
} else if (ret != 2) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "Submitted only %d\n", ret);
|
|
Packit Service |
63ea89 |
goto err;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
for (i = 0; i < 2; i++) {
|
|
Packit Service |
63ea89 |
ret = io_uring_wait_cqe(ring, &cqe);
|
|
Packit Service |
63ea89 |
if (ret < 0) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "wait completion %d\n", ret);
|
|
Packit Service |
63ea89 |
goto err;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
if (cqe->res < 0) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "I/O write error on %lu: %s\n",
|
|
Packit Service |
63ea89 |
(unsigned long) cqe->user_data,
|
|
Packit Service |
63ea89 |
strerror(-cqe->res));
|
|
Packit Service |
63ea89 |
goto err;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
if (cqe->res != strlen(str)) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "Got %d bytes, wanted %d on %lu\n",
|
|
Packit Service |
63ea89 |
cqe->res, (int)strlen(str),
|
|
Packit Service |
63ea89 |
(unsigned long) cqe->user_data);
|
|
Packit Service |
63ea89 |
goto err;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
if (cqe->user_data == 2 && memcmp(str, buffer, strlen(str))) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "read data mismatch\n");
|
|
Packit Service |
63ea89 |
goto err;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
io_uring_cqe_seen(ring, cqe);
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
io_uring_unregister_buffers(ring);
|
|
Packit Service |
63ea89 |
return 0;
|
|
Packit Service |
63ea89 |
err:
|
|
Packit Service |
63ea89 |
return 1;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
static int test_stdout_io_fixed(struct io_uring *ring)
|
|
Packit Service |
63ea89 |
{
|
|
Packit Service |
63ea89 |
const char str[] = "This is a fixed pipe test\n";
|
|
Packit Service |
63ea89 |
struct io_uring_cqe *cqe;
|
|
Packit Service |
63ea89 |
struct io_uring_sqe *sqe;
|
|
Packit Service |
63ea89 |
struct iovec vecs;
|
|
Packit Service |
63ea89 |
int ret;
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
if (posix_memalign(&vecs.iov_base, 4096, 4096)) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "Failed to alloc mem\n");
|
|
Packit Service |
63ea89 |
return 1;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
memcpy(vecs.iov_base, str, strlen(str));
|
|
Packit Service |
63ea89 |
vecs.iov_len = strlen(str);
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
ret = io_uring_register_buffers(ring, &vecs, 1);
|
|
Packit Service |
63ea89 |
if (ret) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "Failed to register buffers: %d\n", ret);
|
|
Packit Service |
63ea89 |
return 1;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
sqe = io_uring_get_sqe(ring);
|
|
Packit Service |
63ea89 |
if (!sqe) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "get sqe failed\n");
|
|
Packit Service |
63ea89 |
goto err;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
io_uring_prep_write_fixed(sqe, STDOUT_FILENO, vecs.iov_base, vecs.iov_len, 0, 0);
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
ret = io_uring_submit(ring);
|
|
Packit Service |
63ea89 |
if (ret < 0) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "sqe submit failed: %d\n", ret);
|
|
Packit Service |
63ea89 |
goto err;
|
|
Packit Service |
63ea89 |
} else if (ret < 1) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "Submitted only %d\n", ret);
|
|
Packit Service |
63ea89 |
goto err;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
ret = io_uring_wait_cqe(ring, &cqe);
|
|
Packit Service |
63ea89 |
if (ret < 0) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "wait completion %d\n", ret);
|
|
Packit Service |
63ea89 |
goto err;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
if (cqe->res < 0) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "STDOUT write error: %s\n", strerror(-cqe->res));
|
|
Packit Service |
63ea89 |
goto err;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
if (cqe->res != vecs.iov_len) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "Got %d write, wanted %d\n", cqe->res, (int)vecs.iov_len);
|
|
Packit Service |
63ea89 |
goto err;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
io_uring_cqe_seen(ring, cqe);
|
|
Packit Service |
63ea89 |
io_uring_unregister_buffers(ring);
|
|
Packit Service |
63ea89 |
return 0;
|
|
Packit Service |
63ea89 |
err:
|
|
Packit Service |
63ea89 |
return 1;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
static int test_stdout_io(struct io_uring *ring)
|
|
Packit Service |
63ea89 |
{
|
|
Packit Service |
63ea89 |
struct io_uring_cqe *cqe;
|
|
Packit Service |
63ea89 |
struct io_uring_sqe *sqe;
|
|
Packit Service |
63ea89 |
struct iovec vecs;
|
|
Packit Service |
63ea89 |
int ret;
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
vecs.iov_base = "This is a pipe test\n";
|
|
Packit Service |
63ea89 |
vecs.iov_len = strlen(vecs.iov_base);
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
sqe = io_uring_get_sqe(ring);
|
|
Packit Service |
63ea89 |
if (!sqe) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "get sqe failed\n");
|
|
Packit Service |
63ea89 |
goto err;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
io_uring_prep_writev(sqe, STDOUT_FILENO, &vecs, 1, 0);
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
ret = io_uring_submit(ring);
|
|
Packit Service |
63ea89 |
if (ret < 0) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "sqe submit failed: %d\n", ret);
|
|
Packit Service |
63ea89 |
goto err;
|
|
Packit Service |
63ea89 |
} else if (ret < 1) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "Submitted only %d\n", ret);
|
|
Packit Service |
63ea89 |
goto err;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
ret = io_uring_wait_cqe(ring, &cqe);
|
|
Packit Service |
63ea89 |
if (ret < 0) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "wait completion %d\n", ret);
|
|
Packit Service |
63ea89 |
goto err;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
if (cqe->res < 0) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "STDOUT write error: %s\n",
|
|
Packit Service |
63ea89 |
strerror(-cqe->res));
|
|
Packit Service |
63ea89 |
goto err;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
if (cqe->res != vecs.iov_len) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "Got %d write, wanted %d\n", cqe->res,
|
|
Packit Service |
63ea89 |
(int)vecs.iov_len);
|
|
Packit Service |
63ea89 |
goto err;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
io_uring_cqe_seen(ring, cqe);
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
return 0;
|
|
Packit Service |
63ea89 |
err:
|
|
Packit Service |
63ea89 |
return 1;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
int main(int argc, char *argv[])
|
|
Packit Service |
63ea89 |
{
|
|
Packit Service |
63ea89 |
struct io_uring ring;
|
|
Packit Service |
63ea89 |
int ret;
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
if (argc > 1)
|
|
Packit Service |
63ea89 |
return 0;
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
ret = io_uring_queue_init(8, &ring, 0);
|
|
Packit Service |
63ea89 |
if (ret) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "ring setup failed\n");
|
|
Packit Service |
63ea89 |
return 1;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
ret = test_stdout_io(&ring);
|
|
Packit Service |
63ea89 |
if (ret) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "test_pipe_io failed\n");
|
|
Packit Service |
63ea89 |
return ret;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
ret = test_stdout_io_fixed(&ring);
|
|
Packit Service |
63ea89 |
if (ret) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "test_pipe_io_fixed failed\n");
|
|
Packit Service |
63ea89 |
return ret;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
ret = test_pipe_io_fixed(&ring);
|
|
Packit Service |
63ea89 |
if (ret) {
|
|
Packit Service |
63ea89 |
fprintf(stderr, "test_pipe_io_fixed failed\n");
|
|
Packit Service |
63ea89 |
return ret;
|
|
Packit Service |
63ea89 |
}
|
|
Packit Service |
63ea89 |
|
|
Packit Service |
63ea89 |
return 0;
|
|
Packit Service |
63ea89 |
}
|