some fixes to accented characters
[tangerine.git] / rom / dos / systemtaglist.c
blobd0040192b3a0fb1cf158491c570ed577f8502696
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 #ifdef DEBUG
10 #undef DEBUG
11 #endif
12 # define DEBUG 1
13 # include <aros/debug.h>
15 #include "dos_newcliproc.h"
16 #include "dos_intern.h"
17 #include <utility/tagitem.h>
18 #include <dos/dostags.h>
19 #include <proto/utility.h>
20 #include <dos/dosextens.h>
21 #include <aros/asmcall.h>
22 #include <exec/ports.h>
24 static BPTR DupFH(BPTR fh, LONG mode, struct DosLibrary * DOSBase);
26 /*****************************************************************************
28 NAME */
30 #include <proto/dos.h>
32 AROS_LH2(LONG, SystemTagList,
34 /* SYNOPSIS */
35 AROS_LHA(CONST_STRPTR , command, D1),
36 AROS_LHA(struct TagItem *, tags, D2),
38 /* LOCATION */
39 struct DosLibrary *, DOSBase, 101, Dos)
41 /* FUNCTION
43 Execute a command via a shell. As defaults, the process will use the
44 current Input() and Output(), and the current directory as well as the
45 path will be inherited from your process. If no path is specified, this
46 path will be used to find the command.
47 Normally, the boot shell is used but other shells may be specified
48 via tags. The tags are passed through to CreateNewProc() except those
49 who conflict with SystemTagList(). Currently, these are
51 NP_Seglist
52 NP_FreeSeglist
53 NP_Entry
54 NP_Input
55 NP_Error
56 NP_Output
57 NP_CloseInput
58 NP_CloseOutput
59 NP_CloseError
60 NP_HomeDir
61 NP_Cli
62 NP_Arguments
63 NP_Synchrounous
64 NP_UserData
67 INPUTS
69 command -- program and arguments as a string
70 tags -- see <dos/dostags.h>. Note that both SystemTagList() tags and
71 tags for CreateNewProc() may be passed.
73 RESULT
75 The return code of the command executed or -1 or if the command could
76 not run because the shell couldn't be created. If the command is not
77 found, the shell will return an error code, usually RETURN_ERROR.
79 NOTES
81 You must close the input and output filehandles yourself (if needed)
82 after System() returns if they were specified via SYS_Input or
83 SYS_Output (also, see below).
84 You may NOT use the same filehandle for both SYS_Input and SYS_Output.
85 If you want them to be the same CON: window, set SYS_Input to a filehandle
86 on the CON: window and set SYS_Output to NULL. Then the shell will
87 automatically set the output by opening CONSOLE: on that handler.
88 If you specified SYS_Asynch, both the input and the output filehandles
89 will be closed when the command is finished (even if this was your Input()
90 and Output().
92 EXAMPLE
94 BUGS
96 SEE ALSO
98 Execute(), CreateNewProc(), Input(), Output(), <dos/dostags.h>
100 INTERNALS
102 *****************************************************************************/
104 AROS_LIBFUNC_INIT
106 BPTR cis = Input(), cos = Output(), ces = Error(), script = NULL;
107 BPTR shellseg = NULL;
108 STRPTR cShell = NULL;
109 BOOL script_opened = FALSE;
110 BOOL cis_opened = FALSE;
111 BOOL cos_opened = FALSE;
112 BOOL ces_opened = FALSE;
113 BOOL isBoot = TRUE;
114 BOOL isBackground = TRUE;
115 BOOL isAsynch = FALSE;
116 LONG rc = -1;
117 LONG *cliNumPtr = NULL;
119 struct TagItem *newtags, *tags2 = tags, *tag;
121 while ((tag = NextTagItem(&tags2)))
123 switch (tag->ti_Tag)
125 case SYS_ScriptInput:
126 script = (BPTR)tag->ti_Data;
127 break;
129 case SYS_Input:
130 cis = (BPTR)tag->ti_Data;
131 break;
133 case SYS_Output:
134 cos = (BPTR)tag->ti_Data;
135 break;
137 case SYS_Error:
138 ces = (BPTR)tag->ti_Data;
139 break;
141 case SYS_CustomShell:
142 cShell = (STRPTR)tag->ti_Data;
143 break;
145 case SYS_UserShell:
146 isBoot = !tag->ti_Data;
147 break;
149 case SYS_Background:
150 isBackground = tag->ti_Data ? TRUE : FALSE;
151 break;
153 case SYS_Asynch:
154 isAsynch = tag->ti_Data ? TRUE : FALSE;
155 break;
157 case SYS_CliNumPtr:
158 cliNumPtr = (LONG *)tag->ti_Data;
159 break;
163 /* Set up the streams */
164 if (!cis)
166 cis = Open("NIL:", FMF_READ);
167 if (!cis) goto end;
169 cis_opened = TRUE;
171 else
172 if (cis == (BPTR)SYS_DupStream)
174 cis = DupFH(Input(), FMF_READ, DOSBase);
175 if (!cis) goto end;
177 cis_opened = TRUE;
180 if (!cos)
182 if (IsInteractive(cis))
183 cos = DupFH(cis, FMF_WRITE, DOSBase);
184 else
185 cos = Open("*", FMF_WRITE);
187 if (!cos) goto end;
189 cos_opened = TRUE;
191 else
192 if (cos == (BPTR)SYS_DupStream)
194 cos = DupFH(Output(), FMF_WRITE, DOSBase);
195 if (!cos) goto end;
197 cos_opened = TRUE;
200 if (!ces)
202 if (IsInteractive(cis))
203 ces = DupFH(cos, FMF_WRITE, DOSBase);
204 else
205 ces = Open("*", FMF_WRITE);
207 if (!ces) goto end;
209 ces_opened = TRUE;
211 else
212 if (ces == (BPTR)SYS_DupStream)
214 ces = DupFH(Output(), FMF_WRITE, DOSBase);
215 if (!ces) goto end;
217 ces_opened = TRUE;
220 /* Load the shell */
221 #warning implement UserShell and BootShell
222 shellseg = LoadSeg("C:Shell");
223 if (!shellseg)
224 goto end;
226 newtags = CloneTagItems(tags);
227 if (newtags)
229 struct CliStartupMessage csm;
230 struct Process *me = (struct Process *)FindTask(NULL);
231 struct Process *cliproc;
233 struct TagItem proctags[] =
235 { NP_Entry , (IPTR) NewCliProc }, /* 0 */
236 { NP_Priority , me->pr_Task.tc_Node.ln_Pri }, /* 1 */
239 Disabled, because CreateNewProc() already handles NP_StackSize,
240 i.e. it uses either AROS_STACKSIZE or the stack from the parent
241 process.
243 // { NP_StackSize , AROS_STACKSIZE },
244 { TAG_IGNORE , 0 }, /* 2 */
245 { NP_Name , isBoot ? (IPTR)"Boot Shell" :
246 isBackground ?
247 (IPTR)"Background CLI" :
248 (IPTR)"New Shell" }, /* 3 */
249 { NP_Input , (IPTR)cis }, /* 4 */
250 { NP_Output , (IPTR)cos }, /* 5 */
251 { NP_CloseInput , (isAsynch || cis_opened) }, /* 6 */
252 { NP_CloseOutput, (isAsynch || cos_opened) }, /* 7 */
253 { NP_Cli , (IPTR)TRUE }, /* 8 */
254 { NP_WindowPtr , isAsynch ? (IPTR)NULL :
255 (IPTR)me->pr_WindowPtr }, /* 9 */
256 { NP_Arguments , (IPTR)command }, /* 10 */
257 { NP_Synchronous, FALSE }, /* 11 */
258 { NP_Error , (IPTR)ces }, /* 12 */
259 { NP_CloseError , (isAsynch || ces_opened) &&
261 Since old AmigaOS programs don't know anything about Error()
262 being handled by this function, don't close the Error stream
263 if it's the same as the caller's one.
265 ces != Error() }, /* 13 */
266 { TAG_END , 0 } /* 14 */
269 Tag filterList[] =
271 NP_Seglist,
272 NP_FreeSeglist,
273 NP_Entry,
274 NP_Input,
275 NP_Output,
276 NP_CloseInput,
277 NP_CloseOutput,
278 NP_CloseError,
279 NP_HomeDir,
280 NP_Cli,
284 FilterTagItems(newtags, filterList, TAGFILTER_NOT);
286 proctags[sizeof(proctags)/(sizeof(proctags[0])) - 1].ti_Tag = TAG_MORE;
287 proctags[sizeof(proctags)/(sizeof(proctags[0])) - 1].ti_Data = (IPTR)newtags;
289 cliproc = CreateNewProc(proctags);
291 if (cliproc)
293 csm.csm_Msg.mn_Node.ln_Type = NT_MESSAGE;
294 csm.csm_Msg.mn_Length = sizeof(csm);
295 csm.csm_Msg.mn_ReplyPort = &me->pr_MsgPort;
297 csm.csm_CurrentInput = script;
298 csm.csm_ShellSeg = shellseg;
299 csm.csm_Background = isBackground;
300 csm.csm_Asynch = isAsynch;
302 PutMsg(&cliproc->pr_MsgPort, (struct Message *)&csm);
303 WaitPort(&me->pr_MsgPort);
304 GetMsg(&me->pr_MsgPort);
306 if (cliNumPtr) *cliNumPtr = csm.csm_CliNumber;
308 rc = csm.csm_ReturnCode;
310 script_opened =
311 cis_opened =
312 cos_opened =
313 ces_opened = FALSE;
315 shellseg = NULL;
317 FreeTagItems(newtags);
320 end:
321 UnLoadSeg(shellseg);
322 if (script_opened) Close(script);
323 if (cis_opened) Close(cis);
324 if (cos_opened) Close(cos);
325 if (ces_opened) Close(ces);
327 return rc;
329 AROS_LIBFUNC_EXIT
330 } /* SystemTagList */
332 static BPTR DupFH(BPTR fh, LONG mode, struct DosLibrary * DOSBase)
334 BPTR ret = NULL;
336 if (fh)
338 BPTR olddir = CurrentDir(fh);
339 ret = Open("", mode);
341 CurrentDir(olddir);
344 return ret;