aboutsummaryrefslogtreecommitdiff
path: root/src/service/testing/testing_api_cmd_exec_bash_script.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/service/testing/testing_api_cmd_exec_bash_script.c')
-rw-r--r--src/service/testing/testing_api_cmd_exec_bash_script.c216
1 files changed, 216 insertions, 0 deletions
diff --git a/src/service/testing/testing_api_cmd_exec_bash_script.c b/src/service/testing/testing_api_cmd_exec_bash_script.c
new file mode 100644
index 000000000..171a2baac
--- /dev/null
+++ b/src/service/testing/testing_api_cmd_exec_bash_script.c
@@ -0,0 +1,216 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2023 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file testing_api_cmd_local_test_prepared.c
23 * @brief cmd to block the interpreter loop until all peers started.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testing_ng_lib.h"
29
30#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
31
32struct BashScriptState
33{
34 /**
35 * Context for our asynchronous completion.
36 */
37 struct GNUNET_TESTING_AsyncContext ac;
38
39 /**
40 * Callback handed over to the command, which should
41 * be called upon death or completion of the script.
42 */
43 GNUNET_ChildCompletedCallback cb;
44
45 // Child Wait handle
46 struct GNUNET_ChildWaitHandle *cwh;
47
48 /**
49 * The process id of the script.
50 */
51 struct GNUNET_OS_Process *start_proc;
52
53 /**
54 * Script this cmd will execute.
55 */
56 const char *script;
57
58
59 /**
60 * Arguments for the script
61 */
62 char *const*script_argv;
63
64 /**
65 * Size of script_argv.
66 */
67 int argc;
68};
69
70/**
71 * The cleanup function of this cmd frees resources the cmd allocated.
72 *
73 */
74static void
75exec_bash_script_cleanup (void *cls)
76{
77 struct BashScriptState *bss = cls;
78
79 if (NULL != bss->cwh)
80 {
81 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
82 "Cancel child\n");
83 GNUNET_wait_child_cancel (bss->cwh);
84 bss->cwh = NULL;
85 }
86 if (NULL != bss->start_proc)
87 {
88 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
89 "Kill process\n");
90 GNUNET_assert (0 ==
91 GNUNET_OS_process_kill (bss->start_proc,
92 SIGKILL));
93 GNUNET_assert (GNUNET_OK ==
94 GNUNET_OS_process_wait (bss->start_proc));
95 GNUNET_OS_process_destroy (bss->start_proc);
96 bss->start_proc = NULL;
97 }
98 GNUNET_free (bss);
99}
100
101/**
102 * Callback which will be called if the setup script finished.
103 *
104 */
105static void
106child_completed_callback (void *cls,
107 enum GNUNET_OS_ProcessStatusType type,
108 long unsigned int exit_code)
109{
110 struct BashScriptState *bss = cls;
111
112 GNUNET_OS_process_destroy (bss->start_proc);
113 bss->start_proc = NULL;
114 bss->cwh = NULL;
115 if (0 == exit_code)
116 {
117 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
118 "Child succeeded!\n");
119 GNUNET_TESTING_async_finish (&bss->ac);
120 }
121 else
122 {
123 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
124 "Child failed with error %lu!\n",
125 exit_code);
126 GNUNET_TESTING_async_fail (&bss->ac);
127 }
128 bss->cb (cls, type, exit_code);
129}
130
131/**
132 * Run method of the command created by the interpreter to wait for another
133 * command to finish.
134 *
135 */
136static void
137exec_bash_script_run (void *cls,
138 struct GNUNET_TESTING_Interpreter *is)
139{
140 struct BashScriptState *bss = cls;
141 enum GNUNET_GenericReturnValue helper_check;
142 char *argv[bss->argc + 2];
143
144 char *data_dir;
145 char *script_name;
146
147 data_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR);
148 GNUNET_asprintf (&script_name, "%s%s", data_dir, bss->script);
149
150 helper_check = GNUNET_OS_check_helper_binary (
151 script_name,
152 GNUNET_YES,
153 NULL);
154
155 LOG (GNUNET_ERROR_TYPE_DEBUG,
156 "script_name %s\n",
157 script_name);
158
159 if (GNUNET_NO == helper_check)
160 {
161 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
162 "No SUID for %s!\n",
163 script_name);
164 GNUNET_TESTING_interpreter_fail (is);
165 return;
166 }
167 if (GNUNET_SYSERR == helper_check)
168 {
169 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
170 "%s not found!\n",
171 script_name);
172 GNUNET_TESTING_interpreter_fail (is);
173 return;
174 }
175 argv[0] = script_name;
176 if (NULL != bss->script_argv)
177 {
178 for (int i = 0; i < bss->argc;i++)
179 argv[i + 1] = bss->script_argv[i];
180 }
181 argv[bss->argc] = NULL;
182
183 bss->start_proc = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR,
184 NULL,
185 NULL,
186 NULL,
187 script_name,
188 argv);
189 bss->cwh = GNUNET_wait_child (bss->start_proc,
190 &child_completed_callback,
191 bss);
192 GNUNET_break (NULL != bss->cwh);
193}
194
195const struct GNUNET_TESTING_Command
196GNUNET_TESTING_cmd_exec_bash_script (const char *label,
197 const char *script,
198 char *const script_argv[],
199 int argc,
200 GNUNET_ChildCompletedCallback cb)
201{
202 struct BashScriptState *bss;
203
204 bss = GNUNET_new (struct BashScriptState);
205 bss->script = script;
206 bss->script_argv = script_argv; // FIXME this is not just a cast to fix
207 bss->argc = argc;
208 bss->cb = cb;
209
210 return GNUNET_TESTING_command_new (bss,
211 label,
212 &exec_bash_script_run,
213 &exec_bash_script_cleanup,
214 NULL,
215 &bss->ac);
216}