openblt

a hobby OS from the late 90s
git clone http://frotz.net/git/openblt.git
Log | Files | Refs | LICENSE

exec.c (3324B)


      1 /* $Id: //depot/blt/lib/libposix/exec.c#1 $
      2 **
      3 ** Copyright 1999 Sidney Cammeresi
      4 ** All rights reserved.
      5 **
      6 ** Redistribution and use in source and binary forms, with or without
      7 ** modification, are permitted provided that the following conditions
      8 ** are met:
      9 ** 1. Redistributions of source code must retain the above copyright
     10 **    notice, this list of conditions, and the following disclaimer.
     11 ** 2. Redistributions in binary form must reproduce the above copyright
     12 **    notice, this list of conditions, and the following disclaimer in the
     13 **    documentation and/or other materials provided with the distribution.
     14 ** 3. The name of the author may not be used to endorse or promote products
     15 **    derived from this software without specific prior written permission.
     16 **
     17 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19 ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20 ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21 ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22 ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26 ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 */
     28 
     29 #include <string.h>
     30 #include <fcntl.h>
     31 #include <unistd.h>
     32 #include <errno.h>
     33 #include <elf.h>
     34 #include <sys/stat.h>
     35 #include <blt/syscall.h>
     36 #include <blt/libsyms.h>
     37 
     38 weak_alias (_execve, execve)
     39 
     40 int _execve (const char *path, char * const *argv, char * const *envp)
     41 {
     42 	char *ptr, *c;
     43 	char **n_argv;
     44 	int i, j, fd, area, sarea, res, size, total;
     45 	unsigned int *magic;
     46 	struct stat buf;
     47 	uint32 *stack, *top;
     48 	
     49 	res = _stat (path, &buf);
     50 	if (res)
     51 	{
     52 		errno = ENOENT;
     53 		return -1;
     54 	}
     55 	size = (buf.st_size & 0xfff) ? (buf.st_size & 0xfffff000) + 0x1000 :
     56 		buf.st_size;
     57 	fd = _open (path, O_RDONLY, 0);
     58 	if (fd < 0)
     59 	{
     60 		errno = ENOENT;
     61 		return -1;
     62 	}
     63 	area = area_create (size, 0, (void **) &ptr, 0);
     64 	res = _read (fd, ptr, size);
     65 	magic = (unsigned int *) ptr;
     66 	if (*magic != ELF_MAGIC)
     67 	{
     68 		errno = ENOEXEC;
     69 		area_destroy (area);
     70 		return -1;
     71 	}
     72 	// _close(fd);
     73 
     74 	/* compute how much stack we need for arguments */
     75 	for (i = total = 0; argv[i] != NULL; i++)
     76 		total += strlen (argv[i]) + 1;
     77 	total = (total & ~3) ? (total & ~3) + 4 : total;
     78 
     79 	/* create stack */
     80 	sarea = area_create (0x1000, 0, (void **) &stack, 0);
     81 
     82 	/* copy arguments and set up the argv array */
     83 	c = (char *) stack + 0xffc - total;
     84 	n_argv = (char **) (c - i * sizeof (char *));
     85 	for (j = 0; j < i; j++)
     86 	{
     87 		strcpy (c, argv[j]);
     88 		n_argv[j] = (char *) (0x3ff000 + ((unsigned int) c & 0xfff));
     89 		c += strlen (argv[j]) + 1;
     90 	}
     91 
     92 	/* drop argc and argv on the top */
     93 	top = (uint32 *) ((unsigned int) stack + 0x1000 - (total + (i + 3) *
     94 		sizeof (char *)));
     95 	top[0] = i;
     96 	top[1] = 0x3ff000 + (((uint32) top + 8) & 0xfff);
     97 
     98 	/* off we go */
     99 	res = thr_spawn (0x1074, 0x3ff000 + ((unsigned int) top & 0xfff) + 0x10,
    100 		area, 0x1000, sarea, 0x3ff000, argv[0]);
    101 
    102 	/* clean up */
    103 	area_destroy (area);
    104 	area_destroy (sarea);
    105 	return res;
    106 }
    107