/* * 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 *)); }
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 *)); }