Don't try to setup and use X11 shared memory if
[tangerine.git] / compiler / clib / system.c
blob81ad178688ee4f044f459f437d6cc12f8171b9d5
1 /*
2 Copyright © 1995-2009, The AROS Development Team. All rights reserved.
3 $Id$
5 ANSI C function system().
6 */
8 #include "__arosc_privdata.h"
10 #include <dos/dos.h>
11 #include <dos/filesystem.h>
12 #include <proto/dos.h>
13 #include <utility/tagitem.h>
14 #include <unistd.h>
15 #include <sys/types.h>
16 #include <sys/wait.h>
18 #include "__errno.h"
19 #include "__open.h"
20 #include "__upath.h"
21 #include <process.h>
23 #define DEBUG 0
24 #include <aros/debug.h>
26 typedef struct
28 BPTR command;
29 LONG returncode;
30 struct arosc_privdata *ppriv;
31 } childdata_t;
33 static AROS_UFP3(LONG, wait_entry,
34 AROS_UFPA(char *, argstr,A0),
35 AROS_UFPA(ULONG, argsize,D0),
36 AROS_UFPA(struct ExecBase *,SysBase,A6)
38 static int system_sh(const char *string);
39 static int system_no_sh(const char *string);
41 /*****************************************************************************
43 NAME */
44 #include <stdlib.h>
46 int system (
48 /* SYNOPSIS */
49 const char *string)
51 /* FUNCTION
53 INPUTS
55 RESULT
57 NOTES
59 EXAMPLE
61 BUGS
63 SEE ALSO
65 INTERNALS
67 ******************************************************************************/
69 BPTR lock;
70 APTR old_proc_window;
71 struct Process *me;
73 if (string == NULL || string[0] == '\0')
75 D(bug("system(cmd=, args=)=1\n"));
76 return 1;
79 me = (struct Process*) FindTask(NULL);
80 old_proc_window = me->pr_WindowPtr;
81 me->pr_WindowPtr = (APTR) -1;
82 lock = Lock((STRPTR) "bin:sh", SHARED_LOCK);
83 me->pr_WindowPtr = old_proc_window;
85 if(lock)
87 UnLock(lock);
88 return system_sh(string);
90 else
92 return system_no_sh(string);
94 } /* system */
97 static AROS_UFH3(LONG, wait_entry,
98 AROS_UFHA(char *, argstr,A0),
99 AROS_UFHA(ULONG, argsize,D0),
100 AROS_UFHA(struct ExecBase *,SysBase,A6)
103 AROS_USERFUNC_INIT
105 struct DosLibrary *DOSBase;
106 struct Library *aroscbase;
107 LONG rc = -1;
108 childdata_t *childdata = (childdata_t *)FindTask(NULL)->tc_UserData;
109 struct CommandLineInterface *cli;
110 LONG stacksize;
111 fdesc *in, *out, *err;
112 fdesc *newin, *newout, *newerr;
114 DOSBase = (struct DosLibrary *)OpenLibrary(DOSNAME, 39);
115 if (DOSBase == NULL)
116 goto err1;
118 aroscbase = OpenLibrary("arosc.library", 0);
119 if (aroscbase == NULL)
120 goto err2;
122 newin = __alloc_fdesc();
123 newout = __alloc_fdesc();
124 newerr = __alloc_fdesc();
125 if(!newin || !newout || !newerr)
127 goto err2;
129 #define privdata __get_arosc_privdata()
130 D(bug("privdata: %p, ppriv: %p\n", privdata, childdata->ppriv));
131 privdata->acpd_parent_does_upath = childdata->ppriv->acpd_doupath;
132 __get_arosc_privdata()->acpd_flags |= KEEP_OLD_ACPD | DO_NOT_CLONE_ENV_VARS;
134 cli = Cli();
135 if (cli)
136 stacksize = cli->cli_DefaultStack * CLI_DEFAULTSTACK_UNIT;
137 else
138 stacksize = AROS_STACKSIZE;
140 if(__fd_array[STDIN_FILENO])
141 close(STDIN_FILENO);
142 if(__fd_array[STDOUT_FILENO])
143 close(STDOUT_FILENO);
144 if(__fd_array[STDERR_FILENO])
145 close(STDERR_FILENO);
147 in = childdata->ppriv->acpd_fd_array[STDIN_FILENO];
148 out = childdata->ppriv->acpd_fd_array[STDOUT_FILENO];
149 err = childdata->ppriv->acpd_fd_array[STDERR_FILENO];
151 if(in)
152 SelectInput(in->fcb->fh);
153 if(out)
154 SelectOutput(out->fcb->fh);
155 if(err)
156 SelectError(err->fcb->fh);
158 in->fcb->opencount++;
159 out->fcb->opencount++;
160 err->fcb->opencount++;
161 newin->fdflags = 0;
162 newout->fdflags = 0;
163 newerr->fdflags = 0;
164 newin->fcb = in->fcb;
165 newout->fcb = out->fcb;
166 newerr->fcb = err->fcb;
167 __fd_array[STDIN_FILENO] = newin;
168 __fd_array[STDOUT_FILENO] = newout;
169 __fd_array[STDERR_FILENO] = newerr;
171 rc = RunCommand(childdata->command, stacksize, argstr, argsize);
173 CloseLibrary(aroscbase);
175 err2:
176 CloseLibrary((struct Library *)DOSBase);
178 err1:
179 childdata->returncode = rc;
181 return rc;
183 AROS_USERFUNC_EXIT
186 static int system_sh(const char *string)
188 pid_t pid = vfork();
189 int status;
191 if(pid > 0)
193 if(waitpid(pid, &status, 0) == -1)
194 return -1;
195 return status;
197 else if(pid == 0)
199 execl((__doupath ? "/bin/sh" : "bin:sh"), "sh", "-c", string, (char *) NULL);
200 _exit(127);
202 else
204 return -1;
208 static int system_no_sh(const char *string)
210 CONST_STRPTR apath;
211 char *args, *cmd;
212 BPTR seg;
213 int ret;
215 cmd = strdup(string);
216 args = cmd;
218 while (++args)
220 switch (args[0])
222 case ' ':
223 case '\t':
224 case '\n':
225 args[0] = '\0';
226 break;
227 case '\0':
228 args = NULL;
229 break;
232 if (!args)
233 break;
235 if (args[0] == '\0')
237 ++args;
238 break;
242 D(bug("system(cmd=%s, args=%s)\n", cmd, args ? args : ""));
244 apath = (STRPTR) __path_u2a(cmd);
245 seg = LoadSeg(apath);
246 if (seg == MKBADDR(NULL))
248 struct CommandLineInterface *cli = Cli();
249 BPTR oldCurDir = CurrentDir(NULL);
250 BPTR *paths = cli ? BADDR(cli->cli_CommandDir) : NULL;
252 for (; seg == MKBADDR(NULL) && paths; paths = BADDR(paths[0]))
254 CurrentDir(paths[1]);
255 seg = LoadSeg(apath);
258 if (seg == MKBADDR(NULL))
260 errno = IoErr2errno(IoErr());
261 D(bug("system(cmd=%s, args=%s)=-1, errno=%d\n",
262 cmd, args ? args : "", errno));
263 CurrentDir(oldCurDir);
264 free(cmd);
265 return -1;
267 else
268 errno = 0;
270 CurrentDir(oldCurDir);
272 else
273 errno = 0;
276 childdata_t childdata;
278 struct TagItem tags[] =
280 { NP_Entry, (IPTR)wait_entry },
281 { NP_Arguments, (IPTR)args },
282 { NP_CloseInput, FALSE },
283 { NP_CloseOutput, FALSE },
284 { NP_CloseError, FALSE },
285 { NP_FreeSeglist, FALSE },
286 { NP_Cli, TRUE },
287 { NP_Synchronous, TRUE },
288 { NP_Name, (IPTR)cmd },
289 { NP_UserData, (IPTR)&childdata },
290 { TAG_DONE, 0 }
293 childdata.command = seg;
294 childdata.ppriv = __get_arosc_privdata();
296 if (CreateNewProc(tags) != NULL)
297 ret = childdata.returncode;
298 else
300 ret = -1;
301 errno = IoErr2errno(IoErr());
304 UnLoadSeg(seg);
307 D(bug("system(cmd=%s, args=%s)=%d, errno=%d\n",
308 cmd, args ? args : "", ret, errno));
309 free(cmd);
310 return ret;
311 } /* system */