Upgraded GRUB2 to 2.00 release.
[AROS.git] / compiler / clib / __spawnv.c
blob2cf4cf69e365c0bc10dee2f4300de594396606e3
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 <aros/debug.h>
16 #include <unistd.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <errno.h>
20 #include <assert.h>
21 #include <sys/wait.h>
23 /*****************************************************************************
25 NAME */
26 #include <process.h>
28 int __spawnv(
30 /* SYNOPSIS */
31 int mode,
32 const char *filename,
33 int searchpath,
34 char *const argv[])
36 /* FUNCTION
37 Spawn a child process, given a vector of arguments and an already LoadSeg()'d executable.
39 INPUTS
40 mode - the way the child process has to be loaded, and how the parent has to behave
41 after the child process is initiated. Specify one of the following values:
43 P_WAIT - the child program is loaded into memory, then it's executed while
44 the parent process waits for it to terminate, at which point the
45 patent process resumes execution.
47 P_NOWAIT - the parent program is executed concurrently with the new child process.
49 P_OVERLAY - teplace the parent program with the child program in memory and then
50 execute the child. The parent program will never be resumed. This
51 mode is equivalent to calling one of the exec*() functions.
53 filename - command to execute
55 searchpath - boolean to indicate if path should be searched for command
57 argv - a pointer to a NULL terminated array of strings representing arguments to pass
58 to the child process. The first entry in the array is conventionally the name of
59 the program to spawn, but in any case it must _never_ be NULL, and the argv
60 pointer itself must never be NULL either.
62 RESULT
64 If P_WAIT is specified, then the return code of the child program is returned.
65 If instead P_NOWAIT is used, then the pid of the newly created process is returned.
66 Finally, if P_OVERLAY is used, the function doesn't return unless an error has occurred,
67 in which case -1 is returned also for the other modes and the global errno variable will
68 hold the proper error code.
70 NOTES
72 The way the child process behaves regarding parent's file descriptors, signal handlers
73 and so on is the same way it would behave with one of the exec*(3) functions.
74 This, for one, means that all filedescriptors are inherited except the ones which have
75 the close-on-exec flag set.
77 EXAMPLE
79 BUGS
81 SEE ALSO
82 execl(), execle(), execlp(), execlpe(), execv(), execve(), execvp(), execvpe(), getenv(),
83 putenv(), setenv(), spawn(), spawnl(), spawnle(), spawnlp(), spawnlpe(), spawnp(),
84 spawnve(), spawnvp(), spawnvpe(), wait(), waitpid()
86 INTERNALS
88 For now only the stdin, stout and stderr file descriptors are inherited, and signals
89 are not handled yet.
91 ******************************************************************************/
93 switch (mode)
95 case P_NOWAIT:
96 case P_WAIT:
98 pid_t pid;
99 int ret = 0;
101 pid = vfork();
103 D(bug("__spawnv: vfork pid = %d\n", pid));
105 if (pid > 0)
107 if (ret != 0)
109 D(bug("__spawnv: From parent child returned %d from execv,\n"
110 " errno = %d\n", ret, errno));
111 /* Child exec did return => error */
112 return -1;
115 if (mode == P_WAIT)
117 int status;
119 D(bug("__spawnv: waiting for child with waitpid\n", ret));
121 waitpid(pid, &status, 0);
123 D(bug("__spawnv: child exited\n", ret));
125 if (WIFEXITED(status))
126 return WEXITSTATUS(status);
127 else
128 /* FIXME: Is this the right thing to do ? */
129 return -1;
131 else /* mode == P_NOWAIT */
132 return pid;
134 else if (pid == 0)
136 if (searchpath)
137 ret = execvp(filename, argv);
138 else
139 ret = execv(filename, argv);
141 D(bug("__spawnv: Child exec returned %d\n", ret));
143 _exit(0);
145 else /* Error in vfork */
146 return -1;
148 break;
150 case P_OVERLAY:
152 if (searchpath)
153 return execvp(filename, argv);
154 else
155 return execv(filename, argv);
157 assert(0);
159 break;
161 default:
162 errno = EINVAL;
163 return -1;
166 assert(0); /* Should not be reached */
167 errno = ENOSYS;
168 return -1;