1 /* execve() - basic program execution call Author: Kees J. Bot
15 int execve(const char *path
, char * const *argv
, char * const *envp
)
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;
43 if (frame_size
< n
) ov
= 1;
44 string_off
+= sizeof(*ap
);
48 for (ep
= envp
; *ep
!= nil
; ep
++) {
49 n
= sizeof(*ep
) + strlen(*ep
) + 1;
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
);
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 *)) {
68 /* Allocate space for the stack frame. */
69 if ((frame
= (char *) sbrk(frame_size
)) == (char *) -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
);
88 /* Load the environment vector and strings. */
89 for (ep
= envp
; *ep
!= nil
; ep
++) {
90 *vp
++= (char *) (sp
- frame
);
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
;
106 /* Clear unused fields */
110 (void) _syscall(MM
, EXEC
, &m
);
112 /* Failure, return the memory used for the frame and exit. */
113 (void) sbrk(-frame_size
);