1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <netinet/ip.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <time.h>
21 #include <sys/socket.h>
22 #include <bits/alltypes.h>
23 #include <unistd.h>
24 #include "test.h"
25
26 extern int __recvmmsg_time64(int, struct mmsghdr *, unsigned int, unsigned int, struct timespec *);
27
28 const int SLEEP_TIME = 2;
29
sendsss(void)30 void sendsss(void)
31 {
32 int sockfd;
33 struct sockaddr_in addr;
34 struct mmsghdr msg[2];
35 struct iovec msg1[2], msg2;
36 int retval;
37
38 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
39 if (sockfd == -1) {
40 t_error("recvmmsg_0100 socket error");
41 exit(EXIT_FAILURE);
42 }
43
44 addr.sin_family = AF_INET;
45 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
46 addr.sin_port = htons(1234);
47 if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
48 t_error("recvmmsg_0100 connect error");
49 exit(EXIT_FAILURE);
50 }
51
52 memset(msg1, 0, sizeof(msg1));
53 msg1[0].iov_base = "one";
54 msg1[0].iov_len = 3;
55 msg1[1].iov_base = "two";
56 msg1[1].iov_len = 3;
57
58 memset(&msg2, 0, sizeof(msg2));
59 msg2.iov_base = "three";
60 msg2.iov_len = 5;
61
62 memset(msg, 0, sizeof(msg));
63 msg[0].msg_hdr.msg_iov = msg1;
64 msg[0].msg_hdr.msg_iovlen = 2;
65
66 msg[1].msg_hdr.msg_iov = &msg2;
67 msg[1].msg_hdr.msg_iovlen = 1;
68
69 retval = sendmmsg(sockfd, msg, 2, 0);
70 if (retval == -1)
71 t_error("recvmmsg_0100 sendmmsg error");
72 }
73
recvsss(void)74 void recvsss(void)
75 {
76 #define VLEN 10
77 #define BUFSIZE 200
78 #define TIMEOUT 1
79 int sockfd, retval;
80 struct sockaddr_in addr;
81 struct mmsghdr msgs[VLEN];
82 struct iovec iovecs[VLEN];
83 char bufs[VLEN][BUFSIZE + 1];
84 struct timespec timeout;
85
86 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
87 if (sockfd == -1) {
88 t_error("recvmmsg_time64_0100 recv socket error");
89 exit(EXIT_FAILURE);
90 }
91
92 addr.sin_family = AF_INET;
93 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
94 addr.sin_port = htons(1234);
95 if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
96 t_error("recvmmsg_time64_0100 recv bind error");
97 exit(EXIT_FAILURE);
98 }
99
100 memset(msgs, 0, sizeof(msgs));
101 for (int i = 0; i < VLEN; i++) {
102 iovecs[i].iov_base = bufs[i];
103 iovecs[i].iov_len = BUFSIZE;
104 msgs[i].msg_hdr.msg_iov = &iovecs[i];
105 msgs[i].msg_hdr.msg_iovlen = 1;
106 }
107
108 timeout.tv_sec = TIMEOUT;
109 timeout.tv_nsec = 0;
110
111 retval = __recvmmsg_time64(sockfd, msgs, VLEN, 0, &timeout);
112 if (retval == -1) {
113 t_error("recvmmsg_time64_0100 recv recvmmsg error");
114 exit(EXIT_FAILURE);
115 }
116 }
117
118 /**
119 * @tc.name : recvmmsg_time64_0100
120 * @tc.desc : Test recvmmsg to recv messages through socket
121 * @tc.level : Level 0
122 */
main(int argc,char * argv[])123 int main(int argc, char *argv[])
124 {
125 pid_t pid = fork();
126 if (pid > 0) {
127 recvsss();
128 } else if (pid == 0) {
129 sleep(SLEEP_TIME);
130 sendsss();
131 } else {
132 t_error("recvmmsg_time64_0100 fork error");
133 }
134 return t_status;
135 }