1 /*
2 * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification,
5 * are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific prior written
16 * permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 #include <fstream>
31 #include <iostream>
32 #include "It_container_test.h"
33 using namespace std;
34
childFunc(void *arg)35 static int childFunc(void *arg)
36 {
37 int ret;
38 (void)arg;
39 mqd_t mqueueChild;
40 char msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0};
41 char mqname[MQUEUE_STANDARD_NAME_LENGTH] = "/testMQueue001";
42 const char msgptr[] = "childMsgs";
43 struct mq_attr attr = { 0 };
44 attr.mq_msgsize = MQUEUE_TEST_SIZE;
45 attr.mq_maxmsg = MQUEUE_TEST_MAX_MSG;
46 mqueueChild = mq_open(mqname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, &attr);
47 if (mqueueChild == (mqd_t)-1) {
48 goto EXIT1;
49 }
50 ret = mq_send(mqueueChild, msgptr, strlen(msgptr), 0);
51 if (ret != 0) {
52 goto EXIT1;
53 }
54 ret = mq_receive(mqueueChild, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL);
55 if (ret == -1) {
56 goto EXIT1;
57 }
58 if (strncmp(msgrcd, msgptr, strlen(msgptr)) != 0) {
59 goto EXIT1;
60 }
61
62 EXIT1:
63 if (mqueueChild >= 0) {
64 ret = mq_close(mqueueChild);
65 if (ret != 0) {
66 return EXIT_CODE_ERRNO_1;
67 }
68 ret = mq_unlink(mqname);
69 if (ret != 0) {
70 return EXIT_CODE_ERRNO_2;
71 }
72 }
73 return EXIT_CODE_ERRNO_7;
74 }
75
ItIpcContainer001(void)76 void ItIpcContainer001(void)
77 {
78 uint32_t ret;
79 int status;
80 int exitCode;
81 pid_t pid;
82 mqd_t mqueueParent;
83 int arg = CHILD_FUNC_ARG;
84 char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK,
85 -1, 0);
86 ASSERT_NE(stack, nullptr);
87 char *stackTop = stack + STACK_SIZE;
88 char msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0};
89 char mqname[MQUEUE_STANDARD_NAME_LENGTH] = "/testMQueue001";
90 const char msgptr[] = "parentMsg";
91 struct mq_attr attr = { 0 };
92 attr.mq_msgsize = MQUEUE_TEST_SIZE;
93 attr.mq_maxmsg = MQUEUE_TEST_MAX_MSG;
94
95 mqueueParent = mq_open(mqname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, NULL);
96 MQueueFinalizer mQueueFinalizer(mqueueParent, mqname);
97
98 ASSERT_NE(mqueueParent, (mqd_t)-1);
99
100 (void)memset_s(&attr, sizeof(attr), 0, sizeof(attr));
101 ret = mq_getattr(mqueueParent, &attr);
102 ASSERT_EQ(ret, 0);
103
104 attr.mq_flags |= O_NONBLOCK;
105 ret = mq_setattr(mqueueParent, &attr, NULL);
106 ASSERT_EQ(ret, 0);
107
108 ret = mq_getattr(mqueueParent, &attr);
109 ASSERT_EQ(ret, 0);
110
111 ret = mq_send(mqueueParent, msgptr, strlen(msgptr), 0);
112 ASSERT_EQ(ret, 0);
113
114 pid = clone(childFunc, stackTop, CLONE_NEWIPC | SIGCHLD, &arg);
115 ASSERT_NE(pid, -1);
116
117 ret = waitpid(pid, &status, 0);
118 ASSERT_EQ(ret, pid);
119
120 ret = WIFEXITED(status);
121 ASSERT_NE(ret, 0);
122
123 exitCode = WEXITSTATUS(status);
124 ASSERT_EQ(exitCode, EXIT_CODE_ERRNO_7);
125
126 ret = mq_receive(mqueueParent, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL);
127 ASSERT_NE(ret, -1);
128 ASSERT_STREQ(msgrcd, msgptr);
129 }
130