1/*
2 * Copyright (C) 2024 HiHope Open Source Organization.
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 <cerrno>
17#include <cstdio>
18#include <cstdlib>
19#include <string>
20#include <vector>
21#include <fcntl.h>
22#include <pthread.h>
23#include <unistd.h>
24#include <arpa/inet.h>
25#include <gtest/gtest.h>
26#include <netinet/in.h>
27#include <sys/stat.h>
28#include <sys/socket.h>
29#include <sys/types.h>
30#include "securec.h"
31
32using namespace testing::ext;
33
34static const int BAD_SOCKET_FD = -1;
35static const int BUFFER_SIZE = 1024;
36static const int TEST_UDP_PORT = 22356;
37static const int TEST_TCP_PORT = 22355;
38static const char *TEST_LOCAL_IP = "127.0.0.1";
39static const char *TEST_BUFFER = "Hello, world!";
40static const char *TEST_EXIT = "exit";
41static int g_tcpFd = -1;
42static int g_udpFd = -1;
43
44enum ClientType {
45    NO_RECV_MSG = 0,
46    WAIT_MSG_NULL,
47    WAIT_MSG_EXIT,
48};
49
50class HatsDataHandleTest : public testing::Test {
51public:
52    static void SetUpTestCase();
53    static void TearDownTestCase();
54    void SetUp();
55    void TearDown();
56private:
57};
58void HatsDataHandleTest::SetUp()
59{
60    int ret;
61    int tcpFd = -1;
62    int udpFd = -1;
63    int32_t optVal = 1;
64    struct sockaddr_in serAddr = {
65        .sin_family = AF_INET,
66        .sin_port = htons(TEST_TCP_PORT),
67        .sin_addr = {
68            .s_addr = inet_addr(TEST_LOCAL_IP),
69        }
70    };
71
72    tcpFd = socket(AF_INET, SOCK_STREAM, 0);
73    EXPECT_TRUE(tcpFd > 0);
74
75    ret = setsockopt(tcpFd, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(optVal));
76    EXPECT_EQ(ret, 0);
77
78    ret = bind(tcpFd, reinterpret_cast<struct sockaddr *>(&serAddr), sizeof(serAddr));
79    EXPECT_EQ(ret, 0);
80
81    serAddr.sin_port = htons(TEST_UDP_PORT),
82    udpFd = socket(AF_INET, SOCK_DGRAM, 0);
83    EXPECT_TRUE(udpFd > 0);
84
85    ret = setsockopt(udpFd, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(optVal));
86    EXPECT_EQ(ret, 0);
87
88    ret = bind(udpFd, reinterpret_cast<struct sockaddr *>(&serAddr), sizeof(serAddr));
89    EXPECT_EQ(ret, 0);
90
91    g_tcpFd = tcpFd;
92    g_udpFd = udpFd;
93}
94void HatsDataHandleTest::TearDown()
95{
96    close(g_tcpFd);
97    g_tcpFd = -1;
98    close(g_udpFd);
99    g_udpFd = -1;
100}
101void HatsDataHandleTest::SetUpTestCase()
102{
103}
104void HatsDataHandleTest::TearDownTestCase()
105{
106}
107
108static void *TcpClient(void *args)
109{
110    int ret;
111    ssize_t size;
112    char buffer[BUFFER_SIZE] = { 0 };
113    int clientFd = -1;
114    struct sockaddr_in serAddr = {
115        .sin_family = AF_INET,
116        .sin_port = htons(TEST_TCP_PORT),
117        .sin_addr = {
118            .s_addr = inet_addr(TEST_LOCAL_IP),
119        }
120    };
121
122    clientFd = socket(AF_INET, SOCK_STREAM, 0);
123    EXPECT_TRUE(clientFd > 0);
124
125    ret = connect(clientFd, reinterpret_cast<struct sockaddr *>(&serAddr), sizeof(struct sockaddr_in));
126    EXPECT_EQ(ret, 0);
127
128    size = send(clientFd, TEST_BUFFER, strlen(TEST_BUFFER), 0);
129    EXPECT_EQ(size, strlen(TEST_BUFFER));
130
131    size = recv(clientFd, static_cast<void *>(buffer), BUFFER_SIZE, 0);
132    EXPECT_EQ(size, strlen(TEST_EXIT));
133    EXPECT_STREQ(buffer, TEST_EXIT);
134
135    close(clientFd);
136    return nullptr;
137}
138
139static void *UdpClient(void *args)
140{
141    ssize_t size;
142    int clientFd = -1;
143    char buffer[BUFFER_SIZE] = { 0 };
144    struct sockaddr_in dstAddr = { 0 };
145    socklen_t addrLen = sizeof(struct sockaddr_in);
146    struct sockaddr_in serAddr = {
147        .sin_family = AF_INET,
148        .sin_port = htons(TEST_UDP_PORT),
149        .sin_addr = {
150            .s_addr = inet_addr(TEST_LOCAL_IP),
151        }
152    };
153    ClientType *type = reinterpret_cast<ClientType *>(args);
154
155    clientFd = socket(AF_INET, SOCK_DGRAM, 0);
156    EXPECT_TRUE(clientFd > 0);
157
158    size = sendto(clientFd, TEST_BUFFER, strlen(TEST_BUFFER), 0,
159        reinterpret_cast<struct sockaddr *>(&serAddr), sizeof(struct sockaddr_in));
160    EXPECT_EQ(size, strlen(TEST_BUFFER));
161
162    if (*type == WAIT_MSG_EXIT) {
163        size = recvfrom(clientFd, static_cast<void *>(buffer), BUFFER_SIZE, 0,
164            reinterpret_cast<struct sockaddr *>(&dstAddr), &addrLen);
165        EXPECT_EQ(size, strlen(TEST_EXIT));
166        EXPECT_STREQ(buffer, TEST_EXIT);
167    } else if (*type == WAIT_MSG_NULL) {
168        size = recvfrom(clientFd, static_cast<void *>(buffer), BUFFER_SIZE, 0,
169            reinterpret_cast<struct sockaddr *>(&dstAddr), &addrLen);
170        EXPECT_EQ(size, 0);
171    }
172
173    close(clientFd);
174    return nullptr;
175}
176
177/*
178 * @tc.number : SUB_KERNEL_SYSCALL_SENDTO_RECVFROM_0100
179 * @tc.name   : SendtoAndRecvFromDataSuccess_0001
180 * @tc.desc   : sendto and recvfrom by client and service success.
181 * @tc.size   : MediumTest
182 * @tc.type   : Function
183 * @tc.level  : Level 1
184 */
185HWTEST_F(HatsDataHandleTest, SendtoAndRecvFromDataSuccess_0001, Function | MediumTest | Level1)
186{
187    ssize_t size;
188    pthread_t thread;
189    char buffer[BUFFER_SIZE] = { 0 };
190    struct sockaddr_in dstAddr = { 0 };
191    socklen_t addrLen = sizeof(struct sockaddr_in);
192    ClientType type = WAIT_MSG_EXIT;
193
194    pthread_create(&thread, nullptr, UdpClient, static_cast<void *>(&type));
195
196    size = recvfrom(g_udpFd, static_cast<void *>(buffer), BUFFER_SIZE, 0,
197        reinterpret_cast<struct sockaddr *>(&dstAddr), &addrLen);
198    EXPECT_EQ(size, strlen(TEST_BUFFER));
199    EXPECT_STREQ(buffer, TEST_BUFFER);
200
201    size = sendto(g_udpFd, TEST_EXIT, strlen(TEST_EXIT), 0,
202        reinterpret_cast<struct sockaddr *>(&dstAddr), addrLen);
203    EXPECT_EQ(size, strlen(TEST_EXIT));
204
205    pthread_join(thread, nullptr);
206}
207
208/*
209 * @tc.number : SUB_KERNEL_SYSCALL_SENDTO_RECVFROM_0200
210 * @tc.name   : SendtoAndRecvFromInvalidParamsFailed_0002
211 * @tc.desc   : sendto and recvfrom use invalid param failed.
212 * @tc.size   : MediumTest
213 * @tc.type   : Function
214 * @tc.level  : Level 2
215 */
216HWTEST_F(HatsDataHandleTest, SendtoAndRecvFromInvalidParamsFailed_0002, Function | MediumTest | Level2)
217{
218    ssize_t size;
219    char buffer[BUFFER_SIZE] = { 0 };
220    struct sockaddr_in dstAddr = { 0 };
221    socklen_t addrLen = sizeof(struct sockaddr_in);
222    int socketFd = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 0);
223    EXPECT_TRUE(socketFd > 0);
224
225    errno = 0;
226    size = recvfrom(BAD_SOCKET_FD, static_cast<void *>(buffer), BUFFER_SIZE, 0,
227        reinterpret_cast<struct sockaddr *>(&dstAddr), &addrLen);
228    EXPECT_EQ(size, -1);
229    EXPECT_EQ(errno, EBADF);
230
231    errno = 0;
232    size = recvfrom(STDIN_FILENO, static_cast<void *>(buffer), BUFFER_SIZE, 0,
233        reinterpret_cast<struct sockaddr *>(&dstAddr), &addrLen);
234    EXPECT_EQ(size, -1);
235    EXPECT_EQ(errno, ENOTSOCK);
236
237    errno = 0;
238    size = recvfrom(socketFd, nullptr, BUFFER_SIZE, 0,
239        reinterpret_cast<struct sockaddr *>(&dstAddr), &addrLen);
240    EXPECT_EQ(size, -1);
241    EXPECT_EQ(errno, EAGAIN);
242
243    errno = 0;
244    size = recvfrom(socketFd, static_cast<void *>(buffer), 0, 0,
245        reinterpret_cast<struct sockaddr *>(&dstAddr), &addrLen);
246    EXPECT_EQ(size, -1);
247    EXPECT_EQ(errno, EAGAIN);
248
249    errno = 0;
250    size = sendto(BAD_SOCKET_FD, TEST_EXIT, strlen(TEST_EXIT), 0,
251        reinterpret_cast<struct sockaddr *>(&dstAddr), addrLen);
252    EXPECT_EQ(size, -1);
253    EXPECT_EQ(errno, EBADF);
254
255    errno = 0;
256    size = sendto(STDIN_FILENO, TEST_EXIT, strlen(TEST_EXIT), 0,
257        reinterpret_cast<struct sockaddr *>(&dstAddr), addrLen);
258    EXPECT_EQ(size, -1);
259    EXPECT_EQ(errno, ENOTSOCK);
260
261    errno = 0;
262    size = sendto(socketFd, nullptr, BUFFER_SIZE, 0,
263        reinterpret_cast<struct sockaddr *>(&dstAddr), addrLen);
264    EXPECT_EQ(size, -1);
265    EXPECT_EQ(errno, EINVAL);
266
267    errno = 0;
268    size = sendto(socketFd, TEST_EXIT, 0, 0,
269        reinterpret_cast<struct sockaddr *>(&dstAddr), addrLen);
270    EXPECT_EQ(size, -1);
271    EXPECT_EQ(errno, EINVAL);
272}
273
274/*
275 * @tc.number : SUB_KERNEL_SYSCALL_SENDTO_RECVFROM_0300
276 * @tc.name   : SendtoFlagTest_0003
277 * @tc.desc   : sendto test MSG_DONTWAIT and MSG_CMSG_CLOEXEC flags success.
278 * @tc.size   : MediumTest
279 * @tc.type   : Function
280 * @tc.level  : Level 1
281 */
282HWTEST_F(HatsDataHandleTest, SendtoFlagTest_0003, Function | MediumTest | Level1)
283{
284    ssize_t size;
285    int clientFd = -1;
286    struct sockaddr_in serAddr = {
287        .sin_family = AF_INET,
288        .sin_port = htons(TEST_UDP_PORT),
289        .sin_addr = {
290            .s_addr = inet_addr(TEST_LOCAL_IP),
291        }
292    };
293
294    clientFd = socket(AF_INET, SOCK_DGRAM, 0);
295    EXPECT_TRUE(clientFd > 0);
296
297    size = sendto(clientFd, TEST_BUFFER, strlen(TEST_BUFFER), MSG_DONTWAIT,
298        reinterpret_cast<struct sockaddr *>(&serAddr), sizeof(struct sockaddr_in));
299    EXPECT_EQ(size, strlen(TEST_BUFFER));
300
301    close(clientFd);
302}
303
304/*
305 * @tc.number : SUB_KERNEL_SYSCALL_SENDMSG_RECVMSG_0400
306 * @tc.name   : RecvmsgSendmsgDataTest_0004
307 * @tc.desc   : sendmsg and recvmsg data success.
308 * @tc.size   : MediumTest
309 * @tc.type   : Function
310 * @tc.level  : Level 1
311 */
312HWTEST_F(HatsDataHandleTest, RecvmsgSendmsgDataTest_0004, Function | MediumTest | Level1)
313{
314    ssize_t size;
315    pthread_t thread;
316    ClientType type = WAIT_MSG_EXIT;
317    char buffer[BUFFER_SIZE] = { 0 };
318    struct sockaddr_in dstAddr = { 0 };
319    struct iovec io = {
320        .iov_base = buffer,
321        .iov_len = BUFFER_SIZE,
322    };
323    struct msghdr msgHdr = {
324        .msg_name = &dstAddr,
325        .msg_namelen = sizeof(struct sockaddr_in),
326        .msg_iov = &io,
327        .msg_iovlen = 1,
328    };
329
330    pthread_create(&thread, nullptr, UdpClient, static_cast<void *>(&type));
331
332    size = recvmsg(g_udpFd, &msgHdr, 0);EXPECT_EQ(size, strlen(TEST_BUFFER));
333    EXPECT_STREQ(static_cast<char *>(msgHdr.msg_iov->iov_base), TEST_BUFFER);
334
335    memcpy_s(msgHdr.msg_iov->iov_base, BUFFER_SIZE, TEST_EXIT, strlen(TEST_EXIT));
336    msgHdr.msg_iov->iov_len = strlen(TEST_EXIT);
337    size = sendmsg(g_udpFd, &msgHdr, 0);
338    EXPECT_EQ(size, strlen(TEST_EXIT));
339
340    pthread_join(thread, nullptr);
341}
342
343/*
344 * @tc.number : SUB_KERNEL_SYSCALL_SENDMSG_RECVMSG_0500
345 * @tc.name   : SendmsgRecvmsgInvalidFdFailed_0005
346 * @tc.desc   : sendmsg and recvmsg use invalid socket fd failed.
347 * @tc.size   : MediumTest
348 * @tc.type   : Function
349 * @tc.level  : Level 2
350 */
351HWTEST_F(HatsDataHandleTest, SendmsgRecvmsgInvalidFdFailed_0005, Function | MediumTest | Level2)
352{
353    ssize_t size;
354    char buffer[BUFFER_SIZE] = { 0 };
355    struct sockaddr_in dstAddr = { 0 };
356    struct iovec io = {
357        .iov_base = buffer,
358        .iov_len = BUFFER_SIZE,
359    };
360    struct msghdr msgHdr = {
361        .msg_name = &dstAddr,
362        .msg_namelen = sizeof(struct sockaddr_in),
363        .msg_iov = &io,
364        .msg_iovlen = 1,
365    };
366
367    errno = 0;
368    size = recvmsg(BAD_SOCKET_FD, &msgHdr, 0);
369    EXPECT_EQ(size, -1);
370    EXPECT_EQ(errno, EBADF);
371    errno = 0;
372    size = sendmsg(BAD_SOCKET_FD, &msgHdr, 0);
373    EXPECT_EQ(size, -1);
374    EXPECT_EQ(errno, EBADF);
375
376    errno = 0;
377    size = recvmsg(STDIN_FILENO, &msgHdr, 0);
378    EXPECT_EQ(size, -1);
379    EXPECT_EQ(errno, ENOTSOCK);
380    errno = 0;
381    size = sendmsg(STDIN_FILENO, &msgHdr, 0);
382    EXPECT_EQ(size, -1);
383    EXPECT_EQ(errno, ENOTSOCK);
384}
385
386
387/*
388 * @tc.number : SUB_KERNEL_SYSCALL_SENDMSG_RECVMSG_0600
389 * @tc.name   : SendmsgRecvmsgMsgNameTest_0006
390 * @tc.desc   : send and recvmsg use msg_name nullptr test.
391 * @tc.size   : MediumTest
392 * @tc.type   : Function
393 * @tc.level  : Level 2
394 */
395HWTEST_F(HatsDataHandleTest, SendmsgRecvmsgMsgNameTest_0006, Function | MediumTest | Level2)
396{
397    ssize_t size;
398    pthread_t thread;
399    ClientType type = NO_RECV_MSG;
400    char buffer[BUFFER_SIZE] = { 0 };
401    struct iovec io = {
402        .iov_base = buffer,
403        .iov_len = BUFFER_SIZE,
404    };
405    struct msghdr msgHdr = {
406        .msg_name = nullptr,
407        .msg_namelen = sizeof(struct sockaddr_in),
408        .msg_iov = &io,
409        .msg_iovlen = 1,
410    };
411
412    pthread_create(&thread, nullptr, UdpClient, static_cast<void *>(&type));
413    size = recvmsg(g_udpFd, &msgHdr, 0);
414    EXPECT_EQ(size, strlen(TEST_BUFFER));
415    EXPECT_EQ(msgHdr.msg_name, nullptr);
416    errno = 0;
417    size = sendmsg(g_udpFd, &msgHdr, 0);
418    EXPECT_EQ(size, -1);
419    EXPECT_EQ(errno, EDESTADDRREQ);
420    pthread_join(thread, nullptr);
421}
422
423/*
424 * @tc.number : SUB_KERNEL_SYSCALL_SENDMSG_RECVMSG_0800
425 * @tc.name   : SendmsgRecvmsgErrorNameLenTest_0008
426 * @tc.desc   : send and recvmsg use error msg_name length test.
427 * @tc.size   : MediumTest
428 * @tc.type   : Function
429 * @tc.level  : Level 2
430 */
431HWTEST_F(HatsDataHandleTest, SendmsgRecvmsgErrorNameLenTest_0008, Function | MediumTest | Level2)
432{
433    ssize_t size;
434    pthread_t thread;
435    ClientType type = NO_RECV_MSG;
436    char buffer[BUFFER_SIZE] = { 0 };
437    struct sockaddr_in dstAddr = { 0 };
438    struct iovec io = {
439        .iov_base = buffer,
440        .iov_len = BUFFER_SIZE,
441    };
442    struct msghdr msgHdr = {
443        .msg_name = &dstAddr,
444        .msg_namelen = 0,
445        .msg_iov = &io,
446        .msg_iovlen = 1,
447    };
448
449    pthread_create(&thread, nullptr, UdpClient, static_cast<void *>(&type));
450    errno = 0;
451    size = recvmsg(g_udpFd, &msgHdr, 0);
452    EXPECT_EQ(size, strlen(TEST_BUFFER));
453    EXPECT_EQ(msgHdr.msg_namelen, sizeof(struct sockaddr_in));
454    msgHdr.msg_namelen = 0;
455    errno = 0;
456    size = sendmsg(g_udpFd, &msgHdr, 0);
457    EXPECT_EQ(size, -1);
458    EXPECT_EQ(errno, EDESTADDRREQ);
459    pthread_join(thread, nullptr);
460
461    type = WAIT_MSG_NULL;
462    pthread_create(&thread, nullptr, UdpClient, static_cast<void *>(&type));
463    msgHdr.msg_name = &dstAddr;
464    msgHdr.msg_namelen = sizeof(struct sockaddr_in);
465    msgHdr.msg_iov = nullptr;
466    msgHdr.msg_iovlen = 0;
467    size = recvmsg(g_udpFd, &msgHdr, 0);
468    EXPECT_EQ(size, 0);
469    msgHdr.msg_iov = nullptr;
470    msgHdr.msg_iovlen = 0;
471    errno = 0;
472    size = sendmsg(g_udpFd, &msgHdr, 0);
473    EXPECT_EQ(size, 0);
474    pthread_join(thread, nullptr);
475}
476
477/*
478 * @tc.number : SUB_KERNEL_SYSCALL_SENDMSG_RECVMSG_0900
479 * @tc.name   : SendmsgRecvmsgMsgIovTest_0009
480 * @tc.desc   : send and recvmsg msg_iov nullptr test.
481 * @tc.size   : MediumTest
482 * @tc.type   : Function
483 * @tc.level  : Level 2
484 */
485HWTEST_F(HatsDataHandleTest, SendmsgRecvmsgMsgIovTest_0009, Function | MediumTest | Level2)
486{
487    ssize_t size;
488    pthread_t thread;
489    ClientType type = WAIT_MSG_NULL;
490    struct sockaddr_in dstAddr = { 0 };
491    struct msghdr msgHdr = {
492        .msg_name = &dstAddr,
493        .msg_namelen = sizeof(struct sockaddr_in),
494        .msg_iov = nullptr,
495        .msg_iovlen = 0,
496    };
497
498    pthread_create(&thread, nullptr, UdpClient, static_cast<void *>(&type));
499    size = recvmsg(g_udpFd, &msgHdr, 0);
500    EXPECT_EQ(size, 0);
501    msgHdr.msg_iov = nullptr;
502    msgHdr.msg_iovlen = 0;
503    errno = 0;
504    size = sendmsg(g_udpFd, &msgHdr, 0);
505    EXPECT_EQ(size, 0);
506    pthread_join(thread, nullptr);
507}
508
509/*
510 * @tc.number : SUB_KERNEL_SYSCALL_SEND_RECV_1000
511 * @tc.name   : SendAndRecvDataSuccess_0010
512 * @tc.desc   : send/recv and getsockname by client and service success.
513 * @tc.size   : MediumTest
514 * @tc.type   : Function
515 * @tc.level  : Level 1
516 */
517HWTEST_F(HatsDataHandleTest, SendAndRecvDataSuccess_0010, Function | MediumTest | Level1)
518{
519    int ret;
520    ssize_t size;
521    pthread_t thread;
522    int acceptFd = -1;
523    int32_t backLog = 5;
524    char buffer[BUFFER_SIZE] = { 0 };
525    struct sockaddr_in dstAddr = { 0 };
526    socklen_t addrLen = sizeof(struct sockaddr_in);
527
528    ret = listen(g_tcpFd, backLog);
529    EXPECT_EQ(ret, 0);
530
531    pthread_create(&thread, nullptr, TcpClient, nullptr);
532
533    acceptFd = accept(g_tcpFd, reinterpret_cast<struct sockaddr *>(&dstAddr), &addrLen);
534    EXPECT_TRUE(acceptFd > 0);
535
536    // test getsockname get client name success
537    ret = getsockname(g_tcpFd, reinterpret_cast<struct sockaddr *>(&dstAddr), &addrLen);
538    EXPECT_EQ(ret, 0);
539    EXPECT_STREQ(inet_ntoa(dstAddr.sin_addr), TEST_LOCAL_IP);
540
541    // test recv success
542    size = recv(acceptFd, static_cast<void *>(buffer), BUFFER_SIZE, 0);
543    EXPECT_EQ(size, strlen(TEST_BUFFER));
544    EXPECT_STREQ(buffer, TEST_BUFFER);
545
546    // test send success
547    size = send(acceptFd, TEST_EXIT, strlen(TEST_EXIT), 0);
548    EXPECT_EQ(size, strlen(TEST_EXIT));
549
550    close(acceptFd);
551    pthread_join(thread, nullptr);
552}
553
554/*
555 * @tc.number : SUB_KERNEL_SYSCALL_GETSOCKNAME_1100
556 * @tc.name   : GetsocknameUseInvalidFdFailed_0011
557 * @tc.desc   : getsockname use invalid socket fd failed.
558 * @tc.size   : MediumTest
559 * @tc.type   : Function
560 * @tc.level  : Level 2
561 */
562HWTEST_F(HatsDataHandleTest, GetsocknameUseInvalidFdFailed_0011, Function | MediumTest | Level2)
563{
564    int ret;
565    struct sockaddr_in dstAddr = { 0 };
566    socklen_t addrLen = sizeof(struct sockaddr_in);
567
568    // use invalid socket fd failed
569    errno = 0;
570    ret = getsockname(BAD_SOCKET_FD, reinterpret_cast<struct sockaddr *>(&dstAddr), &addrLen);
571    EXPECT_EQ(ret, -1);
572    EXPECT_EQ(errno, EBADF);
573}
574
575