__declspec(noreturn) static void fork_child() { install_syscall_handler(); tls_afterfork(); process_init(fork->stack_base); dbt_init(); if (fork->ctid) *(pid_t *)fork->ctid = GetCurrentProcessId(); restore_fork_context(&fork->context); }
void main() { win7compat_init(); log_init(); fork_init(); /* fork_init() will directly jump to restored thread context if we are a fork child */ mm_init(); flags_init(); /* Parse command line */ const char *cmdline = GetCommandLineA(); int len = strlen(cmdline); if (len > BLOCK_SIZE) /* TODO: Test if there is sufficient space for argv[] array */ { init_subsystems(); kprintf("Command line too long.\n"); process_exit(1, 0); } startup = mm_mmap(NULL, BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS, INTERNAL_MAP_TOPDOWN | INTERNAL_MAP_NORESET | INTERNAL_MAP_VIRTUALALLOC, NULL, 0); *(uintptr_t*) startup = 1; char *current_startup_base = startup + sizeof(uintptr_t); memcpy(current_startup_base, cmdline, len + 1); char *envbuf = (char *)ALIGN_TO(current_startup_base + len + 1, sizeof(void*)); char *env0 = envbuf; ENV("TERM=xterm"); char *env1 = envbuf; ENV("HOME=/root"); char *env2 = envbuf; ENV("DISPLAY=127.0.0.1:0"); char *env3 = envbuf; ENV("PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/bin:/sbin"); int argc = 0; char **argv = (char **)ALIGN_TO(envbuf, sizeof(void*)); /* Parse command line */ int in_quote = 0; char *j = current_startup_base; for (char *i = current_startup_base; i <= current_startup_base + len; i++) if (!in_quote && (*i == ' ' || *i == '\t' || *i == '\r' || *i == '\n' || *i == 0)) { *i = 0; if (i > j) argv[argc++] = j; j = i + 1; } else if (*i == '"') { *i = 0; if (in_quote) argv[argc++] = j; in_quote = !in_quote; j = i + 1; } argv[argc] = NULL; char **envp = argv + argc + 1; int env_size = 4; envp[0] = env0; envp[1] = env1; envp[2] = env2; envp[3] = env3; envp[4] = NULL; char *buffer_base = (char*)(envp + env_size + 1); const char *filename = NULL; int arg_start; for (int i = 1; i < argc; i++) { if (!strcmp(argv[i], "--session-id")) { if (++i < argc) { int len = strlen(argv[i]); if (len >= MAX_SESSION_ID_LEN) { init_subsystems(); kprintf("--session-id: Session ID too long.\n"); process_exit(1, 0); } for (int j = 0; j < len; j++) { char ch = argv[i][j]; if (!((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == '_' || ch == '-')) { init_subsystems(); kprintf("--session-id: Invalid characters.\n"); process_exit(1, 0); } } strcpy(cmdline_flags->global_session_id, argv[i]); } else { init_subsystems(); kprintf("--session-id: No ID given.\n"); process_exit(1, 0); } } else if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) { init_subsystems(); print_help(); process_exit(1, 0); } else if (!strcmp(argv[i], "--usage")) { init_subsystems(); print_usage(); process_exit(1, 0); } else if (!strcmp(argv[i], "--version") || !strcmp(argv[i], "-v")) { init_subsystems(); print_version(); process_exit(1, 0); } else if (!strcmp(argv[i], "--dbt-trace")) cmdline_flags->dbt_trace = true; else if (!strcmp(argv[i], "--dbt-trace-all")) { cmdline_flags->dbt_trace = true; cmdline_flags->dbt_trace_all = true; } else if (argv[i][0] == '-') { init_subsystems(); kprintf("Unrecognized option: %s\n", argv[i]); process_exit(1, 0); } else if (!filename) { filename = argv[i]; arg_start = i; break; } } init_subsystems(); if (filename) { install_syscall_handler(); int r = do_execve(filename, argc - arg_start, argv + arg_start, env_size, envp, buffer_base, NULL); if (r == -L_ENOENT) { kprintf("Executable not found."); process_exit(1, 0); } } print_usage(); process_exit(1, 0); }
void main() { log_init(); fork_init(); /* fork_init() will directly jump to restored thread context if we are a fork child */ mm_init(); install_syscall_handler(); heap_init(); signal_init(); process_init(); tls_init(); vfs_init(); dbt_init(); /* Parse command line */ const char *cmdline = GetCommandLineA(); int len = strlen(cmdline); if (len > BLOCK_SIZE) /* TODO: Test if there is sufficient space for argv[] array */ { kprintf("Command line too long.\n"); process_exit(1, 0); } startup = mm_mmap(NULL, BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS, INTERNAL_MAP_TOPDOWN | INTERNAL_MAP_NORESET, NULL, 0); *(uintptr_t*) startup = 1; char *current_startup_base = startup + sizeof(uintptr_t); memcpy(current_startup_base, cmdline, len + 1); char *envbuf = (char *)ALIGN_TO(current_startup_base + len + 1, sizeof(void*)); char *env0 = envbuf; ENV("TERM=xterm"); char *env1 = envbuf; ENV("HOME=/root"); char *env2 = envbuf; ENV("DISPLAY=127.0.0.1:0"); char *env3 = envbuf; ENV("PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/bin:/sbin"); int argc = 0; char **argv = (char **)ALIGN_TO(envbuf, sizeof(void*)); /* Parse command line */ int in_quote = 0; char *j = current_startup_base; for (char *i = current_startup_base; i <= current_startup_base + len; i++) if (!in_quote && (*i == ' ' || *i == '\t' || *i == '\r' || *i == '\n' || *i == 0)) { *i = 0; if (i > j) argv[argc++] = j; j = i + 1; } else if (*i == '"') { *i = 0; if (in_quote) argv[argc++] = j; in_quote = !in_quote; j = i + 1; } argv[argc] = NULL; char **envp = argv + argc + 1; int env_size = 4; envp[0] = env0; envp[1] = env1; envp[2] = env2; envp[3] = env3; envp[4] = NULL; char *buffer_base = (char*)(envp + env_size + 1); const char *filename = NULL; for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { } else if (!filename) filename = argv[i]; } if (filename) do_execve(filename, argc - 1, argv + 1, env_size, envp, buffer_base, NULL); kprintf("Usage: flinux <executable> [arguments]\n"); process_exit(1, 0); }