2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
9 #include <aros/debug.h>
12 #include <dos/cliinit.h>
13 #include <dos/stdio.h>
14 #include <proto/dos.h>
15 #include <proto/exec.h>
17 #include "dos_intern.h"
18 #include "dos_newcliproc.h"
19 #include "fs_driver.h"
21 ULONG
internal_CliInitAny(struct DosPacket
*dp
, APTR DOSBase
)
25 struct CommandLineInterface
*oldcli
, *cli
;
26 struct Process
*me
= (struct Process
*)FindTask(NULL
);
27 BPTR cis
, cos
, cas
, ces
, olddir
, newdir
;
28 BOOL inter_in
= FALSE
, inter_out
= FALSE
, inter_err
= FALSE
;
29 struct ExtArg
*ea
= NULL
;
31 ASSERT_VALID_PROCESS(me
);
33 D(bug("CliInit%s packet @%p: Process %p\n", (dp
->dp_Type
> 1) ? "Custom" : (dp
->dp_Res1
? "Newcli" : "Run"), dp
, me
));
34 D(bug("\tdp_Type: %p \n", (APTR
)(IPTR
)dp
->dp_Type
));
35 D(bug("\tdp_Res1: %p (is NewCli/NewShell?)\n", (APTR
)dp
->dp_Res1
));
36 D(bug("\tdp_Res2: %p (is Invalid?)\n", (APTR
)dp
->dp_Res2
));
37 D(bug("\tdp_Arg1: %p (%s)\n", (APTR
)dp
->dp_Arg1
, dp
->dp_Res1
? "CurrentDir" : "BPTR to old CLI"));
38 D(bug("\tdp_Arg2: %p (StandardInput)\n", (APTR
)dp
->dp_Arg2
));
39 D(bug("\tdp_Arg3: %p (StandardOutput)\n", (APTR
)dp
->dp_Arg3
));
40 D(bug("\tdp_Arg4: %p (CurrentInput)\n", (APTR
)dp
->dp_Arg4
));
41 if (dp
->dp_Res1
== DOSFALSE
) {
42 D(bug("\tdp_Arg5: %p (CurrentDir)\n", (APTR
)dp
->dp_Arg5
));
43 D(bug("\tdp_Arg6: %p (Flags)\n", (APTR
)dp
->dp_Arg6
));
48 /* If dp_Type > 1, assume it's the old BCPL style of
49 * packet, where dp->dp_Type pointed to a BCPL callback to run
52 extern void BCPL_thunk(void);
54 APTR old_RetAddr
= me
->pr_ReturnAddr
;
55 D(bug("%s: Calling custom BCPL CliInit routine @%p\n",__func__
, Type
));
56 ret
= AROS_UFC8(LONG
, BCPL_thunk
,
57 AROS_UFCA(BPTR
, MKBADDR(dp
), D1
),
58 AROS_UFCA(ULONG
, 0, D2
),
59 AROS_UFCA(ULONG
, 0, D3
),
60 AROS_UFCA(ULONG
, 0, D4
),
61 AROS_UFCA(APTR
, me
->pr_Task
.tc_SPLower
, A1
),
62 AROS_UFCA(APTR
, me
->pr_GlobVec
, A2
),
63 AROS_UFCA(APTR
, &me
->pr_ReturnAddr
, A3
),
64 AROS_UFCA(LONG_FUNC
, (IPTR
)Type
, A4
));
65 D(bug("%s: Called custom BCPL CliInit routine @%p => 0x%08x\n",__func__
, Type
, ret
));
67 D(bug("%s: Calling custom BCPL reply routine @%p\n",__func__
, ret
));
68 ret
= AROS_UFC8(ULONG
, BCPL_thunk
,
69 AROS_UFCA(BPTR
, IoErr(), D1
),
70 AROS_UFCA(ULONG
, 0, D2
),
71 AROS_UFCA(ULONG
, 0, D3
),
72 AROS_UFCA(ULONG
, 0, D4
),
73 AROS_UFCA(APTR
, me
->pr_Task
.tc_SPLower
, A1
),
74 AROS_UFCA(APTR
, me
->pr_GlobVec
, A2
),
75 AROS_UFCA(APTR
, &me
->pr_ReturnAddr
, A3
),
76 AROS_UFCA(LONG_FUNC
, (IPTR
)ret
, A4
));
79 me
->pr_ReturnAddr
= old_RetAddr
;
80 D(bug("%s: Called custom BCPL reply routine @%p => 0x%08x\n",__func__
, Type
, ret
));
85 /* Create a new CLI if needed
89 D(bug("%s: Creating a new pr_CLI\n", __func__
));
90 cli
= AllocDosObject(DOS_CLI
, NULL
);
93 ReplyPkt(dp
, DOSFALSE
, ERROR_NO_FREE_STORE
);
96 SetIoErr(ERROR_NO_FREE_STORE
);
100 me
->pr_CLI
= MKBADDR(cli
);
101 me
->pr_Flags
|= PRF_FREECLI
;
102 addprocesstoroot(me
, DOSBase
);
106 /* C:NewCLI = Res1 = 1, dp_Arg1 = CurrentDir, dp_Arg5 = unused , dp_Arg6 = unused
111 /* dp_Arg1 a Lock() on the desired directory
113 newdir
= (BPTR
)dp
->dp_Arg1
;
115 /* C:Run = Res1 = 0, dp_Arg1 = OldCLI, dp_Arg5 = CurrentDir, dp_Arg6 = 0 */
117 /* dp_Arg1 a BPTR to the old CommandLineInterface
119 oldcli
= BADDR(dp
->dp_Arg1
);
121 /* dp_Arg5 a Lock() on the desired directory
123 newdir
= (BPTR
)dp
->dp_Arg5
;
126 olddir
= CurrentDir(newdir
);
127 if (olddir
&& (me
->pr_Flags
& PRF_FREECURRDIR
)) {
131 /* dp_Arg2 is the StandardInput */
132 cis
= (BPTR
)dp
->dp_Arg2
;
134 /* dp_Arg3 is the COS override */
135 cos
= (BPTR
)dp
->dp_Arg3
;
137 /* dp_Arg7 is AROS extension information */
138 ea
= (struct ExtArg
*)dp
->dp_Arg7
;
141 /* dp_Arg4 contains the CurrentInput */
142 cas
= (BPTR
)dp
->dp_Arg4
;
144 D(bug("%s: Setting cli_StandardInput from dp_Arg2\n", __func__
));
145 if (dp
->dp_Res1
== 0 && dp
->dp_Arg6
) {
146 flags
|= FNF_USERINPUT
;
157 if (IsInteractive(cis
)) {
158 D(bug("%s: Setting ConsoleTask based on cli_StandardInput\n", __func__
));
159 SetConsoleTask(((struct FileHandle
*)BADDR(cis
))->fh_Type
);
161 D(bug("%s: pr_ConsoleTask = %p\n", __func__
, GetConsoleTask()));
164 D(bug("%s: No StandardOutput provided. Synthesize one.\n", __func__
));
165 if (GetConsoleTask()) {
166 D(bug("%s: StandardOutput based on current console\n", __func__
));
167 cos
= Open("*", MODE_NEWFILE
);
169 D(bug("%s: StandardOutput is NIL:\n", __func__
));
170 cos
= Open("NIL:", MODE_NEWFILE
);
176 flags
|= FNF_RUNOUTPUT
;
180 D(bug("%s: No StandardError provided. Synthesize one.\n", __func__
));
181 if (GetConsoleTask()) {
182 D(bug("%s: StandardError based on current console\n", __func__
));
183 ces
= Open("*", MODE_NEWFILE
);
185 D(bug("%s: StandardError is NIL:\n", __func__
));
186 ces
= Open("NIL:", MODE_NEWFILE
);
192 me
->pr_Flags
|= PRF_CLOSECLIERROR
;
195 if (ea
->ea_Flags
& EAF_CLOSECES
)
196 me
->pr_Flags
|= PRF_CLOSECLIERROR
;
198 cli
->cli_CurrentInput
= cas
? cas
: cis
;
199 cli
->cli_StandardInput
= cis
;
201 cli
->cli_StandardOutput
=
202 cli
->cli_CurrentOutput
= cos
;
204 cli
->cli_StandardError
= ces
;
205 /* Compatibility with Amiga Shells which are not aware of cli_StandardError */
206 me
->pr_CES
= cli
->cli_StandardError
;
208 if (IsInteractive(cli
->cli_StandardInput
)) {
209 D(bug("%s: cli_StandardInput is interactive\n", __func__
));
210 fs_ChangeSignal(cli
->cli_StandardInput
, me
, DOSBase
);
211 SetVBuf(cli
->cli_StandardInput
, NULL
, BUF_LINE
, -1);
214 if (IsInteractive(cli
->cli_StandardOutput
)) {
215 D(bug("%s: cli_StandardOutput is interactive\n", __func__
));
216 fs_ChangeSignal(cli
->cli_StandardOutput
, me
, DOSBase
);
217 SetVBuf(cli
->cli_StandardOutput
, NULL
, BUF_LINE
, -1);
220 if (IsInteractive(cli
->cli_StandardError
)) {
221 D(bug("%s: cli_StandardError is interactive\n", __func__
));
222 fs_ChangeSignal(cli
->cli_StandardError
, me
, DOSBase
);
223 SetVBuf(cli
->cli_StandardError
, NULL
, BUF_LINE
, -1);
228 D(bug("%s: Using old CLI %p\n", __func__
, oldcli
));
229 SetPrompt(AROS_BSTR_ADDR(oldcli
->cli_Prompt
));
230 SetCurrentDirName(AROS_BSTR_ADDR(oldcli
->cli_SetName
));
231 cli
->cli_DefaultStack
= oldcli
->cli_DefaultStack
;
232 cli
->cli_CommandDir
= internal_CopyPath(oldcli
->cli_CommandDir
, DOSBase
);
234 D(bug("%s: Initializing CLI\n", __func__
));
236 SetCurrentDirName("SYS:");
237 cli
->cli_DefaultStack
= AROS_STACKSIZE
/ CLI_DEFAULTSTACK_UNIT
;
240 AROS_BSTR_setstrlen(cli
->cli_CommandFile
, 0);
241 AROS_BSTR_setstrlen(cli
->cli_CommandName
, 0);
242 cli
->cli_FailLevel
= 10;
243 cli
->cli_Module
= BNULL
;
245 cli
->cli_Background
= (inter_out
&& inter_in
&& inter_err
) ? DOSFALSE
: DOSTRUE
;
247 D(bug("%s: cli_CurrentInput = %p\n", __func__
, cli
->cli_CurrentInput
));
248 D(bug("%s: cli_StandardInput = %p\n", __func__
, cli
->cli_StandardInput
));
249 D(bug("%s: cli_StandardOutput = %p\n", __func__
, cli
->cli_StandardOutput
));
251 D(bug("%s: cli_Interactive = %p\n", __func__
, cli
->cli_Interactive
));
252 D(bug("%s: cli_Background = %p\n", __func__
, cli
->cli_Background
));
256 D(bug("+ flags:%p\n", flags
));
257 if (dp
->dp_Res1
== 0 || !(inter_in
&& inter_out
&& inter_err
))
258 flags
|= FNF_VALIDFLAGS
;
260 D(bug("- flags:%p\n", flags
));
262 case CLI_ASYSTEM
: flags
= FNF_ASYNCSYSTEM
| FNF_RUNOUTPUT
;
264 case CLI_SYSTEM
: flags
|= FNF_VALIDFLAGS
| FNF_SYSTEM
;
265 cli
->cli_Background
= TRUE
;
267 case CLI_RUN
: cli
->cli_Background
= TRUE
;
269 case CLI_NEWCLI
: flags
= 0;
271 case CLI_BOOT
: flags
|= FNF_VALIDFLAGS
| FNF_USERINPUT
;
275 D(bug("= flags:%p (Type %d)\n", flags
, Type
));
278 if (!(flags
& FNF_VALIDFLAGS
))
279 PutMsg(dp
->dp_Port
, dp
->dp_Link
);
280 FreeMem(ea
, sizeof(struct ExtArg
));
282 D(bug("%s: Flags = 0x%08x\n", __func__
, flags
));