]> git.ipfire.org Git - thirdparty/bash.git/blame - copy_cmd.c
fix for internal redirection flags colliding with open/fcntl flags; call memfd_create...
[thirdparty/bash.git] / copy_cmd.c
CommitLineData
726f6388
JA
1/* copy_command.c -- copy a COMMAND structure. This is needed
2 primarily for making function definitions, but I'm not sure
3 that anyone else will need it. */
4
81e3a4fb 5/* Copyright (C) 1987-2020,2022 Free Software Foundation, Inc.
726f6388
JA
6
7 This file is part of GNU Bash, the Bourne Again SHell.
8
2e4498b3
CR
9 Bash is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
726f6388 13
2e4498b3
CR
14 Bash is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
726f6388
JA
18
19 You should have received a copy of the GNU General Public License
2e4498b3
CR
20 along with Bash. If not, see <http://www.gnu.org/licenses/>.
21*/
726f6388 22
ccc6cda3
JA
23#include "config.h"
24
cce855bc 25#include "bashtypes.h"
726f6388 26
ccc6cda3
JA
27#if defined (HAVE_UNISTD_H)
28# include <unistd.h>
29#endif
30
cce855bc
JA
31#include <stdio.h>
32
726f6388
JA
33#include "shell.h"
34
81e3a4fb
CR
35static PATTERN_LIST *copy_case_clause (PATTERN_LIST *);
36static PATTERN_LIST *copy_case_clauses (PATTERN_LIST *);
37static FOR_COM *copy_for_command (FOR_COM *);
f73dda09 38#if defined (ARITH_FOR_COMMAND)
81e3a4fb 39static ARITH_FOR_COM *copy_arith_for_command (ARITH_FOR_COM *);
f73dda09 40#endif
81e3a4fb
CR
41static GROUP_COM *copy_group_command (GROUP_COM *);
42static SUBSHELL_COM *copy_subshell_command (SUBSHELL_COM *);
43static COPROC_COM *copy_coproc_command (COPROC_COM *);
44static CASE_COM *copy_case_command (CASE_COM *);
45static WHILE_COM *copy_while_command (WHILE_COM *);
46static IF_COM *copy_if_command (IF_COM *);
f73dda09 47#if defined (DPAREN_ARITHMETIC)
81e3a4fb 48static ARITH_COM *copy_arith_command (ARITH_COM *);
f73dda09
JA
49#endif
50#if defined (COND_COMMAND)
81e3a4fb 51static COND_COM *copy_cond_command (COND_COM *);
f73dda09 52#endif
81e3a4fb 53static SIMPLE_COM *copy_simple_command (SIMPLE_COM *);
f73dda09 54
726f6388 55WORD_DESC *
81e3a4fb 56copy_word (WORD_DESC *w)
726f6388 57{
ccc6cda3
JA
58 WORD_DESC *new_word;
59
7117c2d2 60 new_word = make_bare_word (w->word);
28ef6c31 61 new_word->flags = w->flags;
726f6388
JA
62 return (new_word);
63}
64
ccc6cda3 65/* Copy the chain of words in LIST. Return a pointer to
726f6388
JA
66 the new chain. */
67WORD_LIST *
81e3a4fb 68copy_word_list (WORD_LIST *list)
726f6388 69{
07298682
CR
70 WORD_LIST *new_list, *tl;
71
72 for (new_list = tl = (WORD_LIST *)NULL; list; list = list->next)
73 {
74 if (new_list == 0)
75 new_list = tl = make_word_list (copy_word (list->word), new_list);
76 else
77 {
78 tl->next = make_word_list (copy_word (list->word), (WORD_LIST *)NULL);
79 tl = tl->next;
80 }
81 }
82
83 return (new_list);
726f6388
JA
84}
85
86static PATTERN_LIST *
81e3a4fb 87copy_case_clause (PATTERN_LIST *clause)
726f6388 88{
ccc6cda3
JA
89 PATTERN_LIST *new_clause;
90
91 new_clause = (PATTERN_LIST *)xmalloc (sizeof (PATTERN_LIST));
726f6388
JA
92 new_clause->patterns = copy_word_list (clause->patterns);
93 new_clause->action = copy_command (clause->action);
8943768b 94 new_clause->flags = clause->flags;
726f6388
JA
95 return (new_clause);
96}
97
98static PATTERN_LIST *
81e3a4fb 99copy_case_clauses (PATTERN_LIST *clauses)
726f6388 100{
ccc6cda3 101 PATTERN_LIST *new_list, *new_clause;
726f6388 102
ccc6cda3 103 for (new_list = (PATTERN_LIST *)NULL; clauses; clauses = clauses->next)
726f6388 104 {
ccc6cda3 105 new_clause = copy_case_clause (clauses);
726f6388
JA
106 new_clause->next = new_list;
107 new_list = new_clause;
726f6388
JA
108 }
109 return (REVERSE_LIST (new_list, PATTERN_LIST *));
110}
111
112/* Copy a single redirect. */
113REDIRECT *
81e3a4fb 114copy_redirect (REDIRECT *redirect)
726f6388 115{
ccc6cda3
JA
116 REDIRECT *new_redirect;
117
118 new_redirect = (REDIRECT *)xmalloc (sizeof (REDIRECT));
e6dfa717 119 *new_redirect = *redirect; /* let the compiler do the fast structure copy */
e6dfa717
CR
120
121 if (redirect->rflags & REDIR_VARASSIGN)
122 new_redirect->redirector.filename = copy_word (redirect->redirector.filename);
123
726f6388
JA
124 switch (redirect->instruction)
125 {
126 case r_reading_until:
127 case r_deblank_reading_until:
30595b57 128 new_redirect->here_doc_eof = redirect->here_doc_eof ? savestring (redirect->here_doc_eof) : 0;
ccc6cda3 129 /*FALLTHROUGH*/
7117c2d2 130 case r_reading_string:
726f6388
JA
131 case r_appending_to:
132 case r_output_direction:
133 case r_input_direction:
134 case r_inputa_direction:
135 case r_err_and_out:
8943768b 136 case r_append_err_and_out:
726f6388
JA
137 case r_input_output:
138 case r_output_force:
139 case r_duplicating_input_word:
140 case r_duplicating_output_word:
7117c2d2
JA
141 case r_move_input_word:
142 case r_move_output_word:
ccc6cda3 143 new_redirect->redirectee.filename = copy_word (redirect->redirectee.filename);
726f6388 144 break;
d166f048
JA
145 case r_duplicating_input:
146 case r_duplicating_output:
7117c2d2
JA
147 case r_move_input:
148 case r_move_output:
d166f048
JA
149 case r_close_this:
150 break;
726f6388
JA
151 }
152 return (new_redirect);
153}
ccc6cda3 154
726f6388 155REDIRECT *
81e3a4fb 156copy_redirects (REDIRECT *list)
726f6388 157{
ccc6cda3 158 REDIRECT *new_list, *temp;
726f6388 159
ccc6cda3 160 for (new_list = (REDIRECT *)NULL; list; list = list->next)
726f6388 161 {
ccc6cda3 162 temp = copy_redirect (list);
726f6388
JA
163 temp->next = new_list;
164 new_list = temp;
726f6388
JA
165 }
166 return (REVERSE_LIST (new_list, REDIRECT *));
167}
ccc6cda3 168
726f6388 169static FOR_COM *
81e3a4fb 170copy_for_command (FOR_COM *com)
726f6388 171{
ccc6cda3
JA
172 FOR_COM *new_for;
173
174 new_for = (FOR_COM *)xmalloc (sizeof (FOR_COM));
726f6388 175 new_for->flags = com->flags;
d3a24ed2 176 new_for->line = com->line;
726f6388
JA
177 new_for->name = copy_word (com->name);
178 new_for->map_list = copy_word_list (com->map_list);
179 new_for->action = copy_command (com->action);
180 return (new_for);
181}
182
bb70624e
JA
183#if defined (ARITH_FOR_COMMAND)
184static ARITH_FOR_COM *
81e3a4fb 185copy_arith_for_command (ARITH_FOR_COM *com)
bb70624e
JA
186{
187 ARITH_FOR_COM *new_arith_for;
188
189 new_arith_for = (ARITH_FOR_COM *)xmalloc (sizeof (ARITH_FOR_COM));
190 new_arith_for->flags = com->flags;
191 new_arith_for->line = com->line;
192 new_arith_for->init = copy_word_list (com->init);
193 new_arith_for->test = copy_word_list (com->test);
194 new_arith_for->step = copy_word_list (com->step);
195 new_arith_for->action = copy_command (com->action);
196 return (new_arith_for);
197}
198#endif /* ARITH_FOR_COMMAND */
199
726f6388 200static GROUP_COM *
81e3a4fb 201copy_group_command (GROUP_COM *com)
726f6388 202{
ccc6cda3 203 GROUP_COM *new_group;
726f6388 204
ccc6cda3 205 new_group = (GROUP_COM *)xmalloc (sizeof (GROUP_COM));
726f6388
JA
206 new_group->command = copy_command (com->command);
207 return (new_group);
208}
209
bb70624e 210static SUBSHELL_COM *
81e3a4fb 211copy_subshell_command (SUBSHELL_COM *com)
bb70624e
JA
212{
213 SUBSHELL_COM *new_subshell;
214
215 new_subshell = (SUBSHELL_COM *)xmalloc (sizeof (SUBSHELL_COM));
216 new_subshell->command = copy_command (com->command);
217 new_subshell->flags = com->flags;
ec157dfe 218 new_subshell->line = com->line;
bb70624e
JA
219 return (new_subshell);
220}
221
09767ff0 222static COPROC_COM *
81e3a4fb 223copy_coproc_command (COPROC_COM *com)
09767ff0
CR
224{
225 COPROC_COM *new_coproc;
226
227 new_coproc = (COPROC_COM *)xmalloc (sizeof (COPROC_COM));
228 new_coproc->name = savestring (com->name);
229 new_coproc->command = copy_command (com->command);
230 new_coproc->flags = com->flags;
231 return (new_coproc);
232}
233
726f6388 234static CASE_COM *
81e3a4fb 235copy_case_command (CASE_COM *com)
726f6388 236{
ccc6cda3 237 CASE_COM *new_case;
726f6388 238
ccc6cda3 239 new_case = (CASE_COM *)xmalloc (sizeof (CASE_COM));
726f6388 240 new_case->flags = com->flags;
d3a24ed2 241 new_case->line = com->line;
726f6388
JA
242 new_case->word = copy_word (com->word);
243 new_case->clauses = copy_case_clauses (com->clauses);
244 return (new_case);
245}
246
247static WHILE_COM *
81e3a4fb 248copy_while_command (WHILE_COM *com)
726f6388 249{
ccc6cda3 250 WHILE_COM *new_while;
726f6388 251
ccc6cda3 252 new_while = (WHILE_COM *)xmalloc (sizeof (WHILE_COM));
726f6388
JA
253 new_while->flags = com->flags;
254 new_while->test = copy_command (com->test);
255 new_while->action = copy_command (com->action);
256 return (new_while);
257}
258
259static IF_COM *
81e3a4fb 260copy_if_command (IF_COM *com)
726f6388 261{
ccc6cda3 262 IF_COM *new_if;
726f6388 263
ccc6cda3 264 new_if = (IF_COM *)xmalloc (sizeof (IF_COM));
726f6388
JA
265 new_if->flags = com->flags;
266 new_if->test = copy_command (com->test);
267 new_if->true_case = copy_command (com->true_case);
7117c2d2 268 new_if->false_case = com->false_case ? copy_command (com->false_case) : com->false_case;
726f6388
JA
269 return (new_if);
270}
271
cce855bc
JA
272#if defined (DPAREN_ARITHMETIC)
273static ARITH_COM *
81e3a4fb 274copy_arith_command (ARITH_COM *com)
cce855bc
JA
275{
276 ARITH_COM *new_arith;
277
278 new_arith = (ARITH_COM *)xmalloc (sizeof (ARITH_COM));
279 new_arith->flags = com->flags;
280 new_arith->exp = copy_word_list (com->exp);
281 new_arith->line = com->line;
282
283 return (new_arith);
284}
285#endif
286
287#if defined (COND_COMMAND)
288static COND_COM *
81e3a4fb 289copy_cond_command (COND_COM *com)
cce855bc
JA
290{
291 COND_COM *new_cond;
292
293 new_cond = (COND_COM *)xmalloc (sizeof (COND_COM));
294 new_cond->flags = com->flags;
295 new_cond->line = com->line;
bc4cd23c
JA
296 new_cond->type = com->type;
297 new_cond->op = com->op ? copy_word (com->op) : com->op;
cce855bc
JA
298 new_cond->left = com->left ? copy_cond_command (com->left) : (COND_COM *)NULL;
299 new_cond->right = com->right ? copy_cond_command (com->right) : (COND_COM *)NULL;
300
301 return (new_cond);
302}
303#endif
304
726f6388 305static SIMPLE_COM *
81e3a4fb 306copy_simple_command (SIMPLE_COM *com)
726f6388 307{
cce855bc 308 SIMPLE_COM *new_simple;
726f6388 309
cce855bc 310 new_simple = (SIMPLE_COM *)xmalloc (sizeof (SIMPLE_COM));
726f6388
JA
311 new_simple->flags = com->flags;
312 new_simple->words = copy_word_list (com->words);
7117c2d2 313 new_simple->redirects = com->redirects ? copy_redirects (com->redirects) : (REDIRECT *)NULL;
726f6388
JA
314 new_simple->line = com->line;
315 return (new_simple);
316}
317
d3a24ed2 318FUNCTION_DEF *
81e3a4fb 319copy_function_def_contents (FUNCTION_DEF *old, FUNCTION_DEF *new_def)
d3a24ed2
CR
320{
321 new_def->name = copy_word (old->name);
5e13499c 322 new_def->command = old->command ? copy_command (old->command) : old->command;
d3a24ed2
CR
323 new_def->flags = old->flags;
324 new_def->line = old->line;
325 new_def->source_file = old->source_file ? savestring (old->source_file) : old->source_file;
326 return (new_def);
327}
328
329FUNCTION_DEF *
81e3a4fb 330copy_function_def (FUNCTION_DEF *com)
726f6388 331{
ccc6cda3 332 FUNCTION_DEF *new_def;
726f6388 333
ccc6cda3 334 new_def = (FUNCTION_DEF *)xmalloc (sizeof (FUNCTION_DEF));
d3a24ed2 335 new_def = copy_function_def_contents (com, new_def);
726f6388
JA
336 return (new_def);
337}
338
339/* Copy the command structure in COMMAND. Return a pointer to the
340 copy. Don't you forget to dispose_command () on this pointer
341 later! */
342COMMAND *
81e3a4fb 343copy_command (COMMAND *command)
726f6388 344{
ccc6cda3 345 COMMAND *new_command;
726f6388 346
ccc6cda3
JA
347 if (command == NULL)
348 return (command);
726f6388 349
ccc6cda3
JA
350 new_command = (COMMAND *)xmalloc (sizeof (COMMAND));
351 FASTCOPY ((char *)command, (char *)new_command, sizeof (COMMAND));
352 new_command->flags = command->flags;
353 new_command->line = command->line;
726f6388 354
ccc6cda3
JA
355 if (command->redirects)
356 new_command->redirects = copy_redirects (command->redirects);
357
358 switch (command->type)
359 {
360 case cm_for:
361 new_command->value.For = copy_for_command (command->value.For);
362 break;
726f6388 363
bb70624e
JA
364#if defined (ARITH_FOR_COMMAND)
365 case cm_arith_for:
366 new_command->value.ArithFor = copy_arith_for_command (command->value.ArithFor);
367 break;
368#endif
369
726f6388 370#if defined (SELECT_COMMAND)
ccc6cda3
JA
371 case cm_select:
372 new_command->value.Select =
373 (SELECT_COM *)copy_for_command ((FOR_COM *)command->value.Select);
374 break;
726f6388
JA
375#endif
376
ccc6cda3
JA
377 case cm_group:
378 new_command->value.Group = copy_group_command (command->value.Group);
379 break;
726f6388 380
bb70624e 381 case cm_subshell:
28ef6c31
JA
382 new_command->value.Subshell = copy_subshell_command (command->value.Subshell);
383 break;
bb70624e 384
09767ff0
CR
385 case cm_coproc:
386 new_command->value.Coproc = copy_coproc_command (command->value.Coproc);
387 break;
388
ccc6cda3
JA
389 case cm_case:
390 new_command->value.Case = copy_case_command (command->value.Case);
391 break;
392
393 case cm_until:
394 case cm_while:
395 new_command->value.While = copy_while_command (command->value.While);
396 break;
397
398 case cm_if:
399 new_command->value.If = copy_if_command (command->value.If);
400 break;
401
cce855bc
JA
402#if defined (DPAREN_ARITHMETIC)
403 case cm_arith:
28ef6c31
JA
404 new_command->value.Arith = copy_arith_command (command->value.Arith);
405 break;
cce855bc
JA
406#endif
407
408#if defined (COND_COMMAND)
409 case cm_cond:
410 new_command->value.Cond = copy_cond_command (command->value.Cond);
411 break;
412#endif
413
ccc6cda3
JA
414 case cm_simple:
415 new_command->value.Simple = copy_simple_command (command->value.Simple);
416 break;
417
418 case cm_connection:
419 {
420 CONNECTION *new_connection;
421
422 new_connection = (CONNECTION *)xmalloc (sizeof (CONNECTION));
423 new_connection->connector = command->value.Connection->connector;
424 new_connection->first = copy_command (command->value.Connection->first);
425 new_connection->second = copy_command (command->value.Connection->second);
426 new_command->value.Connection = new_connection;
726f6388
JA
427 break;
428 }
ccc6cda3
JA
429
430 case cm_function_def:
431 new_command->value.Function_def = copy_function_def (command->value.Function_def);
432 break;
726f6388
JA
433 }
434 return (new_command);
435}