/* This is a simple "cat" example that uses io_uring in IORING_SETUP_IOPOLL mode. It demonstrates the bare minimum needed to use io_uring in polling mode. It uses liburing for simplicity. */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include #include struct io_uring ring; __attribute__((aligned(1024))) char data[1024]; int main(int argc, char * argv[]) { if(argc != 2) { printf("usage: %s FILE - prints file to console.\n", argv[0]); return 1; } int fd = open(argv[1], O_DIRECT); if(fd < 0) { printf("Could not open file %s.\n", argv[1]); return 2; } /* prep the array */ struct iovec iov = { data, 1024 }; /* init liburing */ io_uring_queue_init(256, &ring, IORING_SETUP_IOPOLL); /* declare required structs */ struct io_uring_sqe * sqe; struct io_uring_cqe * cqe; /* get an sqe and fill in a READV operation */ sqe = io_uring_get_sqe(&ring); io_uring_prep_readv(sqe, fd, &iov, 1, 0); // io_uring_prep_read(sqe, fd, data, 1024, 0); sqe->user_data = (uint64_t)(uintptr_t)data; /* tell the kernel we have an sqe ready for consumption */ io_uring_submit(&ring); /* wait for the sqe to complete */ int ret = io_uring_wait_cqe(&ring, &cqe); /* read and process cqe event */ if(ret == 0) { char * out = (char *)(uintptr_t)cqe->user_data; signed int len = cqe->res; io_uring_cqe_seen(&ring, cqe); if(len > 0) { printf("%.*s", len, out); } else if( len < 0 ) { fprintf(stderr, "readv/read returned error : %s\n", strerror(-len)); } } else { printf("%d\n", ret); io_uring_cqe_seen(&ring, cqe); } io_uring_queue_exit(&ring); close(fd); }