Restored work-around for hangs when trying to use disk-based handlers
[tangerine.git] / compiler / clib / system.c
blobd6a104af9785560840a21a6f408608ffb9052456
1 /*
2 Copyright © 1995-2001, 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>
16 #include "__errno.h"
17 #include "__open.h"
18 #include "__spawnv.h"
19 #include "__upath.h"
20 #include <process.h>
22 #define DEBUG 0
23 #include <aros/debug.h>
25 /* defined in __spawnv.c */
26 AROS_UFP3(extern LONG, wait_entry,
27 AROS_UFPA(char *, argstr,A0),
28 AROS_UFPA(ULONG, argsize,D0),
29 AROS_UFPA(struct ExecBase *,SysBase,A6));
31 extern BPTR DupFHFromfd(int fd, ULONG mode);
33 static void syncFilePos(int from_fd, BPTR to_fh)
35 fdesc *desc;
36 BPTR fh;
37 LONG offset;
39 desc = __getfdesc(from_fd);
40 if (desc)
42 fh = (BPTR)(desc->fh);
43 Flush(fh);
44 offset = Seek(fh, 0, OFFSET_CURRENT);
46 if (offset > 0)
47 if (Seek(to_fh, offset, OFFSET_BEGINNING) < 0)
48 D(bug("system: Seek error: %d\n", IoErr()));
52 static void syncFilePosBack(BPTR from_fh, int to_fd)
54 fdesc *desc;
55 BPTR fh;
56 LONG offset;
58 desc = __getfdesc(to_fd);
59 if (desc)
61 fh = (BPTR)(desc->fh);
62 Flush(fh);
63 offset = Seek(from_fh, 0, OFFSET_CURRENT);
65 if (offset > 0)
66 if (Seek(fh, offset, OFFSET_BEGINNING) < 0)
67 D(bug("system: Seek error: %d\n", IoErr()));
71 /*****************************************************************************
73 NAME */
74 #include <stdlib.h>
76 int system (
78 /* SYNOPSIS */
79 const char *string)
81 /* FUNCTION
83 INPUTS
85 RESULT
87 NOTES
89 EXAMPLE
91 BUGS
93 SEE ALSO
95 INTERNALS
97 ******************************************************************************/
99 CONST_STRPTR apath;
100 char *args, *cmd;
101 BPTR seg;
102 int ret;
104 if (string == NULL || string[0] == '\0')
106 D(bug("system(cmd=, args=)=1\n"));
107 return 1;
110 cmd = strdup(string);
111 args = cmd;
113 while (++args)
115 switch (args[0])
117 case ' ':
118 case '\t':
119 case '\n':
120 args[0] = '\0';
121 break;
122 case '\0':
123 args = NULL;
124 break;
127 if (!args)
128 break;
130 if (args[0] == '\0')
132 ++args;
133 break;
137 D(bug("system(cmd=%s, args=%s)\n", cmd, args ? args : ""));
139 apath = __path_u2a(cmd);
140 seg = LoadSeg(apath);
141 if (seg == MKBADDR(NULL))
143 struct CommandLineInterface *cli = Cli();
144 BPTR oldCurDir = CurrentDir(NULL);
145 BPTR *paths = cli ? BADDR(cli->cli_CommandDir) : NULL;
147 for (; seg == MKBADDR(NULL) && paths; paths = BADDR(paths[0]))
149 CurrentDir(paths[1]);
150 seg = LoadSeg(apath);
153 if (seg == MKBADDR(NULL))
155 errno = IoErr2errno(IoErr());
156 D(bug("system(cmd=%s, args=%s)=-1, errno=%d\n",
157 cmd, args ? args : "", errno));
158 CurrentDir(oldCurDir);
159 free(cmd);
160 return -1;
162 else
163 errno = 0;
165 CurrentDir(oldCurDir);
167 else
168 errno = 0;
171 BPTR in, out, err;
172 childdata_t childdata;
174 struct TagItem tags[] =
176 { NP_Entry, (IPTR)wait_entry },
177 { NP_Input, 0 }, /* 1 */
178 { NP_Output, 0 }, /* 2 */
179 { NP_Error, 0 }, /* 3 */
180 { NP_Arguments, (IPTR)args }, /* 4 */
181 { NP_CloseInput, FALSE },
182 { NP_CloseOutput, FALSE },
183 { NP_CloseError, FALSE },
184 { NP_FreeSeglist, FALSE },
185 { NP_Cli, TRUE },
186 { NP_Synchronous, TRUE },
187 { NP_Name, (IPTR)cmd },
188 { NP_UserData, (IPTR)&childdata },
189 { TAG_DONE, 0 }
192 childdata.command = seg;
194 in = DupFHFromfd(STDIN_FILENO, FMF_READ);
195 out = DupFHFromfd(STDOUT_FILENO, FMF_WRITE);
196 err = DupFHFromfd(STDERR_FILENO, FMF_WRITE);
198 /* isnt the responsability of DupFH/DupLock/Open(""/Lock(""
199 to keep files pointers in sync ???
200 or better, the filesystem ??? */
201 if (in)
203 tags[1].ti_Data = (IPTR)in;
204 syncFilePos(STDIN_FILENO, in);
206 else
207 tags[1].ti_Tag = TAG_IGNORE;
209 if (in)
211 tags[2].ti_Data = (IPTR)out;
212 syncFilePos(STDOUT_FILENO, out);
214 else
215 tags[2].ti_Tag = TAG_IGNORE;
217 if (in)
219 tags[3].ti_Data = (IPTR)err;
220 syncFilePos(STDERR_FILENO, err);
222 else
223 tags[3].ti_Tag = TAG_IGNORE;
225 childdata.parent_does_upath = __doupath;
227 if (CreateNewProc(tags) != NULL)
228 ret = childdata.returncode;
229 else
231 ret = -1;
232 errno = IoErr2errno(IoErr());
235 UnLoadSeg(seg);
237 if (in)
239 syncFilePosBack(in, STDIN_FILENO);
240 Close(in);
243 if (out)
245 syncFilePosBack(out, STDOUT_FILENO);
246 Close(out);
249 if (err)
251 syncFilePosBack(err, STDERR_FILENO);
252 Close(err);
256 D(bug("system(cmd=%s, args=%s)=%d, errno=%d\n",
257 cmd, args ? args : "", ret, errno));
258 free(cmd);
259 return ret;
260 } /* system */