source: trunk/minix/lib/posix/_execve.c@ 15

Last change on this file since 15 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 2.6 KB
Line 
1/* execve() - basic program execution call Author: Kees J. Bot
2 * 21 Jan 1994
3 */
4
5#define _MINIX_SOURCE
6
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>
14
15int execve(const char *path, char * const *argv, char * const *envp)
16{
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;
28
29 /* Assumptions: size_t and char *, it's all the same thing. */
30
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.
33 */
34
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. */
39
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++;
46 }
47
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);
53 }
54
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);
58
59 /* Align. */
60 frame_size= (frame_size + sizeof(char *) - 1) & ~(sizeof(char *) - 1);
61
62 /* The party is off if there is an overflow. */
63 if (ov || frame_size < 3 * sizeof(char *)) {
64 errno= E2BIG;
65 return -1;
66 }
67
68 /* Allocate space for the stack frame. */
69 if ((frame = (char *) sbrk(frame_size)) == (char *) -1) {
70 errno = E2BIG;
71 return -1;
72 }
73
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;
78
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;
85 }
86 *vp++= nil;
87
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;
94 }
95 *vp++= nil;
96
97 /* Padding. */
98 while (sp < frame + frame_size) *sp++= 0;
99
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;
105
106 /* Clear unused fields */
107 m.m1_i3 = 0;
108 m.m1_p3 = NULL;
109
110 (void) _syscall(MM, EXEC, &m);
111
112 /* Failure, return the memory used for the frame and exit. */
113 (void) sbrk(-frame_size);
114 return -1;
115}
Note: See TracBrowser for help on using the repository browser.