2 Copyright © 1995-2011, 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
, olddir
, newdir
;
28 BOOL inter_in
= FALSE
, inter_out
= FALSE
;
30 ASSERT_VALID_PROCESS(me
);
32 D(bug("CliInit%s packet @%p: Process %p\n", (dp
->dp_Type
> 1) ? "Custom" : (dp
->dp_Res1
? "Newcli" : "Run"), dp
, me
));
33 D(bug("\tdp_Type: %p \n", (APTR
)(IPTR
)dp
->dp_Type
));
34 D(bug("\tdp_Res1: %p (is NewCli/NewShell?)\n", (APTR
)dp
->dp_Res1
));
35 D(bug("\tdp_Res2: %p (is Invalid?)\n", (APTR
)dp
->dp_Res2
));
36 D(bug("\tdp_Arg1: %p (%s)\n", (APTR
)dp
->dp_Arg1
, dp
->dp_Res1
? "CurrentDir" : "BPTR to old CLI"));
37 D(bug("\tdp_Arg2: %p (StandardInput)\n", (APTR
)dp
->dp_Arg2
));
38 D(bug("\tdp_Arg3: %p (StandardOutput)\n", (APTR
)dp
->dp_Arg3
));
39 D(bug("\tdp_Arg4: %p (CurrentInput)\n", (APTR
)dp
->dp_Arg4
));
40 if (dp
->dp_Res1
== DOSFALSE
) {
41 D(bug("\tdp_Arg5: %p (CurrentDir)\n", (APTR
)dp
->dp_Arg5
));
42 D(bug("\tdp_Arg6: %p (Flags)\n", (APTR
)dp
->dp_Arg6
));
47 /* If dp_Type > 1, assume it's the old BCPL style of
48 * packet, where dp->dp_Type pointed to a BCPL callback to run
51 extern void BCPL_thunk(void);
53 APTR old_RetAddr
= me
->pr_ReturnAddr
;
54 D(bug("%s: Calling custom BCPL CliInit routine @%p\n",__func__
, Type
));
55 ret
= AROS_UFC8(LONG
, BCPL_thunk
,
56 AROS_UFCA(BPTR
, MKBADDR(dp
), D1
),
57 AROS_UFCA(ULONG
, 0, D2
),
58 AROS_UFCA(ULONG
, 0, D3
),
59 AROS_UFCA(ULONG
, 0, D4
),
60 AROS_UFCA(APTR
, me
->pr_Task
.tc_SPLower
, A1
),
61 AROS_UFCA(APTR
, me
->pr_GlobVec
, A2
),
62 AROS_UFCA(APTR
, &me
->pr_ReturnAddr
, A3
),
63 AROS_UFCA(LONG_FUNC
, (IPTR
)Type
, A4
));
64 D(bug("%s: Called custom BCPL CliInit routine @%p => 0x%08x\n",__func__
, Type
, ret
));
66 D(bug("%s: Calling custom BCPL reply routine @%p\n",__func__
, ret
));
67 ret
= AROS_UFC8(ULONG
, BCPL_thunk
,
68 AROS_UFCA(BPTR
, IoErr(), D1
),
69 AROS_UFCA(ULONG
, 0, D2
),
70 AROS_UFCA(ULONG
, 0, D3
),
71 AROS_UFCA(ULONG
, 0, D4
),
72 AROS_UFCA(APTR
, me
->pr_Task
.tc_SPLower
, A1
),
73 AROS_UFCA(APTR
, me
->pr_GlobVec
, A2
),
74 AROS_UFCA(APTR
, &me
->pr_ReturnAddr
, A3
),
75 AROS_UFCA(LONG_FUNC
, (IPTR
)ret
, A4
));
78 me
->pr_ReturnAddr
= old_RetAddr
;
79 D(bug("%s: Called custom BCPL reply routine @%p => 0x%08x\n",__func__
, Type
, ret
));
84 /* Create a new CLI if needed
88 D(bug("%s: Creating a new pr_CLI\n", __func__
));
89 cli
= AllocDosObject(DOS_CLI
, NULL
);
92 ReplyPkt(dp
, DOSFALSE
, ERROR_NO_FREE_STORE
);
95 SetIoErr(ERROR_NO_FREE_STORE
);
99 me
->pr_CLI
= MKBADDR(cli
);
100 me
->pr_Flags
|= PRF_FREECLI
;
101 addprocesstoroot(me
, DOSBase
);
105 /* C:NewCLI = Res1 = 1, dp_Arg1 = CurrentDir, dp_Arg5 = unused , dp_Arg6 = unused
110 /* dp_Arg1 a Lock() on the desired directory
112 newdir
= (BPTR
)dp
->dp_Arg1
;
114 /* C:Run = Res1 = 0, dp_Arg1 = OldCLI, dp_Arg5 = CurrentDir, dp_Arg6 = 0 */
116 /* dp_Arg1 a BPTR to the old CommandLineInterface
118 oldcli
= BADDR(dp
->dp_Arg1
);
120 /* dp_Arg5 a Lock() on the desired directory
122 newdir
= (BPTR
)dp
->dp_Arg5
;
125 olddir
= CurrentDir(newdir
);
126 if (olddir
&& (me
->pr_Flags
& PRF_FREECURRDIR
)) {
130 /* dp_Arg2 is the StandardInput */
131 cis
= (BPTR
)dp
->dp_Arg2
;
133 /* dp_Arg3 is the COS override */
134 cos
= (BPTR
)dp
->dp_Arg3
;
136 /* dp_Arg4 contains the CurrentInput */
137 cas
= (BPTR
)dp
->dp_Arg4
;
139 D(bug("%s: Setting cli_StandardInput from dp_Arg2\n", __func__
));
140 if (dp
->dp_Res1
== 0 && dp
->dp_Arg6
) {
141 flags
|= FNF_USERINPUT
;
152 if (IsInteractive(cis
)) {
153 D(bug("%s: Setting ConsoleTask based on cli_StandardInput\n", __func__
));
154 SetConsoleTask(((struct FileHandle
*)BADDR(cis
))->fh_Type
);
156 D(bug("%s: pr_ConsoleTask = %p\n", __func__
, GetConsoleTask()));
159 D(bug("%s: No StandardOutput provided. Synthesize one.\n", __func__
));
160 if (GetConsoleTask()) {
161 D(bug("%s: StandardOutput based on current console\n", __func__
));
162 cos
= Open("*", MODE_NEWFILE
);
164 D(bug("%s: StandardOutput is NIL:\n", __func__
));
165 cos
= Open("NIL:", MODE_NEWFILE
);
171 flags
|= FNF_RUNOUTPUT
;
174 cli
->cli_CurrentInput
= cas
? cas
: cis
;
175 cli
->cli_StandardInput
= cis
;
177 cli
->cli_StandardOutput
=
178 cli
->cli_CurrentOutput
=
179 cli
->cli_StandardError
= cos
;
183 cli
->cli_StandardError
= me
->pr_CES
;
185 if (IsInteractive(cli
->cli_StandardInput
)) {
186 D(bug("%s: cli_StandardInput is interactive\n", __func__
));
187 fs_ChangeSignal(cli
->cli_StandardInput
, me
, DOSBase
);
188 SetVBuf(cli
->cli_StandardInput
, NULL
, BUF_LINE
, -1);
191 if (IsInteractive(cli
->cli_StandardOutput
)) {
192 D(bug("%s: cli_StandardOutput is interactive\n", __func__
));
193 fs_ChangeSignal(cli
->cli_StandardOutput
, me
, DOSBase
);
194 SetVBuf(cli
->cli_StandardOutput
, NULL
, BUF_LINE
, -1);
199 D(bug("%s: Using old CLI %p\n", __func__
, oldcli
));
200 SetPrompt(AROS_BSTR_ADDR(oldcli
->cli_Prompt
));
201 SetCurrentDirName(AROS_BSTR_ADDR(oldcli
->cli_SetName
));
202 cli
->cli_DefaultStack
= oldcli
->cli_DefaultStack
;
203 cli
->cli_CommandDir
= internal_CopyPath(oldcli
->cli_CommandDir
, DOSBase
);
205 D(bug("%s: Initializing CLI\n", __func__
));
207 SetCurrentDirName("SYS:");
208 cli
->cli_DefaultStack
= AROS_STACKSIZE
/ CLI_DEFAULTSTACK_UNIT
;
211 AROS_BSTR_setstrlen(cli
->cli_CommandFile
, 0);
212 AROS_BSTR_setstrlen(cli
->cli_CommandName
, 0);
213 cli
->cli_FailLevel
= 10;
214 cli
->cli_Module
= BNULL
;
216 cli
->cli_Background
= (inter_out
&& inter_in
) ? DOSFALSE
: DOSTRUE
;
218 D(bug("%s: cli_CurrentInput = %p\n", __func__
, cli
->cli_CurrentInput
));
219 D(bug("%s: cli_StandardInput = %p\n", __func__
, cli
->cli_StandardInput
));
220 D(bug("%s: cli_StandardOutput = %p\n", __func__
, cli
->cli_StandardOutput
));
222 D(bug("%s: cli_Interactive = %p\n", __func__
, cli
->cli_Interactive
));
223 D(bug("%s: cli_Background = %p\n", __func__
, cli
->cli_Background
));
227 D(bug("+ flags:%p\n", flags
));
228 if (dp
->dp_Res1
== 0 || !(inter_in
& inter_out
))
229 flags
|= FNF_VALIDFLAGS
;
231 D(bug("- flags:%p\n", flags
));
233 case CLI_ASYSTEM
: flags
= FNF_ASYNCSYSTEM
| FNF_RUNOUTPUT
;
235 case CLI_SYSTEM
: flags
|= FNF_VALIDFLAGS
| FNF_SYSTEM
;
236 cli
->cli_Background
= TRUE
;
238 case CLI_RUN
: cli
->cli_Background
= TRUE
;
240 case CLI_NEWCLI
: flags
= 0;
242 case CLI_BOOT
: flags
|= FNF_VALIDFLAGS
| FNF_USERINPUT
;
246 D(bug("= flags:%p (Type %d)\n", flags
, Type
));
249 if (!(flags
& FNF_VALIDFLAGS
))
250 PutMsg(dp
->dp_Port
, dp
->dp_Link
);
252 D(bug("%s: Flags = 0x%08x\n", __func__
, flags
));