2 Copyright © 1995-2001, 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 *****************************************************************************/
105 AROS_LIBBASE_EXT_DECL(struct DosLibrary
*, DOSBase
)
107 BPTR cis
= Input(), cos
= Output(), ces
= Error(), script
= NULL
;
108 BPTR shellseg
= NULL
;
109 STRPTR cShell
= NULL
;
110 BOOL script_opened
= FALSE
;
111 BOOL cis_opened
= FALSE
;
112 BOOL cos_opened
= FALSE
;
113 BOOL ces_opened
= FALSE
;
115 BOOL isBackground
= TRUE
;
116 BOOL isAsynch
= FALSE
;
118 LONG
*cliNumPtr
= NULL
;
120 struct TagItem
*newtags
, *tags2
= tags
, *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
;
155 isAsynch
= tag
->ti_Data
;
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 */
238 { NP_StackSize
, AROS_STACKSIZE
}, /* 2 */
239 { NP_Name
, isBoot
? (IPTR
)"Boot Shell" :
241 (IPTR
)"Background CLI" :
242 (IPTR
)"New Shell" }, /* 3 */
243 { NP_Input
, (IPTR
)cis
}, /* 4 */
244 { NP_Output
, (IPTR
)cos
}, /* 5 */
245 { NP_CloseInput
, (isAsynch
|| cis_opened
) }, /* 6 */
246 { NP_CloseOutput
, (isAsynch
|| cos_opened
) }, /* 7 */
247 { NP_Cli
, (IPTR
)TRUE
}, /* 8 */
248 { NP_WindowPtr
, isAsynch
? (IPTR
)NULL
:
249 (IPTR
)me
->pr_WindowPtr
}, /* 9 */
250 { NP_Arguments
, (IPTR
)command
}, /* 10 */
251 { NP_Synchronous
, FALSE
}, /* 11 */
252 { NP_Error
, (IPTR
)ces
}, /* 12 */
253 { NP_CloseError
, (isAsynch
|| ces_opened
) &&
255 Since old AmigaOS programs don't know anything about Error()
256 being handled by this function, don't close the Error stream
257 if it's the same as the caller's one.
259 ces
!= Error() }, /* 13 */
260 { TAG_END
, 0 } /* 14 */
278 FilterTagItems(newtags
, filterList
, TAGFILTER_NOT
);
280 proctags
[sizeof(proctags
)/(sizeof(proctags
[0])) - 1].ti_Tag
= TAG_MORE
;
281 proctags
[sizeof(proctags
)/(sizeof(proctags
[0])) - 1].ti_Data
= (IPTR
)newtags
;
283 cliproc
= CreateNewProc(proctags
);
287 csm
.csm_Msg
.mn_Node
.ln_Type
= NT_MESSAGE
;
288 csm
.csm_Msg
.mn_Length
= sizeof(csm
);
289 csm
.csm_Msg
.mn_ReplyPort
= &me
->pr_MsgPort
;
291 csm
.csm_CurrentInput
= script
;
292 csm
.csm_ShellSeg
= shellseg
;
293 csm
.csm_Background
= isBackground
;
294 csm
.csm_Asynch
= isAsynch
;
296 PutMsg(&cliproc
->pr_MsgPort
, (struct Message
*)&csm
);
297 WaitPort(&me
->pr_MsgPort
);
298 GetMsg(&me
->pr_MsgPort
);
300 if (cliNumPtr
) *cliNumPtr
= csm
.csm_CliNumber
;
302 rc
= csm
.csm_ReturnCode
;
311 FreeTagItems(newtags
);
316 if (script_opened
) Close(script
);
317 if (cis_opened
) Close(cis
);
318 if (cos_opened
) Close(cos
);
319 if (ces_opened
) Close(ces
);
324 } /* SystemTagList */
326 static BPTR
DupFH(BPTR fh
, LONG mode
, struct DosLibrary
* DOSBase
)
332 BPTR olddir
= CurrentDir(fh
);
333 ret
= Open("", mode
);