1 /* Copyright (C) 2018-2021 Free Software Foundation, Inc.
2 
3    This program is free software: you can redistribute it and/or modify
4    it under the terms of the GNU General Public License as published by
5    the Free Software Foundation; either version 3 of the License, or
6    (at your option) any later version.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
15 
16 #include <config.h>
17 
18 /* Specification.  */
19 #include <spawn.h>
20 
21 #include <errno.h>
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #if REPLACE_POSIX_SPAWN
26 # include "spawn_int.h"
27 #endif
28 
29 /* Add an action to FILE-ACTIONS which tells the implementation to call
30    'chdir' to the given directory during the 'spawn' call.  */
31 int
posix_spawn_file_actions_addchdir(posix_spawn_file_actions_t * file_actions,const char * path)32 posix_spawn_file_actions_addchdir (posix_spawn_file_actions_t *file_actions,
33                                    const char *path)
34 #undef posix_spawn_file_actions_addchdir
35 {
36 #if !REPLACE_POSIX_SPAWN
37   return posix_spawn_file_actions_addchdir_np (file_actions, path);
38 #else
39   {
40     /* Copy PATH, because the caller may free it before calling posix_spawn()
41        or posix_spawnp().  */
42     char *path_copy = strdup (path);
43     if (path_copy == NULL)
44       return ENOMEM;
45 
46     /* Allocate more memory if needed.  */
47     if (file_actions->_used == file_actions->_allocated
48         && __posix_spawn_file_actions_realloc (file_actions) != 0)
49       {
50         /* This can only mean we ran out of memory.  */
51         free (path_copy);
52         return ENOMEM;
53       }
54 
55     {
56       struct __spawn_action *rec;
57 
58       /* Add the new value.  */
59       rec = &file_actions->_actions[file_actions->_used];
60       rec->tag = spawn_do_chdir;
61       rec->action.chdir_action.path = path_copy;
62 
63       /* Account for the new entry.  */
64       ++file_actions->_used;
65 
66       return 0;
67     }
68   }
69 #endif
70 }
71