use same location as .configured, etc, to store .files-touched
[AROS.git] / compiler / clib / __spawnv.c
bloba94e37be1975ade25815ee14a9d72d73ff5482fd
1 /*
2 Copyright © 1995-2009, The AROS Development Team. All rights reserved.
3 $Id$
5 spavnv() function, used to spawn new processes.
6 */
7 #define DEBUG 0
8 #include "__arosc_privdata.h"
10 #include <proto/dos.h>
11 #include <proto/exec.h>
12 #include <dos/dos.h>
13 #include <dos/dosextens.h>
14 #include <dos/filesystem.h>
15 #include <aros/debug.h>
17 #include <unistd.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <errno.h>
21 #include <assert.h>
22 #include <sys/syscall.h>
23 #include <sys/wait.h>
25 /*****************************************************************************
27 NAME */
28 #include <process.h>
30 int __spawnv(
32 /* SYNOPSIS */
33 int mode,
34 const char *filename,
35 int searchpath,
36 char *const argv[])
38 /* FUNCTION
39 Spawn a child process, given a vector of arguments and an already LoadSeg()'d executable.
41 INPUTS
42 mode - the way the child process has to be loaded, and how the parent has to behave
43 after the child process is initiated. Specify one of the following values:
45 P_WAIT - the child program is loaded into memory, then it's executed while
46 the parent process waits for it to terminate, at which point the
47 patent process resumes execution.
49 P_NOWAIT - the parent program is executed concurrently with the new child process.
51 P_OVERLAY - teplace the parent program with the child program in memory and then
52 execute the child. The parent program will never be resumed. This
53 mode is equivalent to calling one of the exec*() functions.
55 filename - command to execute
57 searchpath - boolean to indicate if path should be searched for command
59 argv - a pointer to a NULL terminated array of strings representing arguments to pass
60 to the child process. The first entry in the array is conventionally the name of
61 the program to spawn, but in any case it must _never_ be NULL, and the argv
62 pointer itself must never be NULL either.
64 RESULT
66 If P_WAIT is specified, then the return code of the child program is returned.
67 If instead P_NOWAIT is used, then the pid of the newly created process is returned.
68 Finally, if P_OVERLAY is used, the function doesn't return unless an error has occurred,
69 in which case -1 is returned also for the other modes and the global errno variable will
70 hold the proper error code.
72 NOTES
74 The way the child process behaves regarding parent's file descriptors, signal handlers
75 and so on is the same way it would behave with one of the exec*(3) functions.
76 This, for one, means that all filedescriptors are inherited except the ones which have
77 the close-on-exec flag set.
79 EXAMPLE
81 BUGS
83 SEE ALSO
84 execl(), execle(), execlp(), execlpe(), execv(), execve(), execvp(), execvpe(), getenv(),
85 putenv(), setenv(), spawn(), spawnl(), spawnle(), spawnlp(), spawnlpe(), spawnp(),
86 spawnve(), spawnvp(), spawnvpe(), wait(), waitpid()
88 INTERNALS
90 For now only the stdin, stout and stderr file descriptors are inherited, and signals
91 are not handled yet.
93 ******************************************************************************/
95 switch (mode)
97 case P_NOWAIT:
98 case P_WAIT:
100 pid_t pid;
101 int ret = 0;
103 pid = vfork();
105 D(bug("__spawnv: vfork pid = %d\n", pid));
107 if (pid > 0)
109 if (ret != 0)
111 D(bug("__spawnv: From parent child returned %d from execv,\n"
112 " errno = %d\n", ret, errno));
113 /* Child exec did return => error */
114 return -1;
117 if (mode == P_WAIT)
119 int status;
121 D(bug("__spawnv: waiting for child with waitpid\n", ret));
123 waitpid(pid, &status, 0);
125 D(bug("__spawnv: child exited\n", ret));
127 if (WIFEXITED(status))
128 return WEXITSTATUS(status);
129 else
130 /* FIXME: Is this the right thing to do ? */
131 return -1;
133 else /* mode == P_NOWAIT */
134 return pid;
136 else if (pid == 0)
138 if (searchpath)
139 ret = execvp(filename, argv);
140 else
141 ret = execv(filename, argv);
143 D(bug("__spawnv: Child exec returned %d\n", ret));
145 _exit(0);
147 else /* Error in vfork */
148 return -1;
150 break;
152 case P_OVERLAY:
154 if (searchpath)
155 return execvp(filename, argv);
156 else
157 return execv(filename, argv);
159 assert(0);
161 break;
163 default:
164 errno = EINVAL;
165 return -1;
168 assert(0); /* Should not be reached */
169 errno = ENOSYS;
170 return -1;