• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4 #include <sys/socket.h>
5 #include <unistd.h>
6 #include <fcntl.h>
7 #include <errno.h>
8 #include <assert.h>
9 
10 int
main(void)11 main(void)
12 {
13 #if defined(HAVE_SENDMMSG) && defined(HAVE_STRUCT_MMSGHDR)
14 	const int R = 0, W = 1;
15 	int fd;
16 	int sv[2];
17 	char one[] = "one";
18 	char two[] = "two";
19 	char three[] = "three";
20 
21 	struct iovec iov[] = {
22 		{
23 			.iov_base = one,
24 			.iov_len = sizeof(one) - 1
25 		}, {
26 			.iov_base = two,
27 			.iov_len = sizeof(two) - 1
28 		}, {
29 			.iov_base = three,
30 			.iov_len = sizeof(three) - 1
31 		}
32 	};
33 
34 	struct mmsghdr mmh[] = {
35 		{
36 			.msg_hdr = {
37 				.msg_iov = iov + 0,
38 				.msg_iovlen = 2,
39 			}
40 		}, {
41 			.msg_hdr = {
42 				.msg_iov = iov + 2,
43 				.msg_iovlen = 1,
44 			}
45 		}
46 	};
47 #define n_mmh (sizeof(mmh)/sizeof(mmh[0]))
48 
49 	/*
50 	 * Following open/dup2/close calls make the output of strace
51 	 * more predictable, so we can just compare the output and
52 	 * expected output (mmsg.expected) for testing purposes.
53 	 */
54 	while ((fd = open("/dev/null", O_RDWR)) < 3)
55 		assert(fd >= 0);
56 	(void) close(3);
57 
58 	assert(socketpair(AF_UNIX, SOCK_DGRAM, 0, sv) == 0);
59 
60 	assert(dup2(sv[W], W) == W);
61 	assert(close(sv[W]) == 0);
62 	assert(dup2(sv[R], R) == R);
63 	assert(close(sv[R]) == 0);
64 
65 	int r = sendmmsg(W, mmh, n_mmh, 0);
66 	if (r < 0 && errno == ENOSYS)
67 		return 77;
68 	assert((size_t)r == n_mmh);
69 	assert(close(W) == 0);
70 
71 	assert(recvmmsg(R, mmh, n_mmh, 0, NULL) == n_mmh);
72 	assert(close(R) == 0);
73 
74 	return 0;
75 #else
76 	return 77;
77 #endif
78 }
79