1 module during.tests.msg;
2 
3 import during;
4 import during.tests.base;
5 
6 import core.stdc.stdlib;
7 import core.sys.linux.errno;
8 import core.sys.posix.sys.socket;
9 import core.sys.posix.sys.uio : iovec;
10 import core.sys.posix.unistd;
11 
12 import std.algorithm : copy, equal, map;
13 import std.range;
14 
15 @("send/recv")
16 unittest
17 {
18     if (!checkKernelVersion(5, 3)) return;
19 
20     int[2] fd;
21     int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
22     assert(ret == 0, "socketpair()");
23 
24     Uring io;
25     auto res = io.setup();
26     assert(res >= 0, "Error initializing IO");
27 
28     // 0 - read, 1 - write
29     iovec[2] v;
30     msghdr[2] msg;
31 
32     foreach (i; 0..2)
33     {
34         v[i].iov_base = malloc(256);
35         v[i].iov_len = 256;
36 
37         msg[i].msg_iov = &v[i];
38         msg[i].msg_iovlen = 1;
39     }
40     scope (exit) foreach (i; 0..2) free(v[i].iov_base);
41 
42     iota(0, 256)
43         .map!(a => cast(ubyte)a)
44         .copy((cast(ubyte*)v[1].iov_base)[0..256]);
45 
46     // add recvmsg
47     io.putWith!(
48         (ref SubmissionEntry e, int fd, ref msghdr m)
49         {
50             e.prepRecvMsg(fd, m);
51             e.user_data = 0;
52         })(fd[0], msg[0]);
53 
54     // add sendmsg
55     io.putWith!(
56         (ref SubmissionEntry e, int fd, ref msghdr m)
57         {
58             e.prepSendMsg(fd, m);
59             e.user_data = 1;
60         })(fd[1], msg[1]);
61 
62     ret = io.submit(2);
63     assert(ret == 2);
64     assert(io.length == 2);
65 
66     foreach (i; 0..2)
67     {
68         if (io.front.res == -EINVAL)
69         {
70             version (D_BetterC)
71             {
72                 errmsg = "kernel doesn't support SEND/RECVMSG";
73                 return;
74             }
75             else throw new Exception("kernel doesn't support SEND/RECVMSG");
76         }
77         assert(io.front.res >= 0);
78         if (io.front.user_data == 1) continue; // write done
79         else assert((cast(ubyte*)v[0].iov_base)[0..256].equal(iota(0, 256)));
80     }
81 }