| 75 | } |
| 76 | |
| 77 | static void exitspawn(ppu_thread& ppu, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 _flags) |
| 78 | { |
| 79 | sys_mutex_lock(ppu, *g_ppu_exit_mutex, 0); |
| 80 | |
| 81 | u32 arg_count = 0; |
| 82 | u32 env_count = 0; |
| 83 | u32 alloc_size = get_exitspawn_size(path, argv, envp, arg_count, env_count); |
| 84 | |
| 85 | if (alloc_size > 0x1000) |
| 86 | { |
| 87 | argv = vm::null; |
| 88 | envp = vm::null; |
| 89 | arg_count = 0; |
| 90 | env_count = 0; |
| 91 | alloc_size = get_exitspawn_size(path, vm::null, vm::null, arg_count, env_count); |
| 92 | } |
| 93 | |
| 94 | alloc_size += 0x30; |
| 95 | |
| 96 | if (data_size > 0) |
| 97 | { |
| 98 | alloc_size += 0x1030; |
| 99 | } |
| 100 | |
| 101 | u32 alloc_addr = vm::alloc(alloc_size, vm::main); |
| 102 | |
| 103 | if (!alloc_addr) |
| 104 | { |
| 105 | // TODO (process atexit) |
| 106 | return _sys_process_exit(ppu, CELL_ENOMEM, 0, 0); |
| 107 | } |
| 108 | |
| 109 | put_exitspawn(vm::cast(alloc_addr + 0x30), path, arg_count, argv, env_count, envp); |
| 110 | |
| 111 | if (data_size) |
| 112 | { |
| 113 | std::memcpy(vm::base(alloc_addr + alloc_size - 0x1000), vm::base(data), std::min<u32>(data_size, 0x1000)); |
| 114 | } |
| 115 | |
| 116 | vm::ptr<sys_exit2_param> arg = vm::cast(alloc_addr); |
| 117 | arg->x0 = 0x85; |
| 118 | arg->this_size = 0x30; |
| 119 | arg->next_size = alloc_size - 0x30; |
| 120 | arg->prio = prio; |
| 121 | arg->flags = _flags; |
| 122 | arg->args = vm::cast(alloc_addr + 0x30); |
| 123 | |
| 124 | if ((_flags >> 62) == 0 && *g_ppu_atexitspawn) |
| 125 | { |
| 126 | // Execute atexitspawn |
| 127 | g_ppu_atexitspawn->operator()(ppu); |
| 128 | } |
| 129 | |
| 130 | if ((_flags >> 62) == 1 && *g_ppu_at_Exitspawn) |
| 131 | { |
| 132 | // Execute at_Exitspawn |
| 133 | g_ppu_at_Exitspawn->operator()(ppu); |
| 134 | } |
no test coverage detected