summaryrefslogtreecommitdiff
path: root/libc-0.0.4/syscall/execve.c
blob: aee7182c96a4745de0a0aaa872081cb0f3d3fd88 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

#include <errno.h>

extern char ** environ;

#ifdef L_execl
int
execl(fname, arg0)
char * fname, *arg0;
{
   return execve(fname, &arg0, environ);
}
#endif

#ifdef L_execv
int
execv(fname, argv)
char * fname, **argv;
{
   return execve(fname, argv, environ);
}
#endif

#ifdef L_execle
int
execle(fname, arg0)
char *fname, *arg0;
{
   char ** envp = &arg0;
   while(*envp) envp++;
   return execve(fname, &arg0, envp+1);
}
#endif

#ifdef L_execve
int
execve(fname, argv, envp)
char * fname;
char ** argv;
char ** envp;
{
	char **p;
	int argv_len=0, argv_count=0;
	int envp_len=0, envp_count=0;
	int stack_bytes;
	unsigned short * pip;
	char * pcp, * stk_ptr, *baseoff;
	int rv;

	/* How much space for argv */
	for(p=argv; p && *p && argv_len >= 0; p++)
	{
	   argv_count++; argv_len += strlen(*p)+1;
	}

	/* How much space for envp */
	for(p=envp; p && *p && envp_len >= 0; p++)
	{
	   envp_count++; envp_len += strlen(*p)+1;
	}

	/* tot it all up */
	stack_bytes = 2				/* argc */
	            + argv_count * 2 + 2	/* argv */
		    + argv_len
		    + envp_count * 2 + 2	/* envp */
		    + envp_len;

	/* Allocate it */
	if( argv_len < 0 || envp_len < 0 || stack_bytes <= 0
	 || (int)(stk_ptr = (char*)sbrk(stack_bytes)) == -1)
	{
	   errno = ENOMEM;
	   return -1;
	}

/* Sanity check 
	printf("Argv = (%d,%d), Envp=(%d,%d), stack=%d\n",
	        argv_count, argv_len, envp_count, envp_len, stack_bytes);
*/

	/* Now copy in the strings */
	pip=(unsigned short *) stk_ptr;
	pcp=stk_ptr+2*(1+argv_count+1+envp_count+1);

	/* baseoff = stk_ptr + stack_bytes; */
	baseoff = stk_ptr;
	*pip++ = argv_count;
	for(p=argv; p && *p; p++)
	{
	   int l;
	   *pip++ = pcp-baseoff;
	   l = strlen(*p)+1;
	   memcpy(pcp, *p, l);
	   pcp += l;
	}
	*pip++ = 0;

	for(p=envp; p && *p; p++)
	{
	   int l;
	   *pip++ = pcp-baseoff;
	   l = strlen(*p)+1;
	   memcpy(pcp, *p, l);
	   pcp += l;
	}
	*pip++ = 0;

	rv = __exec(fname, stk_ptr, stack_bytes);
	/* FIXME: This will probably have to interpret '#!' style exe's */
	sbrk(-stack_bytes);
	return rv;
}
#endif