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