00001
00002
00003
00004
00005 #define _MINIX_SOURCE
00006
00007 #define nil 0
00008 #define execve _execve
00009 #define sbrk _sbrk
00010 #include <lib.h>
00011 #include <unistd.h>
00012 #include <string.h>
00013 #include <stddef.h>
00014
00015 int execve(const char *path, char * const *argv, char * const *envp)
00016 {
00017 char * const *ap;
00018 char * const *ep;
00019 char *frame;
00020 char **vp;
00021 char *sp;
00022 size_t argc;
00023 size_t frame_size;
00024 size_t string_off;
00025 size_t n;
00026 int ov;
00027 message m;
00028
00029
00030
00031
00032
00033
00034
00035 ov= 0;
00036 frame_size= 0;
00037 string_off= 0;
00038 argc= 0;
00039
00040 for (ap= argv; *ap != nil; ap++) {
00041 n = sizeof(*ap) + strlen(*ap) + 1;
00042 frame_size+= n;
00043 if (frame_size < n) ov= 1;
00044 string_off+= sizeof(*ap);
00045 argc++;
00046 }
00047
00048 for (ep= envp; *ep != nil; ep++) {
00049 n = sizeof(*ep) + strlen(*ep) + 1;
00050 frame_size+= n;
00051 if (frame_size < n) ov= 1;
00052 string_off+= sizeof(*ap);
00053 }
00054
00055
00056 frame_size+= sizeof(argc) + sizeof(*ap) + sizeof(*ep);
00057 string_off+= sizeof(argc) + sizeof(*ap) + sizeof(*ep);
00058
00059
00060 frame_size= (frame_size + sizeof(char *) - 1) & ~(sizeof(char *) - 1);
00061
00062
00063 if (ov || frame_size < 3 * sizeof(char *)) {
00064 errno= E2BIG;
00065 return -1;
00066 }
00067
00068
00069 if ((frame = (char *) sbrk(frame_size)) == (char *) -1) {
00070 errno = E2BIG;
00071 return -1;
00072 }
00073
00074
00075 * (size_t *) frame = argc;
00076 vp = (char **) (frame + sizeof(argc));
00077 sp = frame + string_off;
00078
00079
00080 for (ap= argv; *ap != nil; ap++) {
00081 *vp++= (char *) (sp - frame);
00082 n= strlen(*ap) + 1;
00083 memcpy(sp, *ap, n);
00084 sp+= n;
00085 }
00086 *vp++= nil;
00087
00088
00089 for (ep= envp; *ep != nil; ep++) {
00090 *vp++= (char *) (sp - frame);
00091 n= strlen(*ep) + 1;
00092 memcpy(sp, *ep, n);
00093 sp+= n;
00094 }
00095 *vp++= nil;
00096
00097
00098 while (sp < frame + frame_size) *sp++= 0;
00099
00100
00101 m.m1_i1 = strlen(path) + 1;
00102 m.m1_i2 = frame_size;
00103 m.m1_p1 = (char *) path;
00104 m.m1_p2 = frame;
00105
00106
00107 m.m1_i3 = 0;
00108 m.m1_p3 = NULL;
00109
00110 (void) _syscall(MM, EXEC, &m);
00111
00112
00113 (void) sbrk(-frame_size);
00114 return -1;
00115 }