secondary cache feature in vm.
[minix.git] / lib / libc / posix / _execve.c
blob4b2ec05ff80642814d15357ba449c52854679a7b
1 /* execve() - basic program execution call Author: Kees J. Bot
2 * 21 Jan 1994
3 */
5 #define _MINIX_SOURCE
7 #define execve _execve
8 #define sbrk _sbrk
9 #include <lib.h>
10 #include <unistd.h>
11 #include <string.h>
12 #include <stddef.h>
14 int execve(const char *path, char * const *argv, char * const *envp)
16 char * const *ap;
17 char * const *ep;
18 char *frame;
19 char **vp;
20 char *sp;
21 size_t argc;
22 size_t frame_size;
23 size_t string_off;
24 size_t n;
25 int ov;
26 message m;
28 /* Assumptions: size_t and char *, it's all the same thing. */
30 /* Create a stack image that only needs to be patched up slightly
31 * by the kernel to be used for the process to be executed.
34 ov= 0; /* No overflow yet. */
35 frame_size= 0; /* Size of the new initial stack. */
36 string_off= 0; /* Offset to start of the strings. */
37 argc= 0; /* Argument count. */
39 for (ap= argv; *ap != NULL; ap++) {
40 n = sizeof(*ap) + strlen(*ap) + 1;
41 frame_size+= n;
42 if (frame_size < n) ov= 1;
43 string_off+= sizeof(*ap);
44 argc++;
47 for (ep= envp; *ep != NULL; ep++) {
48 n = sizeof(*ep) + strlen(*ep) + 1;
49 frame_size+= n;
50 if (frame_size < n) ov= 1;
51 string_off+= sizeof(*ap);
54 /* Add an argument count and two terminating nulls. */
55 frame_size+= sizeof(argc) + sizeof(*ap) + sizeof(*ep);
56 string_off+= sizeof(argc) + sizeof(*ap) + sizeof(*ep);
58 /* Align. */
59 frame_size= (frame_size + sizeof(char *) - 1) & ~(sizeof(char *) - 1);
61 /* The party is off if there is an overflow. */
62 if (ov || frame_size < 3 * sizeof(char *)) {
63 errno= E2BIG;
64 return -1;
67 /* Allocate space for the stack frame. */
68 if ((frame = (char *) sbrk(frame_size)) == (char *) -1) {
69 errno = E2BIG;
70 return -1;
73 /* Set arg count, init pointers to vector and string tables. */
74 * (size_t *) frame = argc;
75 vp = (char **) (frame + sizeof(argc));
76 sp = frame + string_off;
78 /* Load the argument vector and strings. */
79 for (ap= argv; *ap != NULL; ap++) {
80 *vp++= (char *) (sp - frame);
81 n= strlen(*ap) + 1;
82 memcpy(sp, *ap, n);
83 sp+= n;
85 *vp++= NULL;
87 /* Load the environment vector and strings. */
88 for (ep= envp; *ep != NULL; ep++) {
89 *vp++= (char *) (sp - frame);
90 n= strlen(*ep) + 1;
91 memcpy(sp, *ep, n);
92 sp+= n;
94 *vp++= NULL;
96 /* Padding. */
97 while (sp < frame + frame_size) *sp++= 0;
99 /* We can finally make the system call. */
100 m.m1_i1 = strlen(path) + 1;
101 m.m1_i2 = frame_size;
102 m.m1_p1 = (char *) path;
103 m.m1_p2 = frame;
105 /* Clear unused fields */
106 m.m1_i3 = 0;
107 m.m1_p3 = NULL;
109 (void) _syscall(MM, EXEC, &m);
111 /* Failure, return the memory used for the frame and exit. */
112 (void) sbrk(-frame_size);
113 return -1;