/* * Executes a program. */ PUBLIC int sys_execve(const char *filename, const char **argv, const char **envp) { int i; /* Loop index. */ struct inode *inode; /* File inode. */ struct region *reg; /* Process region. */ addr_t entry; /* Program entry point. */ addr_t sp; /* User stack pointer. */ char *name; /* File name. */ char stack[ARG_MAX]; /* Stack size. */ /* Get file name. */ if ((name = getname(filename)) == NULL) return (curr_proc->errno); /* Build arguments before freeing user memory. */ kmemset(stack, 0, ARG_MAX); if (!(sp = buildargs(stack, ARG_MAX, argv, envp))) { putname(name); return (curr_proc->errno); } /* Get file's inode. */ if ((inode = inode_name(name)) == NULL) { putname(name); return (curr_proc->errno); } /* Not a regular file. */ if (!S_ISREG(inode->mode)) { putname(name); inode_put(inode); return (-EACCES); } /* Not allowed. */ if (!permission(inode->mode, inode->uid, inode->gid, curr_proc, MAY_EXEC, 0)) { putname(name); inode_put(inode); return (-EACCES); } /* Close file descriptors. */ for (i = 0; i < OPEN_MAX; i++) { if (curr_proc->close & (1 << i)) do_close(i); } /* Detach process memory regions. */ for (i = 0; i < NR_PREGIONS; i++) detachreg(curr_proc, &curr_proc->pregs[i]); /* Reset signal handlers. */ curr_proc->restorer = NULL; for (i = 0; i < NR_SIGNALS; i++) { if (curr_proc->handlers[i] != SIG_DFL) { if (curr_proc->handlers[i] != SIG_IGN) curr_proc->handlers[i] = SIG_DFL; } } /* Load executable. */ if (!(entry = load_elf32(inode))) goto die0; /* Attach stack region. */ if ((reg = allocreg(S_IRUSR | S_IWUSR, PAGE_SIZE, REGION_DOWNWARDS)) == NULL) goto die0; if (attachreg(curr_proc, STACK(curr_proc), USTACK_ADDR - 1, reg)) goto die1; unlockreg(reg); /* Attach heap region. */ if ((reg = allocreg(S_IRUSR | S_IWUSR, PAGE_SIZE, REGION_UPWARDS)) == NULL) goto die0; if (attachreg(curr_proc, HEAP(curr_proc), UHEAP_ADDR, reg)) goto die1; unlockreg(reg); inode_put(inode); putname(name); kmemcpy((void *)(USTACK_ADDR - ARG_MAX), stack, ARG_MAX); user_mode(entry, sp); /* Will not return. */ return (0); die1: unlockreg(reg); freereg(reg); die0: inode_put(inode); putname(name); die(((SIGSEGV & 0xff) << 16) | (1 << 9)); return (-1); }
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { buildargs(); main(m_argc, m_argv); }