delint
[AROS.git] / rom / dos / runcommand.c
blob4603673fbb832575b82ff856a77421058bc449ac
1 /*
2 Copyright © 1995-2015, 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, or -1 if the command could not be
53 started (e.g. no memory for the stack). See also IoErr().
55 NOTES
56 Programs expect the argument string to end with a newline ('\n')
57 character (ReadArgs() requires it to work properly).
59 EXAMPLE
61 BUGS
63 SEE ALSO
64 SystemTagList()
66 INTERNALS
68 *****************************************************************************/
70 AROS_LIBFUNC_INIT
72 STRPTR oldargs;
73 volatile APTR oldReturnAddr;
75 /* Get pointer to process structure */
76 struct Process *me=(struct Process *)FindTask(NULL);
78 UBYTE *stack;
79 LONG ret;
80 struct StackSwapStruct sss;
81 struct StackSwapArgs args;
82 D(BOOL injected;)
84 ASSERT_VALID_PROCESS(me);
86 if(stacksize < AROS_STACKSIZE)
87 stacksize = AROS_STACKSIZE;
89 stack=(UBYTE *)AllocMem(stacksize,MEMF_ANY);
90 if(stack==NULL)
91 return -1;
93 sss.stk_Lower=stack;
94 sss.stk_Upper=stack+stacksize;
95 sss.stk_Pointer = sss.stk_Upper;
97 oldargs=me->pr_Arguments;
98 me->pr_Arguments=(STRPTR)argptr;
101 * Inject command arguments to the beginning of input handle. Guru Book mentions this.
102 * This fixes for example AmigaOS' C:Execute
104 D(bug("RunCommand: segList @%p I=0x%p O=%p Args='%*s' Argsize=%u\n", BADDR(segList), Input(), Output(), argsize, argptr, argsize));
105 D(injected = ) vbuf_inject(Input(), argptr, argsize, DOSBase);
106 D(bug("RunCommand: Arguments %sinjected into FileHandle %p\n", injected ? "" : "not ", Input()));
108 /* pr_ReturnAddr is set by CallEntry routine */
109 oldReturnAddr = me->pr_ReturnAddr;
111 args.Args[0] = (IPTR)argptr;
112 args.Args[1] = argsize;
113 args.Args[2] = (IPTR)BADDR(segList) + sizeof(BPTR);
114 args.Args[3] = (IPTR)me;
116 APTR tsid = SaveTaskStorage();
117 D(bug("RunCommand: b4 StackSwap() tsid=%x, thistask->TaskStorage=%x\n",
118 tsid, FindTask(NULL)->tc_UnionETask.tc_ETask->et_TaskStorage
121 ret = NewStackSwap(&sss, CallEntry, &args);
123 D(bug("RunCommand: after StackSwap() tsid=%x, thistask->TaskStorage=%x\n",
124 tsid, FindTask(NULL)->tc_UnionETask.tc_ETask->et_TaskStorage
127 RestoreTaskStorage(tsid);
129 D(bug("RunCommand: after RestoreTaskStorage() tsid=%x, thistask->TaskStorage=%x\n",
130 tsid, FindTask(NULL)->tc_UnionETask.tc_ETask->et_TaskStorage
133 me->pr_ReturnAddr = oldReturnAddr;
134 me->pr_Arguments = oldargs;
136 /* Flush the current CLI input stream
137 * NOTE: AmigaOS 3.1's C:Execute closes Input(),
138 * so we need to catch that here.
140 if (Cli() && Cli()->cli_CurrentInput == Input()) {
141 Flush(Input());
144 FreeMem(stack,stacksize);
146 return ret;
148 AROS_LIBFUNC_EXIT
150 } /* RunCommand */