static int migrate_execve (struct shim_cp_store * cpstore, struct shim_process * process, struct shim_thread * thread, va_list ap) { struct shim_handle_map * handle_map = NULL; int ret; const char ** envp = va_arg (ap, const char **); size_t envsize = va_arg (ap, size_t); BEGIN_PROFILE_INTERVAL(); if ((ret = dup_handle_map(&handle_map, thread->handle_map)) < 0) return ret; set_handle_map(thread, handle_map); if ((ret = close_cloexec_handle(handle_map)) < 0) return ret; SAVE_PROFILE_INTERVAL(close_CLOEXEC_files_for_exec); /* Now we start to migrate bookkeeping for exec. The data we need to migrate are: 1. cur_threadrent thread 2. cur_threadrent filesystem 3. handle mapping 4. each handle */ BEGIN_MIGRATION_DEF(execve, struct shim_process * proc, struct shim_thread * thread, const char ** envp, size_t envsize) { store->use_gipc = true; DEFINE_MIGRATE(process, proc, sizeof(struct shim_process), false); DEFINE_MIGRATE(all_mounts, NULL, 0, false); DEFINE_MIGRATE(running_thread, thread, sizeof(struct shim_thread), false); DEFINE_MIGRATE(handle_map, thread->handle_map, sizeof (struct shim_handle_map), true); DEFINE_MIGRATE(migratable, NULL, 0, false); DEFINE_MIGRATE(environ, envp, envsize, true); }
int init_important_handles (void) { struct shim_thread * thread = get_cur_thread(); if (thread->handle_map) goto done; struct shim_handle_map * handle_map = get_cur_handle_map(thread); if (!handle_map) { handle_map = get_new_handle_map(INIT_HANDLE_MAP_SIZE); if (!handle_map) return -ENOMEM; set_handle_map(thread, handle_map); } lock(handle_map->lock); if (handle_map->fd_size < 3) { if (!__enlarge_handle_map(handle_map, INIT_HANDLE_MAP_SIZE)) { unlock(handle_map->lock); return -ENOMEM; } } struct shim_handle * hdl = NULL; int ret; for (int fd = 0 ; fd < 3 ; fd++) if (!HANDLE_ALLOCATED(handle_map->map[fd])) { if (!hdl) { hdl = get_new_handle(); if (!hdl) return -ENOMEM; if ((ret = init_tty_handle(hdl, fd)) < 0) { put_handle(hdl); return ret; } } else { get_handle(hdl); } __set_new_fd_handle(&handle_map->map[fd], fd, hdl, 0); put_handle(hdl); if (fd != 1) hdl = NULL; } else { if (fd == 1) hdl = handle_map->map[fd]->handle; } if (handle_map->fd_top == FD_NULL || handle_map->fd_top < 2) handle_map->fd_top = 2; unlock(handle_map->lock); done: init_exec_handle(thread); return 0; }