Detabbed
[AROS.git] / rom / dos / runcommand.c
blobde119fb9c2df7e676a155504803e5b81dd51ab49
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Execute a loaded command synchronously
6 Lang: english
7 */
9 #define DEBUG 0
10 #include <aros/debug.h>
12 #include <exec/memory.h>
13 #include <proto/exec.h>
14 #include <utility/tagitem.h>
15 #include <proto/dos.h>
16 #include <dos/stdio.h>
18 #include "dos_intern.h"
20 /*****************************************************************************
22 NAME */
23 #include <proto/dos.h>
25 AROS_LH4(LONG, RunCommand,
27 /* SYNOPSIS */
28 AROS_LHA(BPTR, segList, D1),
29 AROS_LHA(ULONG, stacksize, D2),
30 AROS_LHA(CONST_STRPTR, argptr, D3),
31 AROS_LHA(ULONG, argsize, D4),
33 /* LOCATION */
34 struct DosLibrary *, DOSBase, 84, Dos)
36 /* FUNCTION
37 RunCommand() will run the command loaded in the |segList| with the
38 arguments specified with a new stack of |stacksize| bytes. Note
39 that the stacksize may be extended if this is required.
41 The return code of the command run will be returned.
43 This call will not return until the command has completed.
45 INPUTS
46 segList - segment of program to run.
47 stacksize - size of the stack to use.
48 argptr - pointer to NULL-terminated arguments.
49 argsize - size of the arguments string.
51 RESULT
52 The return code from the program. See also IoErr().
54 NOTES
55 Programs expect the argument string to end with a newline ('\n')
56 character (ReadArgs() requires it to work properly).
58 EXAMPLE
60 BUGS
62 SEE ALSO
63 SystemTagList()
65 INTERNALS
67 *****************************************************************************/
69 AROS_LIBFUNC_INIT
71 STRPTR oldargs;
72 volatile APTR oldReturnAddr;
74 /* Get pointer to process structure */
75 struct Process *me=(struct Process *)FindTask(NULL);
77 UBYTE *stack;
78 LONG ret;
79 struct StackSwapStruct sss;
80 struct StackSwapArgs args;
81 D(BOOL injected;)
83 ASSERT_VALID_PROCESS(me);
85 if(stacksize < AROS_STACKSIZE)
86 stacksize = AROS_STACKSIZE;
88 stack=(UBYTE *)AllocMem(stacksize,MEMF_ANY);
89 if(stack==NULL)
90 return -1;
92 sss.stk_Lower=stack;
93 sss.stk_Upper=stack+stacksize;
94 sss.stk_Pointer = sss.stk_Upper;
96 oldargs=me->pr_Arguments;
97 me->pr_Arguments=(STRPTR)argptr;
100 * Inject command arguments to the beginning of input handle. Guru Book mentions this.
101 * This fixes for example AmigaOS' C:Execute
103 D(bug("RunCommand: segList @%p I=0x%p O=%p Args='%*s' Argsize=%u\n", BADDR(segList), Input(), Output(), argsize, argptr, argsize));
104 D(injected = ) vbuf_inject(Input(), argptr, argsize, DOSBase);
105 D(bug("RunCommand: Arguments %sinjected into FileHandle %p\n", injected ? "" : "not ", Input()));
107 /* pr_ReturnAddr is set by CallEntry routine */
108 oldReturnAddr = me->pr_ReturnAddr;
110 args.Args[0] = (IPTR)argptr;
111 args.Args[1] = argsize;
112 args.Args[2] = (IPTR)BADDR(segList) + sizeof(BPTR);
113 args.Args[3] = (IPTR)me;
115 APTR tsid = SaveTaskStorage();
116 D(bug("RunCommand: b4 StackSwap() tsid=%x, thistask->TaskStorage=%x\n",
117 tsid, FindTask(NULL)->tc_UnionETask.tc_ETask->et_TaskStorage
120 ret = NewStackSwap(&sss, CallEntry, &args);
122 D(bug("RunCommand: after StackSwap() tsid=%x, thistask->TaskStorage=%x\n",
123 tsid, FindTask(NULL)->tc_UnionETask.tc_ETask->et_TaskStorage
126 RestoreTaskStorage(tsid);
128 D(bug("RunCommand: after RestoreTaskStorage() tsid=%x, thistask->TaskStorage=%x\n",
129 tsid, FindTask(NULL)->tc_UnionETask.tc_ETask->et_TaskStorage
132 me->pr_ReturnAddr = oldReturnAddr;
133 me->pr_Arguments = oldargs;
135 /* Flush the current CLI input stream
136 * NOTE: AmigaOS 3.1's C:Execute closes Input(),
137 * so we need to catch that here.
139 if (Cli() && Cli()->cli_CurrentInput == Input()) {
140 Flush(Input());
143 FreeMem(stack,stacksize);
145 return ret;
147 AROS_LIBFUNC_EXIT
149 } /* RunCommand */