Added AROS port of all shell applications:
[cake.git] / rom / dos / runprocess.c
blob1abd0b558318804fb46d18f1b91dc79c9cab18af
1 /*
2 Copyright © 1995-2008, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: RunProcess() - Run a process from an entry point with args
6 Lang: english
7 */
8 #include <aros/asmcall.h> /* LONG_FUNC */
9 #ifndef TEST
10 # include <dos/dosextens.h>
11 # include <proto/exec.h>
12 # include <aros/debug.h>
13 #else
14 # include <exec/types.h>
15 # include <exec/tasks.h>
16 # define D(x) /* eps */
18 struct Process;
20 struct DosLibrary
22 struct ExecBase * dl_SysBase;
25 extern void StackSwap (struct StackSwapStruct *, struct ExecBase *);
27 #define StackSwap(s) StackSwap(s, SysBase)
28 #define AROS_SLIB_ENTRY(a,b) a
30 #endif /* TEST */
32 #include <string.h>
35 /**************************************************************************
37 NAME */
38 LONG AROS_SLIB_ENTRY(RunProcess,Dos) (
40 /* SYNOPSIS */
41 struct Process * proc,
42 struct StackSwapStruct * sss,
43 CONST_STRPTR argptr,
44 ULONG argsize,
45 LONG_FUNC entry,
46 struct DosLibrary * DOSBase)
48 /* FUNCTION
49 Sets the stack as specified and calls the routine with the given
50 arguments.
52 INPUTS
53 proc - Process context
54 sss - New Stack
55 argptr - Pointer to argument string
56 argsize - Size of the argument string
57 entry - The entry point of the function
58 DOSBase - Pointer to dos.library structure
60 RESULT
61 The return value of (*entry)();
63 NOTES
65 EXAMPLE
67 BUGS
69 SEE ALSO
71 INTERNALS
73 **************************************************************************/
75 APTR * oldSP;
76 APTR * sp;
77 ULONG * retptr;
78 ULONG ret;
79 APTR oldReturnAddr;
81 retptr = &ret;
83 sp = (APTR *)(sss->stk_Upper);
84 oldSP = (APTR *)&DOSBase;
85 oldReturnAddr = proc->pr_ReturnAddr;
87 /* Compute argsize automatically */
88 if (argsize == -1)
90 argsize = strlen(argptr);
93 /* Copy stack + locals + regs + everything */
94 while ( oldSP != (APTR *)&ret )
96 *--sp = *oldSP--;
99 sss->stk_Pointer = sp;
101 D(bug("In RunProcess() entry=%lx, *entry=%lx\n", (IPTR)entry, (IPTR)*entry));
102 StackSwap(sss);
104 /* Call the function with the new stack */
106 We have to set the pr_ReturnAddr pointer to the correct value
107 before we call the entry() otherwise some startup code will
108 not work.
110 This can be done rather more easily on the m68k than elsewhere.
112 #ifndef AROS_UFC3R
113 #error You need to write the AROS_UFC3R macro for your CPU
114 #endif
116 /* The AROS_UFC3R() macro doesn't work on my system (gcc 2.95.1, Linux 2.3.50)
117 * this is the workaround I'm currently using:
120 // *retptr = entry(argptr,argsize,SysBase);
122 *retptr = AROS_UFC3R(ULONG, entry,
123 AROS_UFCA(CONST_STRPTR, argptr, A0),
124 AROS_UFCA(ULONG, argsize, D0),
125 AROS_UFCA(struct ExecBase *, SysBase, A6),
126 &proc->pr_ReturnAddr, (sss->stk_Upper - (ULONG)sss->stk_Lower)
129 StackSwap(sss);
131 proc->pr_ReturnAddr = oldReturnAddr;
133 return ret;
136 #ifdef TEST
138 #include <stdio.h>
140 ULONG teststack[4096];
142 int DemoProc (const char * argstr, int argsize, struct ExecBase * SysBase)
144 printf ("arg=\"%s\" (len=%d\n", argstr, argsize);
146 return argsize;
147 } /* DemoProc */
149 int main (int argc, char ** argv)
151 int ret, len;
152 char * argstr;
153 struct StackSwapStruct sss;
154 struct DosLibrary DosBase;
156 sss.stk_Lower = teststack;
157 sss.stk_Upper = &teststack[sizeof(teststack) / sizeof(teststack[0])];
158 sss.stk_Pointer = sss.stk_Upper;
160 DosBase.dl_SysBase = (struct ExecBase *)0x0bad0bad;
162 printf ("Stack=%p\n", &ret);
164 argstr = "Hello world.";
166 len = strlen (argstr);
168 ret = RunProcess (NULL,
169 &sss,
170 argstr,
171 len,
172 (LONG_FUNC)DemoProc,
173 &DOSBase
176 printf ("Stack=%p\n", &ret);
177 printf ("RunProcess=%d\n",ret);
179 if (len == ret)
181 printf("Test ok.\n");
183 else
185 printf("Test failed.\n");
188 return 0;
191 #endif /* TEST */