2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
5 Desc: Execute a loaded command synchronously
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 /*****************************************************************************
23 #include <proto/dos.h>
25 AROS_LH4(LONG
, RunCommand
,
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
),
34 struct DosLibrary
*, DOSBase
, 84, Dos
)
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.
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.
52 The return code from the program. See also IoErr().
55 Programs expect the argument string to end with a newline ('\n')
56 character (ReadArgs() requires it to work properly).
67 *****************************************************************************/
72 volatile APTR oldReturnAddr
;
74 /* Get pointer to process structure */
75 struct Process
*me
=(struct Process
*)FindTask(NULL
);
79 struct StackSwapStruct sss
;
80 struct StackSwapArgs args
;
83 ASSERT_VALID_PROCESS(me
);
85 if(stacksize
< AROS_STACKSIZE
)
86 stacksize
= AROS_STACKSIZE
;
88 stack
=(UBYTE
*)AllocMem(stacksize
,MEMF_ANY
);
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()) {
143 FreeMem(stack
,stacksize
);