Minor fixes to comments.
[AROS.git] / rom / dos / newcliproc.c
blob293f2862851878416755e8f829161cf6e9324ceb
1 /*
2 Copyright © 1995-2011, 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, 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));
45 Type = dp->dp_Type;
46 #ifdef __mc68000
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
50 if (Type > 1) {
51 extern void BCPL_thunk(void);
52 LONG ret;
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));
65 if (ret > 0) {
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));
76 ret = 0;
78 me->pr_ReturnAddr = old_RetAddr;
79 D(bug("%s: Called custom BCPL reply routine @%p => 0x%08x\n",__func__, Type, ret));
80 return ret;
82 #endif
84 /* Create a new CLI if needed
86 cli = Cli();
87 if (cli == NULL) {
88 D(bug("%s: Creating a new pr_CLI\n", __func__));
89 cli = AllocDosObject(DOS_CLI, NULL);
90 if (cli == NULL) {
91 if (dp) {
92 ReplyPkt(dp, DOSFALSE, ERROR_NO_FREE_STORE);
93 SetIoErr((SIPTR)me);
94 } else {
95 SetIoErr(ERROR_NO_FREE_STORE);
97 return 0;
99 me->pr_CLI = MKBADDR(cli);
100 me->pr_Flags |= PRF_FREECLI;
101 addprocesstoroot(me, DOSBase);
104 if (dp->dp_Res1) {
105 /* C:NewCLI = Res1 = 1, dp_Arg1 = CurrentDir, dp_Arg5 = unused , dp_Arg6 = unused
108 oldcli = BNULL;
110 /* dp_Arg1 a Lock() on the desired directory
112 newdir = (BPTR)dp->dp_Arg1;
113 } else {
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)) {
127 UnLock(olddir);
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;
144 if (cis == BNULL)
145 cis = cas;
147 if (cis == BNULL) {
148 SetIoErr((SIPTR)me);
149 goto exit;
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()));
158 if (!cos) {
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);
163 } else {
164 D(bug("%s: StandardOutput is NIL:\n", __func__));
165 cos = Open("NIL:", MODE_NEWFILE);
167 if (cos == BNULL) {
168 SetIoErr((SIPTR)me);
169 goto exit;
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;
181 /* AROS specific */
182 if (me->pr_CES)
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);
189 inter_in = TRUE;
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);
195 inter_out = TRUE;
198 if (oldcli) {
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);
204 } else {
205 D(bug("%s: Initializing CLI\n", __func__));
206 SetPrompt("%N> ");
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));
225 SetIoErr(0);
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));
232 switch (Type) {
233 case CLI_ASYSTEM: flags = FNF_ASYNCSYSTEM | FNF_RUNOUTPUT;
234 /* Fallthrough */
235 case CLI_SYSTEM: flags |= FNF_VALIDFLAGS | FNF_SYSTEM;
236 cli->cli_Background = TRUE;
237 break;
238 case CLI_RUN: cli->cli_Background = TRUE;
239 /* Fallthrough */
240 case CLI_NEWCLI: flags = 0;
241 break;
242 case CLI_BOOT: flags |= FNF_VALIDFLAGS | FNF_USERINPUT;
243 break;
244 default: break;
246 D(bug("= flags:%p (Type %d)\n", flags, Type));
248 exit:
249 if (!(flags & FNF_VALIDFLAGS))
250 PutMsg(dp->dp_Port, dp->dp_Link);
252 D(bug("%s: Flags = 0x%08x\n", __func__, flags));
254 return flags;