Added kernel module for starting the usb stack at boot time. It's not activated thoug...
[cake.git] / rom / dos / systemtaglist.c
blob945af94572cd7dbd92d6456b77b21f79bd1f03a1
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 #ifdef DEBUG
10 #undef DEBUG
11 #endif
12 # define DEBUG 1
13 # include <aros/debug.h>
15 #include "dos_newcliproc.h"
16 #include "dos_intern.h"
17 #include <utility/tagitem.h>
18 #include <dos/dostags.h>
19 #include <proto/utility.h>
20 #include <dos/dosextens.h>
21 #include <aros/asmcall.h>
22 #include <exec/ports.h>
24 static BPTR DupFH(BPTR fh, LONG mode, struct DosLibrary * DOSBase);
26 /*****************************************************************************
28 NAME */
30 #include <proto/dos.h>
32 AROS_LH2(LONG, SystemTagList,
34 /* SYNOPSIS */
35 AROS_LHA(CONST_STRPTR , command, D1),
36 AROS_LHA(struct TagItem *, tags, D2),
38 /* LOCATION */
39 struct DosLibrary *, DOSBase, 101, Dos)
41 /* FUNCTION
43 Execute a command via a shell. As defaults, the process will use the
44 current Input() and Output(), and the current directory as well as the
45 path will be inherited from your process. If no path is specified, this
46 path will be used to find the command.
47 Normally, the boot shell is used but other shells may be specified
48 via tags. The tags are passed through to CreateNewProc() except those
49 who conflict with SystemTagList(). Currently, these are
51 NP_Seglist
52 NP_FreeSeglist
53 NP_Entry
54 NP_Input
55 NP_Error
56 NP_Output
57 NP_CloseInput
58 NP_CloseOutput
59 NP_CloseError
60 NP_HomeDir
61 NP_Cli
62 NP_Arguments
63 NP_Synchrounous
64 NP_UserData
67 INPUTS
69 command -- program and arguments as a string
70 tags -- see <dos/dostags.h>. Note that both SystemTagList() tags and
71 tags for CreateNewProc() may be passed.
73 RESULT
75 The return code of the command executed or -1 or if the command could
76 not run because the shell couldn't be created. If the command is not
77 found, the shell will return an error code, usually RETURN_ERROR.
79 NOTES
81 You must close the input and output filehandles yourself (if needed)
82 after System() returns if they were specified via SYS_Input or
83 SYS_Output (also, see below).
84 You may NOT use the same filehandle for both SYS_Input and SYS_Output.
85 If you want them to be the same CON: window, set SYS_Input to a filehandle
86 on the CON: window and set SYS_Output to NULL. Then the shell will
87 automatically set the output by opening CONSOLE: on that handler.
88 If you specified SYS_Asynch, both the input and the output filehandles
89 will be closed when the command is finished (even if this was your Input()
90 and Output().
92 EXAMPLE
94 BUGS
96 SEE ALSO
98 Execute(), CreateNewProc(), Input(), Output(), <dos/dostags.h>
100 INTERNALS
102 *****************************************************************************/
104 AROS_LIBFUNC_INIT
106 BPTR cis = Input(), cos = Output(), ces = Error(), script = NULL;
107 BPTR shellseg = NULL;
108 STRPTR cShell = NULL;
109 BOOL script_opened = FALSE;
110 BOOL cis_opened = FALSE;
111 BOOL cos_opened = FALSE;
112 BOOL ces_opened = FALSE;
113 BOOL isBoot = TRUE;
114 BOOL isBackground = TRUE;
115 BOOL isAsynch = FALSE;
116 LONG rc = -1;
117 LONG *cliNumPtr = NULL;
119 const struct TagItem *tags2 = tags;
120 struct TagItem *newtags, *tag;
122 while ((tag = NextTagItem(&tags2)))
124 switch (tag->ti_Tag)
126 case SYS_ScriptInput:
127 script = (BPTR)tag->ti_Data;
128 break;
130 case SYS_Input:
131 cis = (BPTR)tag->ti_Data;
132 break;
134 case SYS_Output:
135 cos = (BPTR)tag->ti_Data;
136 break;
138 case SYS_Error:
139 ces = (BPTR)tag->ti_Data;
140 break;
142 case SYS_CustomShell:
143 cShell = (STRPTR)tag->ti_Data;
144 break;
146 case SYS_UserShell:
147 isBoot = !tag->ti_Data;
148 break;
150 case SYS_Background:
151 isBackground = tag->ti_Data ? TRUE : FALSE;
152 break;
154 case SYS_Asynch:
155 isAsynch = tag->ti_Data ? TRUE : FALSE;
156 break;
158 case SYS_CliNumPtr:
159 cliNumPtr = (LONG *)tag->ti_Data;
160 break;
164 /* Set up the streams */
165 if (!cis)
167 cis = Open("NIL:", FMF_READ);
168 if (!cis) goto end;
170 cis_opened = TRUE;
172 else
173 if (cis == (BPTR)SYS_DupStream)
175 cis = DupFH(Input(), FMF_READ, DOSBase);
176 if (!cis) goto end;
178 cis_opened = TRUE;
181 if (!cos)
183 if (IsInteractive(cis))
184 cos = DupFH(cis, FMF_WRITE, DOSBase);
185 else
186 cos = Open("*", FMF_WRITE);
188 if (!cos) goto end;
190 cos_opened = TRUE;
192 else
193 if (cos == (BPTR)SYS_DupStream)
195 cos = DupFH(Output(), FMF_WRITE, DOSBase);
196 if (!cos) goto end;
198 cos_opened = TRUE;
201 if (!ces)
203 if (IsInteractive(cis))
204 ces = DupFH(cos, FMF_WRITE, DOSBase);
205 else
206 ces = Open("*", FMF_WRITE);
208 if (!ces) goto end;
210 ces_opened = TRUE;
212 else
213 if (ces == (BPTR)SYS_DupStream)
215 ces = DupFH(Output(), FMF_WRITE, DOSBase);
216 if (!ces) goto end;
218 ces_opened = TRUE;
221 /* Load the shell */
222 #warning implement UserShell and BootShell
223 shellseg = LoadSeg("C:Shell");
224 if (!shellseg)
225 goto end;
227 newtags = CloneTagItems(tags);
228 if (newtags)
230 struct CliStartupMessage csm;
231 struct Process *me = (struct Process *)FindTask(NULL);
232 struct Process *cliproc;
234 struct TagItem proctags[] =
236 { NP_Entry , (IPTR) NewCliProc }, /* 0 */
237 { NP_Priority , me->pr_Task.tc_Node.ln_Pri }, /* 1 */
240 Disabled, because CreateNewProc() already handles NP_StackSize,
241 i.e. it uses either AROS_STACKSIZE or the stack from the parent
242 process.
244 // { NP_StackSize , AROS_STACKSIZE },
245 { TAG_IGNORE , 0 }, /* 2 */
246 { NP_Name , isBoot ? (IPTR)"Boot Shell" :
247 isBackground ?
248 (IPTR)"Background CLI" :
249 (IPTR)"New Shell" }, /* 3 */
250 { NP_Input , (IPTR)cis }, /* 4 */
251 { NP_Output , (IPTR)cos }, /* 5 */
252 { NP_CloseInput , (isAsynch || cis_opened) }, /* 6 */
253 { NP_CloseOutput, (isAsynch || cos_opened) }, /* 7 */
254 { NP_Cli , (IPTR)TRUE }, /* 8 */
255 { NP_WindowPtr , isAsynch ? (IPTR)NULL :
256 (IPTR)me->pr_WindowPtr }, /* 9 */
257 { NP_Arguments , (IPTR)command }, /* 10 */
258 { NP_Synchronous, FALSE }, /* 11 */
259 { NP_Error , (IPTR)ces }, /* 12 */
260 { NP_CloseError , (isAsynch || ces_opened) &&
262 Since old AmigaOS programs don't know anything about Error()
263 being handled by this function, don't close the Error stream
264 if it's the same as the caller's one.
266 ces != Error() }, /* 13 */
267 { TAG_END , 0 } /* 14 */
270 Tag filterList[] =
272 NP_Seglist,
273 NP_FreeSeglist,
274 NP_Entry,
275 NP_Input,
276 NP_Output,
277 NP_CloseInput,
278 NP_CloseOutput,
279 NP_CloseError,
280 NP_HomeDir,
281 NP_Cli,
285 FilterTagItems(newtags, filterList, TAGFILTER_NOT);
287 proctags[sizeof(proctags)/(sizeof(proctags[0])) - 1].ti_Tag = TAG_MORE;
288 proctags[sizeof(proctags)/(sizeof(proctags[0])) - 1].ti_Data = (IPTR)newtags;
290 cliproc = CreateNewProc(proctags);
292 if (cliproc)
294 csm.csm_Msg.mn_Node.ln_Type = NT_MESSAGE;
295 csm.csm_Msg.mn_Length = sizeof(csm);
296 csm.csm_Msg.mn_ReplyPort = &me->pr_MsgPort;
298 csm.csm_CurrentInput = script;
299 csm.csm_ShellSeg = shellseg;
300 csm.csm_Background = isBackground;
301 csm.csm_Asynch = isAsynch;
303 PutMsg(&cliproc->pr_MsgPort, (struct Message *)&csm);
304 WaitPort(&me->pr_MsgPort);
305 GetMsg(&me->pr_MsgPort);
307 if (cliNumPtr) *cliNumPtr = csm.csm_CliNumber;
309 rc = csm.csm_ReturnCode;
311 script_opened =
312 cis_opened =
313 cos_opened =
314 ces_opened = FALSE;
316 shellseg = NULL;
318 FreeTagItems(newtags);
321 end:
322 UnLoadSeg(shellseg);
323 if (script_opened) Close(script);
324 if (cis_opened) Close(cis);
325 if (cos_opened) Close(cos);
326 if (ces_opened) Close(ces);
328 return rc;
330 AROS_LIBFUNC_EXIT
331 } /* SystemTagList */
333 static BPTR DupFH(BPTR fh, LONG mode, struct DosLibrary * DOSBase)
335 BPTR ret = NULL;
337 if (fh)
339 BPTR olddir = CurrentDir(fh);
340 ret = Open("", mode);
342 CurrentDir(olddir);
345 return ret;