1 /* 2 * process related system call shims and definitions 3 * 4 * Copyright (c) 2013-14 Stacey D. Son 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #ifndef BSD_USER_FREEBSD_OS_PROC_H 21 #define BSD_USER_FREEBSD_OS_PROC_H 22 23 #include <sys/param.h> 24 #include <sys/procctl.h> 25 #include <sys/signal.h> 26 #include <sys/types.h> 27 #include <sys/procdesc.h> 28 #include <sys/wait.h> 29 #include <unistd.h> 30 31 #include "target_arch_cpu.h" 32 33 pid_t safe_wait4(pid_t wpid, int *status, int options, struct rusage *rusage); 34 pid_t safe_wait6(idtype_t idtype, id_t id, int *status, int options, 35 struct __wrusage *wrusage, siginfo_t *infop); 36 37 extern int __setugid(int flag); 38 39 /* execve(2) */ 40 static inline abi_long do_freebsd_execve(abi_ulong path_or_fd, abi_ulong argp, 41 abi_ulong envp) 42 { 43 44 return freebsd_exec_common(path_or_fd, argp, envp, 0); 45 } 46 47 /* fexecve(2) */ 48 static inline abi_long do_freebsd_fexecve(abi_ulong path_or_fd, abi_ulong argp, 49 abi_ulong envp) 50 { 51 52 return freebsd_exec_common(path_or_fd, argp, envp, 1); 53 } 54 55 /* wait4(2) */ 56 static inline abi_long do_freebsd_wait4(abi_long arg1, abi_ulong target_status, 57 abi_long arg3, abi_ulong target_rusage) 58 { 59 abi_long ret; 60 int status; 61 struct rusage rusage, *rusage_ptr = NULL; 62 63 if (target_rusage) { 64 rusage_ptr = &rusage; 65 } 66 ret = get_errno(safe_wait4(arg1, &status, arg3, rusage_ptr)); 67 68 if (ret < 0) { 69 return ret; 70 } 71 if (target_status != 0) { 72 status = host_to_target_waitstatus(status); 73 if (put_user_s32(status, target_status) != 0) { 74 return -TARGET_EFAULT; 75 } 76 } 77 if (target_rusage != 0) { 78 host_to_target_rusage(target_rusage, &rusage); 79 } 80 return ret; 81 } 82 83 /* wait6(2) */ 84 static inline abi_long do_freebsd_wait6(void *cpu_env, abi_long idtype, 85 abi_long id1, abi_long id2, 86 abi_ulong target_status, abi_long options, abi_ulong target_wrusage, 87 abi_ulong target_infop, abi_ulong pad1) 88 { 89 abi_long ret; 90 int status; 91 struct __wrusage wrusage, *wrusage_ptr = NULL; 92 siginfo_t info; 93 void *p; 94 95 if (regpairs_aligned(cpu_env) != 0) { 96 /* printf("shifting args\n"); */ 97 /* 64-bit id is aligned, so shift all the arguments over by one */ 98 id1 = id2; 99 id2 = target_status; 100 target_status = options; 101 options = target_wrusage; 102 target_wrusage = target_infop; 103 target_infop = pad1; 104 } 105 106 if (target_wrusage) { 107 wrusage_ptr = &wrusage; 108 } 109 ret = get_errno(safe_wait6(idtype, target_arg64(id1, id2), 110 &status, options, wrusage_ptr, &info)); 111 112 if (ret < 0) { 113 return ret; 114 } 115 if (target_status != 0) { 116 status = host_to_target_waitstatus(status); 117 if (put_user_s32(status, target_status) != 0) { 118 return -TARGET_EFAULT; 119 } 120 } 121 if (target_wrusage != 0) { 122 host_to_target_wrusage(target_wrusage, &wrusage); 123 } 124 if (target_infop != 0) { 125 p = lock_user(VERIFY_WRITE, target_infop, sizeof(target_siginfo_t), 0); 126 if (p == NULL) { 127 return -TARGET_EFAULT; 128 } 129 host_to_target_siginfo(p, &info); 130 unlock_user(p, target_infop, sizeof(target_siginfo_t)); 131 } 132 return ret; 133 } 134 135 /* setloginclass(2) */ 136 static inline abi_long do_freebsd_setloginclass(abi_ulong arg1) 137 { 138 abi_long ret; 139 void *p; 140 141 p = lock_user_string(arg1); 142 if (p == NULL) { 143 return -TARGET_EFAULT; 144 } 145 ret = get_errno(setloginclass(p)); 146 unlock_user(p, arg1, 0); 147 148 return ret; 149 } 150 151 /* getloginclass(2) */ 152 static inline abi_long do_freebsd_getloginclass(abi_ulong arg1, abi_ulong arg2) 153 { 154 abi_long ret; 155 void *p; 156 157 p = lock_user(VERIFY_WRITE, arg1, arg2, 0); 158 if (p == NULL) { 159 return -TARGET_EFAULT; 160 } 161 ret = get_errno(getloginclass(p, arg2)); 162 unlock_user(p, arg1, arg2); 163 164 return ret; 165 } 166 167 /* pdgetpid(2) */ 168 static inline abi_long do_freebsd_pdgetpid(abi_long fd, abi_ulong target_pidp) 169 { 170 abi_long ret; 171 pid_t pid; 172 173 ret = get_errno(pdgetpid(fd, &pid)); 174 if (!is_error(ret)) { 175 if (put_user_u32(pid, target_pidp)) { 176 return -TARGET_EFAULT; 177 } 178 } 179 return ret; 180 } 181 182 /* undocumented __setugid */ 183 static inline abi_long do_freebsd___setugid(abi_long arg1) 184 { 185 return -TARGET_ENOSYS; 186 } 187 188 #endif /* BSD_USER_FREEBSD_OS_PROC_H */ 189