_execve.c

Go to the documentation of this file.
00001 /*      execve() - basic program execution call         Author: Kees J. Bot
00002  *                                                              21 Jan 1994
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         /* Assumptions: size_t and char *, it's all the same thing. */
00030 
00031         /* Create a stack image that only needs to be patched up slightly
00032          * by the kernel to be used for the process to be executed.
00033          */
00034 
00035         ov= 0;                  /* No overflow yet. */
00036         frame_size= 0;          /* Size of the new initial stack. */
00037         string_off= 0;          /* Offset to start of the strings. */
00038         argc= 0;                /* Argument count. */
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         /* Add an argument count and two terminating nulls. */
00056         frame_size+= sizeof(argc) + sizeof(*ap) + sizeof(*ep);
00057         string_off+= sizeof(argc) + sizeof(*ap) + sizeof(*ep);
00058 
00059         /* Align. */
00060         frame_size= (frame_size + sizeof(char *) - 1) & ~(sizeof(char *) - 1);
00061 
00062         /* The party is off if there is an overflow. */
00063         if (ov || frame_size < 3 * sizeof(char *)) {
00064                 errno= E2BIG;
00065                 return -1;
00066         }
00067 
00068         /* Allocate space for the stack frame. */
00069         if ((frame = (char *) sbrk(frame_size)) == (char *) -1) {
00070                 errno = E2BIG;
00071                 return -1;
00072         }
00073 
00074         /* Set arg count, init pointers to vector and string tables. */
00075         * (size_t *) frame = argc;
00076         vp = (char **) (frame + sizeof(argc));
00077         sp = frame + string_off;
00078 
00079         /* Load the argument vector and strings. */
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         /* Load the environment vector and strings. */
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         /* Padding. */
00098         while (sp < frame + frame_size) *sp++= 0;
00099 
00100         /* We can finally make the system call. */
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         /* Clear unused fields */
00107         m.m1_i3 = 0;
00108         m.m1_p3 = NULL;
00109 
00110         (void) _syscall(MM, EXEC, &m);
00111 
00112         /* Failure, return the memory used for the frame and exit. */
00113         (void) sbrk(-frame_size);
00114         return -1;
00115 }

Generated on Fri Apr 14 22:57:27 2006 for minix by  doxygen 1.4.6