2 Copyright © 1995-2015, 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, or -1 if the command could not be
53 started (e.g. no memory for the stack). See also IoErr().
56 Programs expect the argument string to end with a newline ('\n')
57 character (ReadArgs() requires it to work properly).
68 *****************************************************************************/
73 volatile APTR oldReturnAddr
;
75 /* Get pointer to process structure */
76 struct Process
*me
=(struct Process
*)FindTask(NULL
);
80 struct StackSwapStruct sss
;
81 struct StackSwapArgs args
;
84 ASSERT_VALID_PROCESS(me
);
86 if(stacksize
< AROS_STACKSIZE
)
87 stacksize
= AROS_STACKSIZE
;
89 stack
=(UBYTE
*)AllocMem(stacksize
,MEMF_ANY
);
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()) {
144 FreeMem(stack
,stacksize
);