revert between 56095 -> 55830 in arch
[AROS.git] / rom / dos / newcliproc.c
blob1bb0905b826950ba365f56530fa2b56288a8e275
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
9 #include <aros/debug.h>
11 #include <dos/dos.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)
23 ULONG flags = 0;
24 LONG Type;
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));
46 Type = dp->dp_Type;
47 #ifdef __mc68000
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
51 if (Type > 1) {
52 extern void BCPL_thunk(void);
53 LONG ret;
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));
66 if (ret > 0) {
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));
77 ret = 0;
79 me->pr_ReturnAddr = old_RetAddr;
80 D(bug("%s: Called custom BCPL reply routine @%p => 0x%08x\n",__func__, Type, ret));
81 return ret;
83 #endif
85 /* Create a new CLI if needed
87 cli = Cli();
88 if (cli == NULL) {
89 D(bug("%s: Creating a new pr_CLI\n", __func__));
90 cli = AllocDosObject(DOS_CLI, NULL);
91 if (cli == NULL) {
92 if (dp) {
93 ReplyPkt(dp, DOSFALSE, ERROR_NO_FREE_STORE);
94 SetIoErr((SIPTR)me);
95 } else {
96 SetIoErr(ERROR_NO_FREE_STORE);
98 return 0;
100 me->pr_CLI = MKBADDR(cli);
101 me->pr_Flags |= PRF_FREECLI;
102 addprocesstoroot(me, DOSBase);
105 if (dp->dp_Res1) {
106 /* C:NewCLI = Res1 = 1, dp_Arg1 = CurrentDir, dp_Arg5 = unused , dp_Arg6 = unused
109 oldcli = BNULL;
111 /* dp_Arg1 a Lock() on the desired directory
113 newdir = (BPTR)dp->dp_Arg1;
114 } else {
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)) {
128 UnLock(olddir);
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;
139 ces = ea->ea_CES;
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;
149 if (cis == BNULL)
150 cis = cas;
152 if (cis == BNULL) {
153 SetIoErr((SIPTR)me);
154 goto exit;
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()));
163 if (!cos) {
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);
168 } else {
169 D(bug("%s: StandardOutput is NIL:\n", __func__));
170 cos = Open("NIL:", MODE_NEWFILE);
172 if (cos == BNULL) {
173 SetIoErr((SIPTR)me);
174 goto exit;
176 flags |= FNF_RUNOUTPUT;
179 if (!ces) {
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);
184 } else {
185 D(bug("%s: StandardError is NIL:\n", __func__));
186 ces = Open("NIL:", MODE_NEWFILE);
188 if (ces == BNULL) {
189 SetIoErr((SIPTR)me);
190 goto exit;
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);
212 inter_in = TRUE;
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);
218 inter_out = TRUE;
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);
224 inter_err = TRUE;
227 if (oldcli) {
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);
233 } else {
234 D(bug("%s: Initializing CLI\n", __func__));
235 SetPrompt("%N> ");
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));
254 SetIoErr(0);
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));
261 switch (Type) {
262 case CLI_ASYSTEM: flags = FNF_ASYNCSYSTEM | FNF_RUNOUTPUT;
263 /* Fallthrough */
264 case CLI_SYSTEM: flags |= FNF_VALIDFLAGS | FNF_SYSTEM;
265 cli->cli_Background = TRUE;
266 break;
267 case CLI_RUN: cli->cli_Background = TRUE;
268 /* Fallthrough */
269 case CLI_NEWCLI: flags = 0;
270 break;
271 case CLI_BOOT: flags |= FNF_VALIDFLAGS | FNF_USERINPUT;
272 break;
273 default: break;
275 D(bug("= flags:%p (Type %d)\n", flags, Type));
277 exit:
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));
284 return flags;