Example #1
0
/*
 * Allocate the stack, and build the argument list.
 */
static void
build_args_and_stack(struct exec_info *boot_exec_info,
		     char **argv, char **envp)
{
	vm_offset_t	stack_base;
	vm_size_t	stack_size;
	char *		arg_ptr;
	int		arg_count, envc;
	int		arg_len;
	char *		arg_pos;
	int		arg_item_len;
	char *		string_pos;
	char *		zero = (char *)0;
	int i;

#define	STACK_SIZE	(64*1024)

	/*
	 * Calculate the size of the argument list.
	 */
	arg_len = 0;
	arg_count = 0;
	while (argv[arg_count] != 0) {
	    arg_ptr = argv[arg_count++];
	    arg_len += strlen(arg_ptr) + 1;
	}
	envc = 0;
	if (envp != 0)
	  while (envp[envc] != 0)
	    arg_len += strlen (envp[envc++]) + 1;

	/*
	 * Add space for:
	 *	arg count
	 *	pointers to arguments
	 *	trailing 0 pointer
	 *	pointers to environment variables
	 *	trailing 0 pointer
	 *	and align to integer boundary
	 */
	arg_len += (sizeof(integer_t)
		    + (arg_count + 1 + envc + 1) * sizeof(char *));
	arg_len = (arg_len + sizeof(integer_t) - 1) & ~(sizeof(integer_t)-1);

	/*
	 * Allocate the stack.
	 */
	stack_size = round_page(STACK_SIZE);
	stack_base = user_stack_low(stack_size);
	(void) vm_allocate(current_task()->map,
			&stack_base,
			stack_size,
			FALSE);

	arg_pos = (char *)
		set_user_regs(stack_base, stack_size, boot_exec_info, arg_len);

	/*
	 * Start the strings after the arg-count and pointers
	 */
	string_pos = (arg_pos
		      + sizeof(integer_t)
		      + (arg_count + 1 + envc + 1) * sizeof(char *));

	/*
	 * first the argument count
	 */
	(void) copyout(&arg_count,
			arg_pos,
			sizeof(integer_t));
	arg_pos += sizeof(integer_t);

	/*
	 * Then the strings and string pointers for each argument
	 */
	for (i = 0; i < arg_count; ++i) {
	    arg_ptr = argv[i];
	    arg_item_len = strlen(arg_ptr) + 1; /* include trailing 0 */

	    /* set string pointer */
	    (void) copyout(&string_pos,
			arg_pos,
			sizeof (char *));
	    arg_pos += sizeof(char *);

	    /* copy string */
	    (void) copyout(arg_ptr, string_pos, arg_item_len);
	    string_pos += arg_item_len;
	}

	/*
	 * Null terminator for argv.
	 */
	(void) copyout(&zero, arg_pos, sizeof(char *));
	arg_pos += sizeof(char *);

	/*
	 * Then the strings and string pointers for each environment variable
	 */
	for (i = 0; i < envc; ++i) {
	    arg_ptr = envp[i];
	    arg_item_len = strlen(arg_ptr) + 1; /* include trailing 0 */

	    /* set string pointer */
	    (void) copyout(&string_pos,
			arg_pos,
			sizeof (char *));
	    arg_pos += sizeof(char *);

	    /* copy string */
	    (void) copyout(arg_ptr, string_pos, arg_item_len);
	    string_pos += arg_item_len;
	}

	/*
	 * Null terminator for envp.
	 */
	(void) copyout(&zero, arg_pos, sizeof(char *));
}
Example #2
0
void
static build_args_and_stack(struct exec_info *boot_exec_info, ...)
{
	vm_offset_t	stack_base;
	vm_size_t	stack_size;
	va_list		argv_ptr;
	register
	char *		arg_ptr;
	int		arg_len;
	int		arg_count;
	register
	char *		arg_pos;
	int		arg_item_len;
	char *		string_pos;
	char *		zero = (char *)0;

#define	STACK_SIZE	(64*1024)

	/*
	 * Calculate the size of the argument list.
	 */
	va_start(argv_ptr, boot_exec_info);
	arg_len = 0;
	arg_count = 0;
	for (;;) {
	    arg_ptr = va_arg(argv_ptr, char *);
	    if (arg_ptr == 0)
		break;
	    arg_count++;
	    arg_len += strlen(arg_ptr) + 1;
	}
	va_end(argv_ptr);

	/*
	 * Add space for:
	 *	arg count
	 *	pointers to arguments
	 *	trailing 0 pointer
	 *	dummy 0 pointer to environment variables
	 *	and align to integer boundary
	 */
	arg_len += sizeof(integer_t)
		 + (2 + arg_count) * sizeof(char *);
	arg_len = (arg_len + sizeof(integer_t) - 1) & ~(sizeof(integer_t)-1);

	/*
	 * Allocate the stack.
	 */
	stack_size = round_page(STACK_SIZE);
	stack_base = user_stack_low(stack_size);
	(void) vm_allocate(current_task()->map,
			&stack_base,
			stack_size,
			FALSE);

	arg_pos = (char *)
		set_user_regs(stack_base, stack_size, boot_exec_info, arg_len);

	/*
	 * Start the strings after the arg-count and pointers
	 */
	string_pos = arg_pos
		+ sizeof(integer_t)
		+ arg_count * sizeof(char *)
		+ 2 * sizeof(char *);

	/*
	 * first the argument count
	 */
	(void) copyout((char *)&arg_count,
			arg_pos,
			sizeof(integer_t));
	arg_pos += sizeof(integer_t);

	/*
	 * Then the strings and string pointers for each argument
	 */
	va_start(argv_ptr, boot_exec_info);
	while (--arg_count >= 0) {
	    arg_ptr = va_arg(argv_ptr, char *);
	    arg_item_len = strlen(arg_ptr) + 1; /* include trailing 0 */

	    /* set string pointer */
	    (void) copyout((char *)&string_pos,
			arg_pos,
			sizeof (char *));
	    arg_pos += sizeof(char *);

	    /* copy string */
	    (void) copyout(arg_ptr, string_pos, arg_item_len);
	    string_pos += arg_item_len;
	}
	va_end(argv_ptr);

	/*
	 * last, the trailing 0 argument and a null environment pointer.
	 */
	(void) copyout((char *)&zero, arg_pos, sizeof(char *));
	arg_pos += sizeof(char *);
	(void) copyout((char *)&zero, arg_pos, sizeof(char *));
}