2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 ANSI C function system().
8 #include "__arosc_privdata.h"
11 #include <dos/filesystem.h>
12 #include <proto/dos.h>
13 #include <utility/tagitem.h>
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
)
39 desc
= __getfdesc(from_fd
);
42 fh
= (BPTR
)(desc
->fh
);
44 offset
= Seek(fh
, 0, OFFSET_CURRENT
);
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
)
58 desc
= __getfdesc(to_fd
);
61 fh
= (BPTR
)(desc
->fh
);
63 offset
= Seek(from_fh
, 0, OFFSET_CURRENT
);
66 if (Seek(fh
, offset
, OFFSET_BEGINNING
) < 0)
67 D(bug("system: Seek error: %d\n", IoErr()));
71 /*****************************************************************************
97 ******************************************************************************/
104 if (string
== NULL
|| string
[0] == '\0')
106 D(bug("system(cmd=, args=)=1\n"));
110 cmd
= strdup(string
);
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
);
165 CurrentDir(oldCurDir
);
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
},
186 { NP_Synchronous
, TRUE
},
187 { NP_Name
, (IPTR
)cmd
},
188 { NP_UserData
, (IPTR
)&childdata
},
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 ??? */
203 tags
[1].ti_Data
= (IPTR
)in
;
204 syncFilePos(STDIN_FILENO
, in
);
207 tags
[1].ti_Tag
= TAG_IGNORE
;
211 tags
[2].ti_Data
= (IPTR
)out
;
212 syncFilePos(STDOUT_FILENO
, out
);
215 tags
[2].ti_Tag
= TAG_IGNORE
;
219 tags
[3].ti_Data
= (IPTR
)err
;
220 syncFilePos(STDERR_FILENO
, err
);
223 tags
[3].ti_Tag
= TAG_IGNORE
;
225 childdata
.parent_does_upath
= __doupath
;
227 if (CreateNewProc(tags
) != NULL
)
228 ret
= childdata
.returncode
;
232 errno
= IoErr2errno(IoErr());
239 syncFilePosBack(in
, STDIN_FILENO
);
245 syncFilePosBack(out
, STDOUT_FILENO
);
251 syncFilePosBack(err
, STDERR_FILENO
);
256 D(bug("system(cmd=%s, args=%s)=%d, errno=%d\n",
257 cmd
, args
? args
: "", ret
, errno
));