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