2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
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 /*****************************************************************************
30 #include <proto/dos.h>
32 AROS_LH2(LONG
, SystemTagList
,
35 AROS_LHA(CONST_STRPTR
, command
, D1
),
36 AROS_LHA(struct TagItem
*, tags
, D2
),
39 struct DosLibrary
*, DOSBase
, 101, Dos
)
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
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.
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.
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()
98 Execute(), CreateNewProc(), Input(), Output(), <dos/dostags.h>
102 *****************************************************************************/
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
;
114 BOOL isBackground
= TRUE
;
115 BOOL isAsynch
= FALSE
;
117 LONG
*cliNumPtr
= NULL
;
119 const struct TagItem
*tags2
= tags
;
120 struct TagItem
*newtags
, *tag
;
122 while ((tag
= NextTagItem(&tags2
)))
126 case SYS_ScriptInput
:
127 script
= (BPTR
)tag
->ti_Data
;
131 cis
= (BPTR
)tag
->ti_Data
;
135 cos
= (BPTR
)tag
->ti_Data
;
139 ces
= (BPTR
)tag
->ti_Data
;
142 case SYS_CustomShell
:
143 cShell
= (STRPTR
)tag
->ti_Data
;
147 isBoot
= !tag
->ti_Data
;
151 isBackground
= tag
->ti_Data
? TRUE
: FALSE
;
155 isAsynch
= tag
->ti_Data
? TRUE
: FALSE
;
159 cliNumPtr
= (LONG
*)tag
->ti_Data
;
164 /* Set up the streams */
167 cis
= Open("NIL:", FMF_READ
);
173 if (cis
== (BPTR
)SYS_DupStream
)
175 cis
= DupFH(Input(), FMF_READ
, DOSBase
);
183 if (IsInteractive(cis
))
184 cos
= DupFH(cis
, FMF_WRITE
, DOSBase
);
186 cos
= Open("*", FMF_WRITE
);
193 if (cos
== (BPTR
)SYS_DupStream
)
195 cos
= DupFH(Output(), FMF_WRITE
, DOSBase
);
203 if (IsInteractive(cis
))
204 ces
= DupFH(cos
, FMF_WRITE
, DOSBase
);
206 ces
= Open("*", FMF_WRITE
);
213 if (ces
== (BPTR
)SYS_DupStream
)
215 ces
= DupFH(Output(), FMF_WRITE
, DOSBase
);
222 #warning implement UserShell and BootShell
223 shellseg
= LoadSeg("C:Shell");
227 newtags
= CloneTagItems(tags
);
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
244 // { NP_StackSize , AROS_STACKSIZE },
245 { TAG_IGNORE
, 0 }, /* 2 */
246 { NP_Name
, isBoot
? (IPTR
)"Boot Shell" :
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 */
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
);
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
;
318 FreeTagItems(newtags
);
323 if (script_opened
) Close(script
);
324 if (cis_opened
) Close(cis
);
325 if (cos_opened
) Close(cos
);
326 if (ces_opened
) Close(ces
);
331 } /* SystemTagList */
333 static BPTR
DupFH(BPTR fh
, LONG mode
, struct DosLibrary
* DOSBase
)
339 BPTR olddir
= CurrentDir(fh
);
340 ret
= Open("", mode
);