. pci driver now returns devices, even when they have been pci_reserve()d
[minix3.git] / lib / posix / _execve.c
blob3a5b6c1069921beedf70d8d6dc588b290ec7eac1
1 /* execve() - basic program execution call Author: Kees J. Bot
2 * 21 Jan 1994
3 */
5 #define _MINIX_SOURCE
7 #define nil 0
8 #define execve _execve
9 #define sbrk _sbrk
10 #include <lib.h>
11 #include <unistd.h>
12 #include <string.h>
13 #include <stddef.h>
15 int execve(const char *path, char * const *argv, char * const *envp)
17 char * const *ap;
18 char * const *ep;
19 char *frame;
20 char **vp;
21 char *sp;
22 size_t argc;
23 size_t frame_size;
24 size_t string_off;
25 size_t n;
26 int ov;
27 message m;
29 /* Assumptions: size_t and char *, it's all the same thing. */
31 /* Create a stack image that only needs to be patched up slightly
32 * by the kernel to be used for the process to be executed.
35 ov= 0; /* No overflow yet. */
36 frame_size= 0; /* Size of the new initial stack. */
37 string_off= 0; /* Offset to start of the strings. */
38 argc= 0; /* Argument count. */
40 for (ap= argv; *ap != nil; ap++) {
41 n = sizeof(*ap) + strlen(*ap) + 1;
42 frame_size+= n;
43 if (frame_size < n) ov= 1;
44 string_off+= sizeof(*ap);
45 argc++;
48 for (ep= envp; *ep != nil; ep++) {
49 n = sizeof(*ep) + strlen(*ep) + 1;
50 frame_size+= n;
51 if (frame_size < n) ov= 1;
52 string_off+= sizeof(*ap);
55 /* Add an argument count and two terminating nulls. */
56 frame_size+= sizeof(argc) + sizeof(*ap) + sizeof(*ep);
57 string_off+= sizeof(argc) + sizeof(*ap) + sizeof(*ep);
59 /* Align. */
60 frame_size= (frame_size + sizeof(char *) - 1) & ~(sizeof(char *) - 1);
62 /* The party is off if there is an overflow. */
63 if (ov || frame_size < 3 * sizeof(char *)) {
64 errno= E2BIG;
65 return -1;
68 /* Allocate space for the stack frame. */
69 if ((frame = (char *) sbrk(frame_size)) == (char *) -1) {
70 errno = E2BIG;
71 return -1;
74 /* Set arg count, init pointers to vector and string tables. */
75 * (size_t *) frame = argc;
76 vp = (char **) (frame + sizeof(argc));
77 sp = frame + string_off;
79 /* Load the argument vector and strings. */
80 for (ap= argv; *ap != nil; ap++) {
81 *vp++= (char *) (sp - frame);
82 n= strlen(*ap) + 1;
83 memcpy(sp, *ap, n);
84 sp+= n;
86 *vp++= nil;
88 /* Load the environment vector and strings. */
89 for (ep= envp; *ep != nil; ep++) {
90 *vp++= (char *) (sp - frame);
91 n= strlen(*ep) + 1;
92 memcpy(sp, *ep, n);
93 sp+= n;
95 *vp++= nil;
97 /* Padding. */
98 while (sp < frame + frame_size) *sp++= 0;
100 /* We can finally make the system call. */
101 m.m1_i1 = strlen(path) + 1;
102 m.m1_i2 = frame_size;
103 m.m1_p1 = (char *) path;
104 m.m1_p2 = frame;
106 /* Clear unused fields */
107 m.m1_i3 = 0;
108 m.m1_p3 = NULL;
110 (void) _syscall(MM, EXEC, &m);
112 /* Failure, return the memory used for the frame and exit. */
113 (void) sbrk(-frame_size);
114 return -1;