Fixes to comments.
[AROS.git] / compiler / include / dos / cliinit.h
blob046b261cbd5dbfdefe0160a6ad83965bde750c93
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Document the CLI startup packet
6 Lang: English
7 */
9 #ifndef DOS_CLIINIT_H
10 #define DOS_CLIINIT_H
12 #include <aros/debug.h>
13 #include <proto/exec.h>
14 #include <proto/dos.h>
16 /* Return codes from CliInitRun() and CliInitNewcli()
19 #define FNF_VALIDFLAGS (1 << 31) /* Valid flags */
20 #define FNF_ASYNCSYSTEM (1 << 3) /* Async System() call */
21 #define FNF_SYSTEM (1 << 2) /* If this a System() call */
22 #define FNF_USERINPUT (1 << 1) /* User provided input stream */
23 #define FNF_RUNOUTPUT (1 << 0) /* C:Run provided output stream */
25 /* Shell startup packets.
27 * In truth, only dp_Res1 and dp_Res2 are 'public' - the rest of
28 * the arguments here are private, and are decoded by the
29 * DOS/CliInitRun() and DOS/CliInitNewcli() routines.
31 * NewCli/NewShell: (Asynchonous)
33 * dp_Type = 1
34 * dp_Res1 = 1
35 * dp_Res2 = 0
36 * dp_Arg1 = BPTR Lock of directory (shell must close)
37 * dp_Arg2 = BPTR to StandardInput
38 * dp_Arg3 = BPTR to StandardOuput
39 * dp_Arg4 = BPTR to CurrentInput
41 * dp_Arg5..dp_Arg7 are unused, and have junk data
43 * Boot CLI: (synchronous - this is AROS private - AOS uses a NULL Dos Packet pointer)
44 * dp_Type = -4 // AROS private
45 * dp_Res1 = 1
46 * dp_Res2 = 0
47 * dp_Arg1 = BPTR to Lock of directory (shell must close)
48 * dp_Arg2 = BPTR to StandardInput
49 * dp_Arg3 = BPTR to StandardOuput (can be BNULL if dp_Arg2 is Interactive)
50 * dp_Arg4 = BPTR to CurrentInput (is BNULL if there is no startup-sequence)
52 * dp_Arg5..dp_Arg7 are unused, and have junk data
54 * Run:
55 * NOTE: KS 1.3: bfunc is a BCPL CliInit*() function,
56 * KS 3.x bfunc is -1
57 * dp_Type = bfunc
58 * dp_Res1 = 0
59 * dp_Res2 = 0
60 * dp_Arg1 = BPTR to the old CommandLineInterface
61 * dp_Arg2 = BPTR to StandardInput
62 * dp_Arg3 = BPTR to StandardOuput
63 * dp_Arg4 = BPTR to CurrentInput
64 * dp_Arg5 = BPTR to Lock of directory (shell must close)
65 * dp_Arg6 = 0 (use CurrentInput/Open("*", MODE_NEWFILE) as Stdin/Stdout,
66 * Close() on exit)
68 * dp_Arg7 is unused, and has junk data
70 * System (SYS_Async == FALSE)
71 * dp_Type = -2
72 * dp_Res1 = 0
73 * dp_Res2 = 0
74 * dp_Arg1 = BPTR to the old CommandLineInterface
75 * dp_Arg2 = BPTR to StandardInput
76 * dp_Arg3 = BPTR to StandardOuput
77 * dp_Arg4 = BPTR to CurrentInput
78 * dp_Arg5 = BPTR to Lock of directory (shell must close)
79 * dp_Arg6 = 0 to use CurrentInput/Open("*", MODE_NEWFILE) as Stdin/Stdout
80 * Close() on exit
81 * 1 to use StandardInput/StandardOutput,
82 * Do not Close() on exit
84 * dp_Arg7 is unused, and has junk data
86 * System (SYS_Asynch == TRUE):
87 * dp_Type = -3
88 * dp_Res1 = 0
89 * dp_Res2 = 0
90 * dp_Arg1 = BPTR to the old CommandLineInterface
91 * dp_Arg2 = BPTR to StandardInput
92 * dp_Arg3 = BPTR to StandardOuput
93 * dp_Arg4 = BPTR to CurrentInput
94 * dp_Arg5 = BPTR to Lock of directory (shell must close)
95 * dp_Arg6 = 0 to use CurrentInput/Open("*", MODE_NEWFILE) as Stdin/Stdout
96 * Close() on exit
97 * 1 to use StandardInput/StandardOutput,
98 * Do not Close() on exit
101 #define CLI_NEWCLI 1
102 #define CLI_INVALID 0 /* Not a valid CLI type */
103 #define CLI_RUN -1
104 #define CLI_SYSTEM -2
105 #define CLI_ASYSTEM -3
106 #define CLI_BOOT -4 /* This is AROS specific. Not in AOS */
108 #include <proto/dos.h>
109 #include <proto/exec.h>
111 /* The following routine handles all the bureaucracy
112 * of creating a Shell suitable for placing in L:,
113 * including startup packet processing and replies,
114 * and pr_CLI initialization and cleanup.
116 * Your 'main' function will have a valid Cli()
117 * on entry. The following variables will
118 * be available to your 'main' routine:
120 * ULONG AROS_CLI_Flags; // As per the DOS/CliInitNewcli and
121 * // DOS/CliInitRun() Autodocs
122 * LONG AROS_CLI_Type; // One of the CLI_* types defined above
124 * Input() and Output() will be NULL
126 * Use the filehandles in Cli() for managing your
127 * input, output, and error streams.
129 * See Amiga Mail II-65: "Writing a UserShell" for details.
131 #define AROS_CLI(main) \
132 AROS_ENTRY(SIPTR, main, \
133 AROS_UFHA(struct DosPacket *, dp, A0), \
134 AROS_UFHA(ULONG, unused, D0), \
135 struct ExecBase *, SysBase) \
137 AROS_USERFUNC_INIT \
139 extern SIPTR _shell_##main(ULONG flags, LONG type D(, struct DosPacket *dp)); \
140 struct Process *me = (struct Process *)FindTask(NULL); \
141 D(struct DosPacket olddp;)\
142 ULONG flags; \
143 LONG type; \
144 APTR DOSBase; \
145 struct CommandLineInterface *cli; \
146 SIPTR ret; \
147 BPTR dir; \
148 BPTR *segArray; \
150 if (dp == NULL) { \
151 WaitPort(&me->pr_MsgPort); \
152 dp = (APTR)(GetMsg(&me->pr_MsgPort)->mn_Node.ln_Name); \
154 DOSBase = OpenLibrary("dos.library", 36); \
155 if (DOSBase == NULL || dp->dp_Res2 != 0) { \
156 PutMsg(dp->dp_Port, dp->dp_Link); \
157 return RETURN_FAIL; \
159 D(CopyMem(dp, &olddp, sizeof(olddp));) \
160 flags = dp->dp_Res1 ? CliInitNewcli(dp) : CliInitRun(dp); \
161 if (flags & FNF_VALIDFLAGS) { \
162 if ((flags & FNF_SYSTEM) && (flags & FNF_ASYNCSYSTEM)) { \
163 PutMsg(dp->dp_Port, dp->dp_Link); \
165 } else { \
166 /* CliInit*() already returned the packet for me */ \
167 if (IoErr() == (SIPTR)me) { \
168 return RETURN_ERROR; \
171 type = dp->dp_Type; \
172 me->pr_HomeDir = BNULL; \
173 segArray = BADDR(me->pr_SegList); \
174 segArray[4] = segArray[3]; \
175 segArray[3] = BNULL; \
176 segArray[0] = (BPTR)3; \
177 ret = _shell_##main(flags, type D(, &olddp)); \
178 cli = Cli(); \
179 if (flags & FNF_VALIDFLAGS) { \
180 D(bug("AROS_CLI: System Exit\n")); \
181 if (!(flags & FNF_USERINPUT)) { \
182 D(bug("AROS_CLI: Close StandardInput\n")); \
183 Close(cli->cli_StandardInput); \
184 cli->cli_StandardInput = BNULL; \
186 if ((flags & FNF_RUNOUTPUT)) { \
187 D(bug("AROS_CLI: Close StandardOutput\n")); \
188 Flush(cli->cli_StandardOutput); \
189 Close(cli->cli_StandardOutput); \
190 cli->cli_StandardOutput = BNULL; \
192 if (!((flags & FNF_SYSTEM) && (flags & FNF_ASYNCSYSTEM))) { \
193 dp->dp_Res1 = cli->cli_ReturnCode; \
194 dp->dp_Res2 = cli->cli_Result2; \
195 D(bug("AROS_CLI: Reply with %d, %d\n", dp->dp_Res1, dp->dp_Res2)); \
196 PutMsg(dp->dp_Port, dp->dp_Link); \
198 } else { \
199 D(bug("AROS_CLI: Shell Exit\n")); \
200 if (cli->cli_StandardInput != BNULL) { \
201 Close(cli->cli_StandardInput); \
202 cli->cli_StandardInput = BNULL; \
204 if (cli->cli_StandardOutput != BNULL) { \
205 /* A little bit of magic here. */ \
206 /* If this was interactive, we don't want to Flush() */ \
207 /* the StandardOutput stream. */ \
208 if (IsInteractive(cli->cli_StandardOutput)) { \
209 struct FileHandle *fh = ((struct FileHandle *)BADDR(cli->cli_StandardOutput)); \
210 fh->fh_Flags &= ~0x80000000; \
212 Close(cli->cli_StandardOutput); \
213 cli->cli_StandardOutput = BNULL; \
216 dir = CurrentDir(BNULL); \
217 if (dir) UnLock(dir); \
218 segArray[3] = segArray[4]; \
219 segArray[4] = BNULL; \
220 CloseLibrary(DOSBase); \
222 return ret; \
224 AROS_USERFUNC_EXIT \
226 SIPTR _shell_##main(ULONG AROS_CLI_Flags, LONG AROS_CLI_Type D(, struct DosPacket *AROS_CLI_DosPacket))
228 #endif /* DOS_CLIINIT_H */