linux_misc.c (80180) | linux_misc.c (83221) |
---|---|
1/*- 2 * Copyright (c) 1994-1995 S�ren Schmidt 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * | 1/*- 2 * Copyright (c) 1994-1995 S�ren Schmidt 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * |
28 * $FreeBSD: head/sys/compat/linux/linux_misc.c 80180 2001-07-23 06:22:10Z pirzyk $ | 28 * $FreeBSD: head/sys/compat/linux/linux_misc.c 83221 2001-09-08 19:07:04Z marcel $ |
29 */ 30 31#include "opt_compat.h" 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/fcntl.h> 36#include <sys/imgact_aout.h> 37#include <sys/kernel.h> 38#include <sys/lock.h> 39#include <sys/mman.h> 40#include <sys/mount.h> 41#include <sys/mutex.h> 42#include <sys/namei.h> | 29 */ 30 31#include "opt_compat.h" 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/fcntl.h> 36#include <sys/imgact_aout.h> 37#include <sys/kernel.h> 38#include <sys/lock.h> 39#include <sys/mman.h> 40#include <sys/mount.h> 41#include <sys/mutex.h> 42#include <sys/namei.h> |
43#include <sys/poll.h> |
|
43#include <sys/proc.h> 44#include <sys/blist.h> 45#include <sys/reboot.h> 46#include <sys/resourcevar.h> 47#include <sys/signalvar.h> 48#include <sys/stat.h> 49#include <sys/sysctl.h> 50#include <sys/sysproto.h> --- 29 unchanged lines hidden (view full) --- 80 81#ifdef __alpha__ 82#define BSD_TO_LINUX_SIGNAL(sig) (sig) 83#else 84#define BSD_TO_LINUX_SIGNAL(sig) \ 85 (((sig) <= LINUX_SIGTBLSZ) ? bsd_to_linux_signal[_SIG_IDX(sig)] : sig) 86#endif 87 | 44#include <sys/proc.h> 45#include <sys/blist.h> 46#include <sys/reboot.h> 47#include <sys/resourcevar.h> 48#include <sys/signalvar.h> 49#include <sys/stat.h> 50#include <sys/sysctl.h> 51#include <sys/sysproto.h> --- 29 unchanged lines hidden (view full) --- 81 82#ifdef __alpha__ 83#define BSD_TO_LINUX_SIGNAL(sig) (sig) 84#else 85#define BSD_TO_LINUX_SIGNAL(sig) \ 86 (((sig) <= LINUX_SIGTBLSZ) ? bsd_to_linux_signal[_SIG_IDX(sig)] : sig) 87#endif 88 |
88struct linux_rlimit { 89 unsigned long rlim_cur; 90 unsigned long rlim_max; 91}; 92 | |
93#ifndef __alpha__ | 89#ifndef __alpha__ |
94static unsigned int linux_to_bsd_resource[LINUX_RLIM_NLIMITS] = 95{ RLIMIT_CPU, RLIMIT_FSIZE, RLIMIT_DATA, RLIMIT_STACK, 96 RLIMIT_CORE, RLIMIT_RSS, RLIMIT_NPROC, RLIMIT_NOFILE, 97 RLIMIT_MEMLOCK, -1 | 90static unsigned int linux_to_bsd_resource[LINUX_RLIM_NLIMITS] = { 91 RLIMIT_CPU, RLIMIT_FSIZE, RLIMIT_DATA, RLIMIT_STACK, 92 RLIMIT_CORE, RLIMIT_RSS, RLIMIT_NPROC, RLIMIT_NOFILE, 93 RLIMIT_MEMLOCK, -1 |
98}; 99#endif /*!__alpha__*/ 100 | 94}; 95#endif /*!__alpha__*/ 96 |
101struct linux_sysinfo { 102 long uptime; /* Seconds since boot */ 103 unsigned long loads[3]; /* 1, 5, and 15 minute load averages */ 104 unsigned long totalram; /* Total usable main memory size */ 105 unsigned long freeram; /* Available memory size */ 106 unsigned long sharedram; /* Amount of shared memory */ 107 unsigned long bufferram; /* Memory used by buffers */ 108 unsigned long totalswap; /* Total swap space size */ 109 unsigned long freeswap; /* swap space still available */ 110 unsigned short procs; /* Number of current processes */ 111 char _f[22]; /* Pads structure to 64 bytes */ | 97struct l_sysinfo { 98 l_long uptime; /* Seconds since boot */ 99 l_ulong loads[3]; /* 1, 5, and 15 minute load averages */ 100 l_ulong totalram; /* Total usable main memory size */ 101 l_ulong freeram; /* Available memory size */ 102 l_ulong sharedram; /* Amount of shared memory */ 103 l_ulong bufferram; /* Memory used by buffers */ 104 l_ulong totalswap; /* Total swap space size */ 105 l_ulong freeswap; /* swap space still available */ 106 l_ushort procs; /* Number of current processes */ 107 char _f[22]; /* Pads structure to 64 bytes */ |
112}; | 108}; |
113 | |
114#ifndef __alpha__ 115int 116linux_sysinfo(struct proc *p, struct linux_sysinfo_args *args) 117{ | 109#ifndef __alpha__ 110int 111linux_sysinfo(struct proc *p, struct linux_sysinfo_args *args) 112{ |
118 struct linux_sysinfo sysinfo; 119 vm_object_t object; 120 int i; 121 struct timespec ts; | 113 struct l_sysinfo sysinfo; 114 vm_object_t object; 115 int i; 116 struct timespec ts; |
122 | 117 |
123 /* Uptime is copied out of print_uptime() procedure in kern_shutdown.c */ 124 getnanouptime(&ts); 125 i = 0; 126 if (ts.tv_sec >= 86400) { 127 ts.tv_sec %= 86400; 128 i = 1; 129 } 130 if (i || ts.tv_sec >= 3600) { 131 ts.tv_sec %= 3600; 132 i = 1; 133 } 134 if (i || ts.tv_sec >= 60) { 135 ts.tv_sec %= 60; 136 i = 1; 137 } 138 sysinfo.uptime=ts.tv_sec; | 118 /* Uptime is copied out of print_uptime() in kern_shutdown.c */ 119 getnanouptime(&ts); 120 i = 0; 121 if (ts.tv_sec >= 86400) { 122 ts.tv_sec %= 86400; 123 i = 1; 124 } 125 if (i || ts.tv_sec >= 3600) { 126 ts.tv_sec %= 3600; 127 i = 1; 128 } 129 if (i || ts.tv_sec >= 60) { 130 ts.tv_sec %= 60; 131 i = 1; 132 } 133 sysinfo.uptime=ts.tv_sec; |
139 | 134 |
140 /* Use the information from the mib to get our load averages */ 141 for (i = 0; i < 3; i++) 142 sysinfo.loads[i] = averunnable.ldavg[i]; | 135 /* Use the information from the mib to get our load averages */ 136 for (i = 0; i < 3; i++) 137 sysinfo.loads[i] = averunnable.ldavg[i]; |
143 | 138 |
144 sysinfo.totalram = physmem * PAGE_SIZE; 145 sysinfo.freeram = sysinfo.totalram - cnt.v_wire_count * PAGE_SIZE; | 139 sysinfo.totalram = physmem * PAGE_SIZE; 140 sysinfo.freeram = sysinfo.totalram - cnt.v_wire_count * PAGE_SIZE; |
146 | 141 |
147 sysinfo.sharedram = 0; 148 for (object = TAILQ_FIRST(&vm_object_list); object != NULL; 149 object = TAILQ_NEXT(object, object_list)) 150 if (object->shadow_count > 1) 151 sysinfo.sharedram += object->resident_page_count; | 142 sysinfo.sharedram = 0; 143 for (object = TAILQ_FIRST(&vm_object_list); object != NULL; 144 object = TAILQ_NEXT(object, object_list)) 145 if (object->shadow_count > 1) 146 sysinfo.sharedram += object->resident_page_count; |
152 | 147 |
153 sysinfo.sharedram *= PAGE_SIZE; | 148 sysinfo.sharedram *= PAGE_SIZE; 149 sysinfo.bufferram = 0; |
154 | 150 |
155 sysinfo.bufferram = 0; | 151 if (swapblist == NULL) { 152 sysinfo.totalswap= 0; 153 sysinfo.freeswap = 0; 154 } else { 155 sysinfo.totalswap = swapblist->bl_blocks * 1024; 156 sysinfo.freeswap = swapblist->bl_root->u.bmu_avail * PAGE_SIZE; 157 } |
156 | 158 |
157 if (swapblist == NULL) { 158 sysinfo.totalswap= 0; 159 sysinfo.freeswap = 0; 160 } else { 161 sysinfo.totalswap = swapblist->bl_blocks * 1024; 162 sysinfo.freeswap = swapblist->bl_root->u.bmu_avail * PAGE_SIZE; 163 } | 159 sysinfo.procs = 20; /* Hack */ |
164 | 160 |
165 sysinfo.procs = 20; /* Hack */ 166 167 return copyout((caddr_t)&sysinfo, (caddr_t)args->info, 168 sizeof(struct linux_sysinfo)); | 161 return copyout(&sysinfo, (caddr_t)args->info, sizeof(sysinfo)); |
169} 170#endif /*!__alpha__*/ 171 172#ifndef __alpha__ 173int 174linux_alarm(struct proc *p, struct linux_alarm_args *args) 175{ | 162} 163#endif /*!__alpha__*/ 164 165#ifndef __alpha__ 166int 167linux_alarm(struct proc *p, struct linux_alarm_args *args) 168{ |
176 struct itimerval it, old_it; 177 struct timeval tv; 178 int s; | 169 struct itimerval it, old_it; 170 struct timeval tv; 171 int s; |
179 180#ifdef DEBUG 181 if (ldebug(alarm)) 182 printf(ARGS(alarm, "%u"), args->secs); 183#endif | 172 173#ifdef DEBUG 174 if (ldebug(alarm)) 175 printf(ARGS(alarm, "%u"), args->secs); 176#endif |
184 if (args->secs > 100000000) 185 return EINVAL; 186 it.it_value.tv_sec = (long)args->secs; 187 it.it_value.tv_usec = 0; 188 it.it_interval.tv_sec = 0; 189 it.it_interval.tv_usec = 0; 190 s = splsoftclock(); 191 old_it = p->p_realtimer; 192 getmicrouptime(&tv); 193 if (timevalisset(&old_it.it_value)) 194 callout_stop(&p->p_itcallout); 195 if (it.it_value.tv_sec != 0) { 196 callout_reset(&p->p_itcallout, tvtohz(&it.it_value), realitexpire, p); 197 timevaladd(&it.it_value, &tv); 198 } 199 p->p_realtimer = it; 200 splx(s); 201 if (timevalcmp(&old_it.it_value, &tv, >)) { 202 timevalsub(&old_it.it_value, &tv); 203 if (old_it.it_value.tv_usec != 0) 204 old_it.it_value.tv_sec++; 205 p->p_retval[0] = old_it.it_value.tv_sec; 206 } 207 return 0; | 177 178 if (args->secs > 100000000) 179 return EINVAL; 180 181 it.it_value.tv_sec = (long)args->secs; 182 it.it_value.tv_usec = 0; 183 it.it_interval.tv_sec = 0; 184 it.it_interval.tv_usec = 0; 185 s = splsoftclock(); 186 old_it = p->p_realtimer; 187 getmicrouptime(&tv); 188 if (timevalisset(&old_it.it_value)) 189 callout_stop(&p->p_itcallout); 190 if (it.it_value.tv_sec != 0) { 191 callout_reset(&p->p_itcallout, tvtohz(&it.it_value), 192 realitexpire, p); 193 timevaladd(&it.it_value, &tv); 194 } 195 p->p_realtimer = it; 196 splx(s); 197 if (timevalcmp(&old_it.it_value, &tv, >)) { 198 timevalsub(&old_it.it_value, &tv); 199 if (old_it.it_value.tv_usec != 0) 200 old_it.it_value.tv_sec++; 201 p->p_retval[0] = old_it.it_value.tv_sec; 202 } 203 return 0; |
208} 209#endif /*!__alpha__*/ 210 211int 212linux_brk(struct proc *p, struct linux_brk_args *args) 213{ | 204} 205#endif /*!__alpha__*/ 206 207int 208linux_brk(struct proc *p, struct linux_brk_args *args) 209{ |
214#if 0 215 struct vmspace *vm = p->p_vmspace; 216 vm_offset_t new, old; 217 int error; | 210 struct vmspace *vm = p->p_vmspace; 211 vm_offset_t new, old; 212 struct obreak_args /* { 213 char * nsize; 214 } */ tmp; |
218 | 215 |
219 if ((vm_offset_t)args->dsend < (vm_offset_t)vm->vm_daddr) 220 return EINVAL; 221 if (((caddr_t)args->dsend - (caddr_t)vm->vm_daddr) 222 > p->p_rlimit[RLIMIT_DATA].rlim_cur) 223 return ENOMEM; 224 225 old = round_page((vm_offset_t)vm->vm_daddr) + ctob(vm->vm_dsize); 226 new = round_page((vm_offset_t)args->dsend); 227 p->p_retval[0] = old; 228 if ((new-old) > 0) { 229 if (swap_pager_full) 230 return ENOMEM; 231 error = vm_map_find(&vm->vm_map, NULL, 0, &old, (new-old), FALSE, 232 VM_PROT_ALL, VM_PROT_ALL, 0); 233 if (error) 234 return error; 235 vm->vm_dsize += btoc((new-old)); 236 p->p_retval[0] = (int)(vm->vm_daddr + ctob(vm->vm_dsize)); 237 } 238 return 0; 239#else 240 struct vmspace *vm = p->p_vmspace; 241 vm_offset_t new, old; 242 struct obreak_args /* { 243 char * nsize; 244 } */ tmp; 245 | |
246#ifdef DEBUG 247 if (ldebug(brk)) 248 printf(ARGS(brk, "%p"), (void *)args->dsend); 249#endif | 216#ifdef DEBUG 217 if (ldebug(brk)) 218 printf(ARGS(brk, "%p"), (void *)args->dsend); 219#endif |
250 old = (vm_offset_t)vm->vm_daddr + ctob(vm->vm_dsize); 251 new = (vm_offset_t)args->dsend; 252 tmp.nsize = (char *) new; 253 if (((caddr_t)new > vm->vm_daddr) && !obreak(p, &tmp)) 254 p->p_retval[0] = (long)new; 255 else 256 p->p_retval[0] = (long)old; | 220 old = (vm_offset_t)vm->vm_daddr + ctob(vm->vm_dsize); 221 new = (vm_offset_t)args->dsend; 222 tmp.nsize = (char *) new; 223 if (((caddr_t)new > vm->vm_daddr) && !obreak(p, &tmp)) 224 p->p_retval[0] = (long)new; 225 else 226 p->p_retval[0] = (long)old; |
257 | 227 |
258 return 0; 259#endif | 228 return 0; |
260} 261 262int 263linux_uselib(struct proc *p, struct linux_uselib_args *args) 264{ | 229} 230 231int 232linux_uselib(struct proc *p, struct linux_uselib_args *args) 233{ |
265 struct nameidata ni; 266 struct vnode *vp; 267 struct exec *a_out; 268 struct vattr attr; 269 vm_offset_t vmaddr; 270 unsigned long file_offset; 271 vm_offset_t buffer; 272 unsigned long bss_size; 273 int error; 274 caddr_t sg; 275 int locked; | 234 struct nameidata ni; 235 struct vnode *vp; 236 struct exec *a_out; 237 struct vattr attr; 238 vm_offset_t vmaddr; 239 unsigned long file_offset; 240 vm_offset_t buffer; 241 unsigned long bss_size; 242 int error; 243 caddr_t sg; 244 int locked; |
276 | 245 |
277 sg = stackgap_init(); 278 CHECKALTEXIST(p, &sg, args->library); | 246 sg = stackgap_init(); 247 CHECKALTEXIST(p, &sg, args->library); |
279 280#ifdef DEBUG 281 if (ldebug(uselib)) 282 printf(ARGS(uselib, "%s"), args->library); 283#endif 284 | 248 249#ifdef DEBUG 250 if (ldebug(uselib)) 251 printf(ARGS(uselib, "%s"), args->library); 252#endif 253 |
285 a_out = NULL; 286 locked = 0; 287 vp = NULL; | 254 a_out = NULL; 255 locked = 0; 256 vp = NULL; |
288 | 257 |
289 NDINIT(&ni, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, args->library, p); 290 error = namei(&ni); 291 if (error) 292 goto cleanup; | 258 NDINIT(&ni, LOOKUP, FOLLOW|LOCKLEAF, UIO_USERSPACE, args->library, p); 259 error = namei(&ni); 260 if (error) 261 goto cleanup; |
293 | 262 |
294 vp = ni.ni_vp; 295 /* 296 * XXX This looks like a bogus check - a LOCKLEAF namei should not succeed 297 * without returning a vnode. 298 */ 299 if (vp == NULL) { 300 error = ENOEXEC; /* ?? */ 301 goto cleanup; 302 } 303 NDFREE(&ni, NDF_ONLY_PNBUF); | 263 vp = ni.ni_vp; 264 /* 265 * XXX - This looks like a bogus check. A LOCKLEAF namei should not 266 * succeed without returning a vnode. 267 */ 268 if (vp == NULL) { 269 error = ENOEXEC; /* ?? */ 270 goto cleanup; 271 } 272 NDFREE(&ni, NDF_ONLY_PNBUF); |
304 | 273 |
305 /* 306 * From here on down, we have a locked vnode that must be unlocked. 307 */ 308 locked++; | 274 /* 275 * From here on down, we have a locked vnode that must be unlocked. 276 */ 277 locked++; |
309 | 278 |
310 /* 311 * Writable? 312 */ 313 if (vp->v_writecount) { 314 error = ETXTBSY; 315 goto cleanup; 316 } | 279 /* Writable? */ 280 if (vp->v_writecount) { 281 error = ETXTBSY; 282 goto cleanup; 283 } |
317 | 284 |
318 /* 319 * Executable? 320 */ 321 error = VOP_GETATTR(vp, &attr, p->p_ucred, p); 322 if (error) 323 goto cleanup; | 285 /* Executable? */ 286 error = VOP_GETATTR(vp, &attr, p->p_ucred, p); 287 if (error) 288 goto cleanup; |
324 | 289 |
325 if ((vp->v_mount->mnt_flag & MNT_NOEXEC) || 326 ((attr.va_mode & 0111) == 0) || 327 (attr.va_type != VREG)) { 328 error = ENOEXEC; 329 goto cleanup; 330 } | 290 if ((vp->v_mount->mnt_flag & MNT_NOEXEC) || 291 ((attr.va_mode & 0111) == 0) || (attr.va_type != VREG)) { 292 error = ENOEXEC; 293 goto cleanup; 294 } |
331 | 295 |
332 /* 333 * Sensible size? 334 */ 335 if (attr.va_size == 0) { 336 error = ENOEXEC; 337 goto cleanup; 338 } | 296 /* Sensible size? */ 297 if (attr.va_size == 0) { 298 error = ENOEXEC; 299 goto cleanup; 300 } |
339 | 301 |
340 /* 341 * Can we access it? 342 */ 343 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p); 344 if (error) 345 goto cleanup; | 302 /* Can we access it? */ 303 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p); 304 if (error) 305 goto cleanup; |
346 | 306 |
347 error = VOP_OPEN(vp, FREAD, p->p_ucred, p); 348 if (error) 349 goto cleanup; | 307 error = VOP_OPEN(vp, FREAD, p->p_ucred, p); 308 if (error) 309 goto cleanup; |
350 | 310 |
351 /* 352 * Lock no longer needed 353 */ 354 VOP_UNLOCK(vp, 0, p); 355 locked = 0; | 311 /* 312 * Lock no longer needed 313 */ 314 VOP_UNLOCK(vp, 0, p); 315 locked = 0; |
356 | 316 |
357 /* 358 * Pull in executable header into kernel_map 359 */ 360 error = vm_mmap(kernel_map, (vm_offset_t *)&a_out, PAGE_SIZE, 361 VM_PROT_READ, VM_PROT_READ, 0, (caddr_t)vp, 0); 362 if (error) 363 goto cleanup; | 317 /* Pull in executable header into kernel_map */ 318 error = vm_mmap(kernel_map, (vm_offset_t *)&a_out, PAGE_SIZE, 319 VM_PROT_READ, VM_PROT_READ, 0, (caddr_t)vp, 0); 320 if (error) 321 goto cleanup; |
364 | 322 |
365 /* 366 * Is it a Linux binary ? 367 */ 368 if (((a_out->a_magic >> 16) & 0xff) != 0x64) { 369 error = ENOEXEC; 370 goto cleanup; 371 } | 323 /* Is it a Linux binary ? */ 324 if (((a_out->a_magic >> 16) & 0xff) != 0x64) { 325 error = ENOEXEC; 326 goto cleanup; 327 } |
372 | 328 |
373 /* While we are here, we should REALLY do some more checks */ | 329 /* 330 * While we are here, we should REALLY do some more checks 331 */ |
374 | 332 |
375 /* 376 * Set file/virtual offset based on a.out variant. 377 */ 378 switch ((int)(a_out->a_magic & 0xffff)) { 379 case 0413: /* ZMAGIC */ 380 file_offset = 1024; 381 break; 382 case 0314: /* QMAGIC */ 383 file_offset = 0; 384 break; 385 default: 386 error = ENOEXEC; 387 goto cleanup; 388 } | 333 /* Set file/virtual offset based on a.out variant. */ 334 switch ((int)(a_out->a_magic & 0xffff)) { 335 case 0413: /* ZMAGIC */ 336 file_offset = 1024; 337 break; 338 case 0314: /* QMAGIC */ 339 file_offset = 0; 340 break; 341 default: 342 error = ENOEXEC; 343 goto cleanup; 344 } |
389 | 345 |
390 bss_size = round_page(a_out->a_bss); | 346 bss_size = round_page(a_out->a_bss); |
391 | 347 |
392 /* 393 * Check various fields in header for validity/bounds. 394 */ 395 if (a_out->a_text & PAGE_MASK || a_out->a_data & PAGE_MASK) { 396 error = ENOEXEC; 397 goto cleanup; 398 } | 348 /* Check various fields in header for validity/bounds. */ 349 if (a_out->a_text & PAGE_MASK || a_out->a_data & PAGE_MASK) { 350 error = ENOEXEC; 351 goto cleanup; 352 } |
399 | 353 |
400 /* text + data can't exceed file size */ 401 if (a_out->a_data + a_out->a_text > attr.va_size) { 402 error = EFAULT; 403 goto cleanup; 404 } | 354 /* text + data can't exceed file size */ 355 if (a_out->a_data + a_out->a_text > attr.va_size) { 356 error = EFAULT; 357 goto cleanup; 358 } |
405 | 359 |
406 /* To protect p->p_rlimit in the if condition. */ 407 mtx_assert(&Giant, MA_OWNED); | 360 /* To protect p->p_rlimit in the if condition. */ 361 mtx_assert(&Giant, MA_OWNED); |
408 | 362 |
409 /* 410 * text/data/bss must not exceed limits 411 * XXX: this is not complete. it should check current usage PLUS 412 * the resources needed by this library. 413 */ 414 if (a_out->a_text > MAXTSIZ || 415 a_out->a_data + bss_size > p->p_rlimit[RLIMIT_DATA].rlim_cur) { 416 error = ENOMEM; 417 goto cleanup; 418 } | 363 /* 364 * text/data/bss must not exceed limits 365 * XXX - this is not complete. it should check current usage PLUS 366 * the resources needed by this library. 367 */ 368 if (a_out->a_text > MAXTSIZ || 369 a_out->a_data + bss_size > p->p_rlimit[RLIMIT_DATA].rlim_cur) { 370 error = ENOMEM; 371 goto cleanup; 372 } |
419 | 373 |
420 /* 421 * prevent more writers 422 */ 423 vp->v_flag |= VTEXT; | 374 /* prevent more writers */ 375 vp->v_flag |= VTEXT; |
424 | 376 |
425 /* 426 * Check if file_offset page aligned,. 427 * Currently we cannot handle misalinged file offsets, 428 * and so we read in the entire image (what a waste). 429 */ 430 if (file_offset & PAGE_MASK) { 431#ifdef DEBUG 432printf("uselib: Non page aligned binary %lu\n", file_offset); 433#endif | |
434 /* | 377 /* |
435 * Map text+data read/write/execute | 378 * Check if file_offset page aligned. Currently we cannot handle 379 * misalinged file offsets, and so we read in the entire image 380 * (what a waste). |
436 */ | 381 */ |
382 if (file_offset & PAGE_MASK) { 383#ifdef DEBUG 384 printf("uselib: Non page aligned binary %lu\n", file_offset); 385#endif 386 /* Map text+data read/write/execute */ |
|
437 | 387 |
438 /* a_entry is the load address and is page aligned */ 439 vmaddr = trunc_page(a_out->a_entry); | 388 /* a_entry is the load address and is page aligned */ 389 vmaddr = trunc_page(a_out->a_entry); |
440 | 390 |
441 /* get anon user mapping, read+write+execute */ 442 error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr, 443 a_out->a_text + a_out->a_data, FALSE, 444 VM_PROT_ALL, VM_PROT_ALL, 0); 445 if (error) 446 goto cleanup; | 391 /* get anon user mapping, read+write+execute */ 392 error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr, 393 a_out->a_text + a_out->a_data, FALSE, VM_PROT_ALL, 394 VM_PROT_ALL, 0); 395 if (error) 396 goto cleanup; |
447 | 397 |
448 /* map file into kernel_map */ 449 error = vm_mmap(kernel_map, &buffer, 450 round_page(a_out->a_text + a_out->a_data + file_offset), 451 VM_PROT_READ, VM_PROT_READ, 0, 452 (caddr_t)vp, trunc_page(file_offset)); 453 if (error) 454 goto cleanup; | 398 /* map file into kernel_map */ 399 error = vm_mmap(kernel_map, &buffer, 400 round_page(a_out->a_text + a_out->a_data + file_offset), 401 VM_PROT_READ, VM_PROT_READ, 0, (caddr_t)vp, 402 trunc_page(file_offset)); 403 if (error) 404 goto cleanup; |
455 | 405 |
456 /* copy from kernel VM space to user space */ 457 error = copyout((caddr_t)(void *)(uintptr_t)(buffer + file_offset), 458 (caddr_t)vmaddr, a_out->a_text + a_out->a_data); | 406 /* copy from kernel VM space to user space */ 407 error = copyout((caddr_t)(uintptr_t)(buffer + file_offset), 408 (caddr_t)vmaddr, a_out->a_text + a_out->a_data); |
459 | 409 |
460 /* release temporary kernel space */ 461 vm_map_remove(kernel_map, buffer, 462 buffer + round_page(a_out->a_text + a_out->a_data + file_offset)); | 410 /* release temporary kernel space */ 411 vm_map_remove(kernel_map, buffer, buffer + 412 round_page(a_out->a_text + a_out->a_data + file_offset)); |
463 | 413 |
464 if (error) 465 goto cleanup; 466 } 467 else { | 414 if (error) 415 goto cleanup; 416 } else { |
468#ifdef DEBUG | 417#ifdef DEBUG |
469printf("uselib: Page aligned binary %lu\n", file_offset); | 418 printf("uselib: Page aligned binary %lu\n", file_offset); |
470#endif | 419#endif |
471 /* 472 * for QMAGIC, a_entry is 20 bytes beyond the load address 473 * to skip the executable header 474 */ 475 vmaddr = trunc_page(a_out->a_entry); | 420 /* 421 * for QMAGIC, a_entry is 20 bytes beyond the load address 422 * to skip the executable header 423 */ 424 vmaddr = trunc_page(a_out->a_entry); |
476 | 425 |
477 /* 478 * Map it all into the process's space as a single copy-on-write 479 * "data" segment. 480 */ 481 error = vm_mmap(&p->p_vmspace->vm_map, &vmaddr, 482 a_out->a_text + a_out->a_data, 483 VM_PROT_ALL, VM_PROT_ALL, MAP_PRIVATE | MAP_FIXED, 484 (caddr_t)vp, file_offset); 485 if (error) 486 goto cleanup; 487 } | 426 /* 427 * Map it all into the process's space as a single 428 * copy-on-write "data" segment. 429 */ 430 error = vm_mmap(&p->p_vmspace->vm_map, &vmaddr, 431 a_out->a_text + a_out->a_data, VM_PROT_ALL, VM_PROT_ALL, 432 MAP_PRIVATE | MAP_FIXED, (caddr_t)vp, file_offset); 433 if (error) 434 goto cleanup; 435 } |
488#ifdef DEBUG | 436#ifdef DEBUG |
489printf("mem=%08lx = %08lx %08lx\n", (long)vmaddr, ((long*)vmaddr)[0], ((long*)vmaddr)[1]); | 437 printf("mem=%08lx = %08lx %08lx\n", (long)vmaddr, ((long*)vmaddr)[0], 438 ((long*)vmaddr)[1]); |
490#endif | 439#endif |
491 if (bss_size != 0) { 492 /* 493 * Calculate BSS start address 494 */ 495 vmaddr = trunc_page(a_out->a_entry) + a_out->a_text + a_out->a_data; | 440 if (bss_size != 0) { 441 /* Calculate BSS start address */ 442 vmaddr = trunc_page(a_out->a_entry) + a_out->a_text + 443 a_out->a_data; |
496 | 444 |
497 /* 498 * allocate some 'anon' space 499 */ 500 error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr, 501 bss_size, FALSE, 502 VM_PROT_ALL, VM_PROT_ALL, 0); 503 if (error) 504 goto cleanup; 505 } | 445 /* allocate some 'anon' space */ 446 error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr, 447 bss_size, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0); 448 if (error) 449 goto cleanup; 450 } |
506 507cleanup: | 451 452cleanup: |
508 /* 509 * Unlock vnode if needed 510 */ 511 if (locked) 512 VOP_UNLOCK(vp, 0, p); | 453 /* Unlock vnode if needed */ 454 if (locked) 455 VOP_UNLOCK(vp, 0, p); |
513 | 456 |
514 /* 515 * Release the kernel mapping. 516 */ 517 if (a_out) 518 vm_map_remove(kernel_map, (vm_offset_t)a_out, (vm_offset_t)a_out + PAGE_SIZE); | 457 /* Release the kernel mapping. */ 458 if (a_out) 459 vm_map_remove(kernel_map, (vm_offset_t)a_out, 460 (vm_offset_t)a_out + PAGE_SIZE); |
519 | 461 |
520 return error; | 462 return error; |
521} 522 523int | 463} 464 465int |
524linux_newselect(struct proc *p, struct linux_newselect_args *args) | 466linux_select(struct proc *p, struct linux_select_args *args) |
525{ | 467{ |
526 struct select_args bsa; 527 struct timeval tv0, tv1, utv, *tvp; 528 caddr_t sg; 529 int error; | 468 struct select_args bsa; 469 struct timeval tv0, tv1, utv, *tvp; 470 caddr_t sg; 471 int error; |
530 531#ifdef DEBUG | 472 473#ifdef DEBUG |
532 if (ldebug(newselect)) 533 printf(ARGS(newselect, "%d, %p, %p, %p, %p"), 534 args->nfds, (void *)args->readfds, 535 (void *)args->writefds, (void *)args->exceptfds, 536 (void *)args->timeout); | 474 if (ldebug(select)) 475 printf(ARGS(select, "%d, %p, %p, %p, %p"), args->nfds, 476 (void *)args->readfds, (void *)args->writefds, 477 (void *)args->exceptfds, (void *)args->timeout); |
537#endif | 478#endif |
538 error = 0; 539 bsa.nd = args->nfds; 540 bsa.in = args->readfds; 541 bsa.ou = args->writefds; 542 bsa.ex = args->exceptfds; 543 bsa.tv = args->timeout; | |
544 | 479 |
545 /* 546 * Store current time for computation of the amount of 547 * time left. 548 */ 549 if (args->timeout) { 550 if ((error = copyin(args->timeout, &utv, sizeof(utv)))) 551 goto select_out; | 480 error = 0; 481 bsa.nd = args->nfds; 482 bsa.in = args->readfds; 483 bsa.ou = args->writefds; 484 bsa.ex = args->exceptfds; 485 bsa.tv = (struct timeval *)args->timeout; 486 487 /* 488 * Store current time for computation of the amount of 489 * time left. 490 */ 491 if (args->timeout) { 492 if ((error = copyin((caddr_t)args->timeout, &utv, 493 sizeof(utv)))) 494 goto select_out; |
552#ifdef DEBUG | 495#ifdef DEBUG |
553 if (ldebug(newselect)) 554 printf(LMSG("incoming timeout (%ld/%ld)"), 555 utv.tv_sec, utv.tv_usec); | 496 if (ldebug(select)) 497 printf(LMSG("incoming timeout (%ld/%ld)"), 498 utv.tv_sec, utv.tv_usec); |
556#endif | 499#endif |
557 if (itimerfix(&utv)) { 558 /* 559 * The timeval was invalid. Convert it to something 560 * valid that will act as it does under Linux. 561 */ 562 sg = stackgap_init(); 563 tvp = stackgap_alloc(&sg, sizeof(utv)); 564 utv.tv_sec += utv.tv_usec / 1000000; 565 utv.tv_usec %= 1000000; 566 if (utv.tv_usec < 0) { 567 utv.tv_sec -= 1; 568 utv.tv_usec += 1000000; 569 } 570 if (utv.tv_sec < 0) 571 timevalclear(&utv); 572 if ((error = copyout(&utv, tvp, sizeof(utv)))) 573 goto select_out; 574 bsa.tv = tvp; | 500 501 if (itimerfix(&utv)) { 502 /* 503 * The timeval was invalid. Convert it to something 504 * valid that will act as it does under Linux. 505 */ 506 sg = stackgap_init(); 507 tvp = stackgap_alloc(&sg, sizeof(utv)); 508 utv.tv_sec += utv.tv_usec / 1000000; 509 utv.tv_usec %= 1000000; 510 if (utv.tv_usec < 0) { 511 utv.tv_sec -= 1; 512 utv.tv_usec += 1000000; 513 } 514 if (utv.tv_sec < 0) 515 timevalclear(&utv); 516 if ((error = copyout(&utv, tvp, sizeof(utv)))) 517 goto select_out; 518 bsa.tv = tvp; 519 } 520 microtime(&tv0); |
575 } | 521 } |
576 microtime(&tv0); 577 } | |
578 | 522 |
579 error = select(p, &bsa); | 523 error = select(p, &bsa); |
580#ifdef DEBUG | 524#ifdef DEBUG |
581 if (ldebug(newselect)) | 525 if (ldebug(select)) |
582 printf(LMSG("real select returns %d"), error); 583#endif | 526 printf(LMSG("real select returns %d"), error); 527#endif |
528 if (error) { 529 /* 530 * See fs/select.c in the Linux kernel. Without this, 531 * Maelstrom doesn't work. 532 */ 533 if (error == ERESTART) 534 error = EINTR; 535 goto select_out; 536 } |
|
584 | 537 |
585 if (error) { 586 /* 587 * See fs/select.c in the Linux kernel. Without this, 588 * Maelstrom doesn't work. 589 */ 590 if (error == ERESTART) 591 error = EINTR; 592 goto select_out; 593 } 594 595 if (args->timeout) { 596 if (p->p_retval[0]) { 597 /* 598 * Compute how much time was left of the timeout, 599 * by subtracting the current time and the time 600 * before we started the call, and subtracting 601 * that result from the user-supplied value. 602 */ 603 microtime(&tv1); 604 timevalsub(&tv1, &tv0); 605 timevalsub(&utv, &tv1); 606 if (utv.tv_sec < 0) 607 timevalclear(&utv); 608 } else 609 timevalclear(&utv); | 538 if (args->timeout) { 539 if (p->p_retval[0]) { 540 /* 541 * Compute how much time was left of the timeout, 542 * by subtracting the current time and the time 543 * before we started the call, and subtracting 544 * that result from the user-supplied value. 545 */ 546 microtime(&tv1); 547 timevalsub(&tv1, &tv0); 548 timevalsub(&utv, &tv1); 549 if (utv.tv_sec < 0) 550 timevalclear(&utv); 551 } else 552 timevalclear(&utv); |
610#ifdef DEBUG | 553#ifdef DEBUG |
611 if (ldebug(newselect)) 612 printf(LMSG("outgoing timeout (%ld/%ld)"), 613 utv.tv_sec, utv.tv_usec); | 554 if (ldebug(select)) 555 printf(LMSG("outgoing timeout (%ld/%ld)"), 556 utv.tv_sec, utv.tv_usec); |
614#endif | 557#endif |
615 if ((error = copyout(&utv, args->timeout, sizeof(utv)))) 616 goto select_out; 617 } | 558 if ((error = copyout(&utv, (caddr_t)args->timeout, 559 sizeof(utv)))) 560 goto select_out; 561 } |
618 619select_out: 620#ifdef DEBUG | 562 563select_out: 564#ifdef DEBUG |
621 if (ldebug(newselect)) 622 printf(LMSG("newselect_out -> %d"), error); | 565 if (ldebug(select)) 566 printf(LMSG("select_out -> %d"), error); |
623#endif | 567#endif |
624 return error; | 568 return error; |
625} 626 627int 628linux_getpgid(struct proc *p, struct linux_getpgid_args *args) 629{ | 569} 570 571int 572linux_getpgid(struct proc *p, struct linux_getpgid_args *args) 573{ |
630 struct proc *curp; | 574 struct proc *curp; |
631 632#ifdef DEBUG 633 if (ldebug(getpgid)) 634 printf(ARGS(getpgid, "%d"), args->pid); 635#endif | 575 576#ifdef DEBUG 577 if (ldebug(getpgid)) 578 printf(ARGS(getpgid, "%d"), args->pid); 579#endif |
636 if (args->pid != p->p_pid) { 637 if (!(curp = pfind(args->pid))) 638 return ESRCH; 639 p->p_retval[0] = curp->p_pgid; 640 PROC_UNLOCK(curp); 641 } 642 else 643 p->p_retval[0] = p->p_pgid; 644 return 0; | 580 581 if (args->pid != p->p_pid) { 582 if (!(curp = pfind(args->pid))) 583 return ESRCH; 584 p->p_retval[0] = curp->p_pgid; 585 PROC_UNLOCK(curp); 586 } else 587 p->p_retval[0] = p->p_pgid; 588 589 return 0; |
645} 646 647int 648linux_mremap(struct proc *p, struct linux_mremap_args *args) 649{ 650 struct munmap_args /* { 651 void *addr; 652 size_t len; --- 12 unchanged lines hidden (view full) --- 665 args->old_len = round_page(args->old_len); 666 667 if (args->new_len > args->old_len) { 668 p->p_retval[0] = 0; 669 return ENOMEM; 670 } 671 672 if (args->new_len < args->old_len) { | 590} 591 592int 593linux_mremap(struct proc *p, struct linux_mremap_args *args) 594{ 595 struct munmap_args /* { 596 void *addr; 597 size_t len; --- 12 unchanged lines hidden (view full) --- 610 args->old_len = round_page(args->old_len); 611 612 if (args->new_len > args->old_len) { 613 p->p_retval[0] = 0; 614 return ENOMEM; 615 } 616 617 if (args->new_len < args->old_len) { |
673 bsd_args.addr = args->addr + args->new_len; | 618 bsd_args.addr = (caddr_t)(args->addr + args->new_len); |
674 bsd_args.len = args->old_len - args->new_len; 675 error = munmap(p, &bsd_args); 676 } 677 678 p->p_retval[0] = error ? 0 : (u_long)args->addr; 679 return error; 680} 681 682int 683linux_msync(struct proc *p, struct linux_msync_args *args) 684{ 685 struct msync_args bsd_args; 686 | 619 bsd_args.len = args->old_len - args->new_len; 620 error = munmap(p, &bsd_args); 621 } 622 623 p->p_retval[0] = error ? 0 : (u_long)args->addr; 624 return error; 625} 626 627int 628linux_msync(struct proc *p, struct linux_msync_args *args) 629{ 630 struct msync_args bsd_args; 631 |
687 bsd_args.addr = args->addr; | 632 bsd_args.addr = (caddr_t)args->addr; |
688 bsd_args.len = args->len; 689 bsd_args.flags = 0; /* XXX ignore */ 690 691 return msync(p, &bsd_args); 692} 693 694#ifndef __alpha__ 695int 696linux_time(struct proc *p, struct linux_time_args *args) 697{ | 633 bsd_args.len = args->len; 634 bsd_args.flags = 0; /* XXX ignore */ 635 636 return msync(p, &bsd_args); 637} 638 639#ifndef __alpha__ 640int 641linux_time(struct proc *p, struct linux_time_args *args) 642{ |
698 struct timeval tv; 699 linux_time_t tm; 700 int error; | 643 struct timeval tv; 644 l_time_t tm; 645 int error; |
701 702#ifdef DEBUG 703 if (ldebug(time)) 704 printf(ARGS(time, "*")); 705#endif | 646 647#ifdef DEBUG 648 if (ldebug(time)) 649 printf(ARGS(time, "*")); 650#endif |
706 microtime(&tv); 707 tm = tv.tv_sec; 708 if (args->tm && (error = copyout(&tm, args->tm, sizeof(linux_time_t)))) 709 return error; 710 p->p_retval[0] = tm; 711 return 0; | 651 652 microtime(&tv); 653 tm = tv.tv_sec; 654 if (args->tm && (error = copyout(&tm, (caddr_t)args->tm, sizeof(tm)))) 655 return error; 656 p->p_retval[0] = tm; 657 return 0; |
712} 713#endif /*!__alpha__*/ 714 | 658} 659#endif /*!__alpha__*/ 660 |
715struct linux_times_argv { 716 long tms_utime; 717 long tms_stime; 718 long tms_cutime; 719 long tms_cstime; | 661struct l_times_argv { 662 l_long tms_utime; 663 l_long tms_stime; 664 l_long tms_cutime; 665 l_long tms_cstime; |
720}; 721 722#ifdef __alpha__ 723#define CLK_TCK 1024 /* Linux uses 1024 on alpha */ 724#else 725#define CLK_TCK 100 /* Linux uses 100 */ 726#endif 727 728#define CONVTCK(r) (r.tv_sec * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK)) 729 730int 731linux_times(struct proc *p, struct linux_times_args *args) 732{ | 666}; 667 668#ifdef __alpha__ 669#define CLK_TCK 1024 /* Linux uses 1024 on alpha */ 670#else 671#define CLK_TCK 100 /* Linux uses 100 */ 672#endif 673 674#define CONVTCK(r) (r.tv_sec * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK)) 675 676int 677linux_times(struct proc *p, struct linux_times_args *args) 678{ |
733 struct timeval tv; 734 struct linux_times_argv tms; 735 struct rusage ru; 736 int error; | 679 struct timeval tv; 680 struct l_times_argv tms; 681 struct rusage ru; 682 int error; |
737 738#ifdef DEBUG 739 if (ldebug(times)) 740 printf(ARGS(times, "*")); 741#endif | 683 684#ifdef DEBUG 685 if (ldebug(times)) 686 printf(ARGS(times, "*")); 687#endif |
742 mtx_lock_spin(&sched_lock); 743 calcru(p, &ru.ru_utime, &ru.ru_stime, NULL); 744 mtx_unlock_spin(&sched_lock); | |
745 | 688 |
746 tms.tms_utime = CONVTCK(ru.ru_utime); 747 tms.tms_stime = CONVTCK(ru.ru_stime); | 689 mtx_lock_spin(&sched_lock); 690 calcru(p, &ru.ru_utime, &ru.ru_stime, NULL); 691 mtx_unlock_spin(&sched_lock); |
748 | 692 |
749 tms.tms_cutime = CONVTCK(p->p_stats->p_cru.ru_utime); 750 tms.tms_cstime = CONVTCK(p->p_stats->p_cru.ru_stime); | 693 tms.tms_utime = CONVTCK(ru.ru_utime); 694 tms.tms_stime = CONVTCK(ru.ru_stime); |
751 | 695 |
752 if ((error = copyout((caddr_t)&tms, (caddr_t)args->buf, 753 sizeof(struct linux_times_argv)))) 754 return error; | 696 tms.tms_cutime = CONVTCK(p->p_stats->p_cru.ru_utime); 697 tms.tms_cstime = CONVTCK(p->p_stats->p_cru.ru_stime); |
755 | 698 |
756 microuptime(&tv); 757 p->p_retval[0] = (int)CONVTCK(tv); 758 return 0; | 699 if ((error = copyout(&tms, (caddr_t)args->buf, sizeof(tms)))) 700 return error; 701 702 microuptime(&tv); 703 p->p_retval[0] = (int)CONVTCK(tv); 704 return 0; |
759} 760 761int 762linux_newuname(struct proc *p, struct linux_newuname_args *args) 763{ | 705} 706 707int 708linux_newuname(struct proc *p, struct linux_newuname_args *args) 709{ |
764 struct linux_new_utsname utsname; | 710 struct l_new_utsname utsname; |
765 char *osrelease, *osname; 766 767#ifdef DEBUG 768 if (ldebug(newuname)) 769 printf(ARGS(newuname, "*")); 770#endif 771 772 osname = linux_get_osname(p); 773 osrelease = linux_get_osrelease(p); 774 | 711 char *osrelease, *osname; 712 713#ifdef DEBUG 714 if (ldebug(newuname)) 715 printf(ARGS(newuname, "*")); 716#endif 717 718 osname = linux_get_osname(p); 719 osrelease = linux_get_osrelease(p); 720 |
775 bzero(&utsname, sizeof(struct linux_new_utsname)); | 721 bzero(&utsname, sizeof(utsname)); |
776 strncpy(utsname.sysname, osname, LINUX_MAX_UTSNAME-1); 777 strncpy(utsname.nodename, hostname, LINUX_MAX_UTSNAME-1); 778 strncpy(utsname.release, osrelease, LINUX_MAX_UTSNAME-1); 779 strncpy(utsname.version, version, LINUX_MAX_UTSNAME-1); 780 strncpy(utsname.machine, machine, LINUX_MAX_UTSNAME-1); 781 strncpy(utsname.domainname, domainname, LINUX_MAX_UTSNAME-1); 782 | 722 strncpy(utsname.sysname, osname, LINUX_MAX_UTSNAME-1); 723 strncpy(utsname.nodename, hostname, LINUX_MAX_UTSNAME-1); 724 strncpy(utsname.release, osrelease, LINUX_MAX_UTSNAME-1); 725 strncpy(utsname.version, version, LINUX_MAX_UTSNAME-1); 726 strncpy(utsname.machine, machine, LINUX_MAX_UTSNAME-1); 727 strncpy(utsname.domainname, domainname, LINUX_MAX_UTSNAME-1); 728 |
783 return (copyout((caddr_t)&utsname, (caddr_t)args->buf, 784 sizeof(struct linux_new_utsname))); | 729 return (copyout(&utsname, (caddr_t)args->buf, sizeof(utsname))); |
785} 786 | 730} 731 |
787struct linux_utimbuf { 788 linux_time_t l_actime; 789 linux_time_t l_modtime; | 732#if defined(__i386__) 733struct l_utimbuf { 734 l_time_t l_actime; 735 l_time_t l_modtime; |
790}; 791 792int 793linux_utime(struct proc *p, struct linux_utime_args *args) 794{ | 736}; 737 738int 739linux_utime(struct proc *p, struct linux_utime_args *args) 740{ |
795 struct utimes_args /* { 796 char *path; 797 struct timeval *tptr; 798 } */ bsdutimes; 799 struct timeval tv[2], *tvp; 800 struct linux_utimbuf lut; 801 int error; 802 caddr_t sg; | 741 struct utimes_args /* { 742 char *path; 743 struct timeval *tptr; 744 } */ bsdutimes; 745 struct timeval tv[2], *tvp; 746 struct l_utimbuf lut; 747 int error; 748 caddr_t sg; |
803 | 749 |
804 sg = stackgap_init(); 805 CHECKALTEXIST(p, &sg, args->fname); | 750 sg = stackgap_init(); 751 CHECKALTEXIST(p, &sg, args->fname); |
806 807#ifdef DEBUG 808 if (ldebug(utime)) 809 printf(ARGS(utime, "%s, *"), args->fname); 810#endif | 752 753#ifdef DEBUG 754 if (ldebug(utime)) 755 printf(ARGS(utime, "%s, *"), args->fname); 756#endif |
811 if (args->times) { 812 if ((error = copyin(args->times, &lut, sizeof lut))) 813 return error; 814 tv[0].tv_sec = lut.l_actime; 815 tv[0].tv_usec = 0; 816 tv[1].tv_sec = lut.l_modtime; 817 tv[1].tv_usec = 0; 818 /* so that utimes can copyin */ 819 tvp = (struct timeval *)stackgap_alloc(&sg, sizeof(tv)); 820 if (tvp == NULL) 821 return (ENAMETOOLONG); 822 if ((error = copyout(tv, tvp, sizeof(tv)))) 823 return error; 824 bsdutimes.tptr = tvp; 825 } else 826 bsdutimes.tptr = NULL; | |
827 | 757 |
828 bsdutimes.path = args->fname; 829 return utimes(p, &bsdutimes); | 758 if (args->times) { 759 if ((error = copyin((caddr_t)args->times, &lut, sizeof lut))) 760 return error; 761 tv[0].tv_sec = lut.l_actime; 762 tv[0].tv_usec = 0; 763 tv[1].tv_sec = lut.l_modtime; 764 tv[1].tv_usec = 0; 765 /* so that utimes can copyin */ 766 tvp = (struct timeval *)stackgap_alloc(&sg, sizeof(tv)); 767 if (tvp == NULL) 768 return (ENAMETOOLONG); 769 if ((error = copyout(tv, tvp, sizeof(tv)))) 770 return error; 771 bsdutimes.tptr = tvp; 772 } else 773 bsdutimes.tptr = NULL; 774 775 bsdutimes.path = args->fname; 776 return utimes(p, &bsdutimes); |
830} | 777} |
778#endif /* __i386__ */ |
|
831 832#define __WCLONE 0x80000000 833 834#ifndef __alpha__ 835int 836linux_waitpid(struct proc *p, struct linux_waitpid_args *args) 837{ | 779 780#define __WCLONE 0x80000000 781 782#ifndef __alpha__ 783int 784linux_waitpid(struct proc *p, struct linux_waitpid_args *args) 785{ |
838 struct wait_args /* { 839 int pid; 840 int *status; 841 int options; 842 struct rusage *rusage; 843 } */ tmp; 844 int error, tmpstat; | 786 struct wait_args /* { 787 int pid; 788 int *status; 789 int options; 790 struct rusage *rusage; 791 } */ tmp; 792 int error, tmpstat; |
845 846#ifdef DEBUG 847 if (ldebug(waitpid)) 848 printf(ARGS(waitpid, "%d, %p, %d"), 849 args->pid, (void *)args->status, args->options); 850#endif | 793 794#ifdef DEBUG 795 if (ldebug(waitpid)) 796 printf(ARGS(waitpid, "%d, %p, %d"), 797 args->pid, (void *)args->status, args->options); 798#endif |
851 tmp.pid = args->pid; 852 tmp.status = args->status; 853 tmp.options = (args->options & (WNOHANG | WUNTRACED)); 854 /* WLINUXCLONE should be equal to __WCLONE, but we make sure */ 855 if (args->options & __WCLONE) 856 tmp.options |= WLINUXCLONE; 857 tmp.rusage = NULL; | |
858 | 799 |
859 if ((error = wait4(p, &tmp)) != 0) 860 return error; | 800 tmp.pid = args->pid; 801 tmp.status = args->status; 802 tmp.options = (args->options & (WNOHANG | WUNTRACED)); 803 /* WLINUXCLONE should be equal to __WCLONE, but we make sure */ 804 if (args->options & __WCLONE) 805 tmp.options |= WLINUXCLONE; 806 tmp.rusage = NULL; |
861 | 807 |
862 if (args->status) { 863 if ((error = copyin(args->status, &tmpstat, sizeof(int))) != 0) 864 return error; 865 tmpstat &= 0xffff; 866 if (WIFSIGNALED(tmpstat)) 867 tmpstat = (tmpstat & 0xffffff80) | 868 BSD_TO_LINUX_SIGNAL(WTERMSIG(tmpstat)); 869 else if (WIFSTOPPED(tmpstat)) 870 tmpstat = (tmpstat & 0xffff00ff) | 871 (BSD_TO_LINUX_SIGNAL(WSTOPSIG(tmpstat)) << 8); 872 return copyout(&tmpstat, args->status, sizeof(int)); 873 } else | 808 if ((error = wait4(p, &tmp)) != 0) 809 return error; 810 811 if (args->status) { 812 if ((error = copyin((caddr_t)args->status, &tmpstat, 813 sizeof(int))) != 0) 814 return error; 815 tmpstat &= 0xffff; 816 if (WIFSIGNALED(tmpstat)) 817 tmpstat = (tmpstat & 0xffffff80) | 818 BSD_TO_LINUX_SIGNAL(WTERMSIG(tmpstat)); 819 else if (WIFSTOPPED(tmpstat)) 820 tmpstat = (tmpstat & 0xffff00ff) | 821 (BSD_TO_LINUX_SIGNAL(WSTOPSIG(tmpstat)) << 8); 822 return copyout(&tmpstat, (caddr_t)args->status, sizeof(int)); 823 } 824 |
874 return 0; 875} 876#endif /*!__alpha__*/ 877 878int 879linux_wait4(struct proc *p, struct linux_wait4_args *args) 880{ | 825 return 0; 826} 827#endif /*!__alpha__*/ 828 829int 830linux_wait4(struct proc *p, struct linux_wait4_args *args) 831{ |
881 struct wait_args /* { 882 int pid; 883 int *status; 884 int options; 885 struct rusage *rusage; 886 } */ tmp; 887 int error, tmpstat; | 832 struct wait_args /* { 833 int pid; 834 int *status; 835 int options; 836 struct rusage *rusage; 837 } */ tmp; 838 int error, tmpstat; |
888 889#ifdef DEBUG 890 if (ldebug(wait4)) 891 printf(ARGS(wait4, "%d, %p, %d, %p"), 892 args->pid, (void *)args->status, args->options, 893 (void *)args->rusage); 894#endif | 839 840#ifdef DEBUG 841 if (ldebug(wait4)) 842 printf(ARGS(wait4, "%d, %p, %d, %p"), 843 args->pid, (void *)args->status, args->options, 844 (void *)args->rusage); 845#endif |
895 tmp.pid = args->pid; 896 tmp.status = args->status; 897 tmp.options = (args->options & (WNOHANG | WUNTRACED)); 898 /* WLINUXCLONE should be equal to __WCLONE, but we make sure */ 899 if (args->options & __WCLONE) 900 tmp.options |= WLINUXCLONE; 901 tmp.rusage = args->rusage; | |
902 | 846 |
903 if ((error = wait4(p, &tmp)) != 0) 904 return error; | 847 tmp.pid = args->pid; 848 tmp.status = args->status; 849 tmp.options = (args->options & (WNOHANG | WUNTRACED)); 850 /* WLINUXCLONE should be equal to __WCLONE, but we make sure */ 851 if (args->options & __WCLONE) 852 tmp.options |= WLINUXCLONE; 853 tmp.rusage = (struct rusage *)args->rusage; |
905 | 854 |
906 SIGDELSET(p->p_siglist, SIGCHLD); | 855 if ((error = wait4(p, &tmp)) != 0) 856 return error; |
907 | 857 |
908 if (args->status) { 909 if ((error = copyin(args->status, &tmpstat, sizeof(int))) != 0) 910 return error; 911 tmpstat &= 0xffff; 912 if (WIFSIGNALED(tmpstat)) 913 tmpstat = (tmpstat & 0xffffff80) | 914 BSD_TO_LINUX_SIGNAL(WTERMSIG(tmpstat)); 915 else if (WIFSTOPPED(tmpstat)) 916 tmpstat = (tmpstat & 0xffff00ff) | 917 (BSD_TO_LINUX_SIGNAL(WSTOPSIG(tmpstat)) << 8); 918 return copyout(&tmpstat, args->status, sizeof(int)); 919 } else | 858 SIGDELSET(p->p_siglist, SIGCHLD); 859 860 if (args->status) { 861 if ((error = copyin((caddr_t)args->status, &tmpstat, 862 sizeof(int))) != 0) 863 return error; 864 tmpstat &= 0xffff; 865 if (WIFSIGNALED(tmpstat)) 866 tmpstat = (tmpstat & 0xffffff80) | 867 BSD_TO_LINUX_SIGNAL(WTERMSIG(tmpstat)); 868 else if (WIFSTOPPED(tmpstat)) 869 tmpstat = (tmpstat & 0xffff00ff) | 870 (BSD_TO_LINUX_SIGNAL(WSTOPSIG(tmpstat)) << 8); 871 return copyout(&tmpstat, (caddr_t)args->status, sizeof(int)); 872 } 873 |
920 return 0; 921} 922 923int 924linux_mknod(struct proc *p, struct linux_mknod_args *args) 925{ 926 caddr_t sg; 927 struct mknod_args bsd_mknod; --- 52 unchanged lines hidden (view full) --- 980 int error; 981 982#ifdef DEBUG 983 if (ldebug(setitimer)) 984 printf(ARGS(setitimer, "%p, %p"), 985 (void *)args->itv, (void *)args->oitv); 986#endif 987 bsa.which = args->which; | 874 return 0; 875} 876 877int 878linux_mknod(struct proc *p, struct linux_mknod_args *args) 879{ 880 caddr_t sg; 881 struct mknod_args bsd_mknod; --- 52 unchanged lines hidden (view full) --- 934 int error; 935 936#ifdef DEBUG 937 if (ldebug(setitimer)) 938 printf(ARGS(setitimer, "%p, %p"), 939 (void *)args->itv, (void *)args->oitv); 940#endif 941 bsa.which = args->which; |
988 bsa.itv = args->itv; 989 bsa.oitv = args->oitv; | 942 bsa.itv = (struct itimerval *)args->itv; 943 bsa.oitv = (struct itimerval *)args->oitv; |
990 if (args->itv) { | 944 if (args->itv) { |
991 if ((error = copyin((caddr_t)args->itv, (caddr_t)&foo, 992 sizeof(foo)))) | 945 if ((error = copyin((caddr_t)args->itv, &foo, sizeof(foo)))) |
993 return error; 994#ifdef DEBUG 995 if (ldebug(setitimer)) { 996 printf("setitimer: value: sec: %ld, usec: %ld\n", 997 foo.it_value.tv_sec, foo.it_value.tv_usec); 998 printf("setitimer: interval: sec: %ld, usec: %ld\n", 999 foo.it_interval.tv_sec, foo.it_interval.tv_usec); 1000 } --- 6 unchanged lines hidden (view full) --- 1007linux_getitimer(struct proc *p, struct linux_getitimer_args *args) 1008{ 1009 struct getitimer_args bsa; 1010#ifdef DEBUG 1011 if (ldebug(getitimer)) 1012 printf(ARGS(getitimer, "%p"), (void *)args->itv); 1013#endif 1014 bsa.which = args->which; | 946 return error; 947#ifdef DEBUG 948 if (ldebug(setitimer)) { 949 printf("setitimer: value: sec: %ld, usec: %ld\n", 950 foo.it_value.tv_sec, foo.it_value.tv_usec); 951 printf("setitimer: interval: sec: %ld, usec: %ld\n", 952 foo.it_interval.tv_sec, foo.it_interval.tv_usec); 953 } --- 6 unchanged lines hidden (view full) --- 960linux_getitimer(struct proc *p, struct linux_getitimer_args *args) 961{ 962 struct getitimer_args bsa; 963#ifdef DEBUG 964 if (ldebug(getitimer)) 965 printf(ARGS(getitimer, "%p"), (void *)args->itv); 966#endif 967 bsa.which = args->which; |
1015 bsa.itv = args->itv; | 968 bsa.itv = (struct itimerval *)args->itv; |
1016 return getitimer(p, &bsa); 1017} 1018 1019#ifndef __alpha__ 1020int 1021linux_nice(struct proc *p, struct linux_nice_args *args) 1022{ 1023 struct setpriority_args bsd_args; 1024 1025 bsd_args.which = PRIO_PROCESS; 1026 bsd_args.who = 0; /* current process */ 1027 bsd_args.prio = args->inc; 1028 return setpriority(p, &bsd_args); 1029} 1030#endif /*!__alpha__*/ 1031 1032int | 969 return getitimer(p, &bsa); 970} 971 972#ifndef __alpha__ 973int 974linux_nice(struct proc *p, struct linux_nice_args *args) 975{ 976 struct setpriority_args bsd_args; 977 978 bsd_args.which = PRIO_PROCESS; 979 bsd_args.who = 0; /* current process */ 980 bsd_args.prio = args->inc; 981 return setpriority(p, &bsd_args); 982} 983#endif /*!__alpha__*/ 984 985int |
1033linux_setgroups(p, uap) 1034 struct proc *p; 1035 struct linux_setgroups_args *uap; | 986linux_setgroups(struct proc *p, struct linux_setgroups_args *args) |
1036{ 1037 struct ucred *newcred, *oldcred; | 987{ 988 struct ucred *newcred, *oldcred; |
1038 linux_gid_t linux_gidset[NGROUPS]; | 989 l_gid_t linux_gidset[NGROUPS]; |
1039 gid_t *bsd_gidset; 1040 int ngrp, error; 1041 | 990 gid_t *bsd_gidset; 991 int ngrp, error; 992 |
1042 ngrp = uap->gidsetsize; | 993 ngrp = args->gidsetsize; |
1043 oldcred = p->p_ucred; 1044 1045 /* 1046 * cr_groups[0] holds egid. Setting the whole set from 1047 * the supplied set will cause egid to be changed too. 1048 * Keep cr_groups[0] unchanged to prevent that. 1049 */ 1050 1051 if ((error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 1052 return (error); 1053 1054 if (ngrp >= NGROUPS) 1055 return (EINVAL); 1056 1057 newcred = crdup(oldcred); 1058 if (ngrp > 0) { | 994 oldcred = p->p_ucred; 995 996 /* 997 * cr_groups[0] holds egid. Setting the whole set from 998 * the supplied set will cause egid to be changed too. 999 * Keep cr_groups[0] unchanged to prevent that. 1000 */ 1001 1002 if ((error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 1003 return (error); 1004 1005 if (ngrp >= NGROUPS) 1006 return (EINVAL); 1007 1008 newcred = crdup(oldcred); 1009 if (ngrp > 0) { |
1059 error = copyin((caddr_t)uap->gidset, (caddr_t)linux_gidset, 1060 ngrp * sizeof(linux_gid_t)); | 1010 error = copyin((caddr_t)args->grouplist, linux_gidset, 1011 ngrp * sizeof(l_gid_t)); |
1061 if (error) 1062 return (error); 1063 1064 newcred->cr_ngroups = ngrp + 1; 1065 1066 bsd_gidset = newcred->cr_groups; 1067 ngrp--; 1068 while (ngrp >= 0) { --- 6 unchanged lines hidden (view full) --- 1075 1076 setsugid(p); 1077 p->p_ucred = newcred; 1078 crfree(oldcred); 1079 return (0); 1080} 1081 1082int | 1012 if (error) 1013 return (error); 1014 1015 newcred->cr_ngroups = ngrp + 1; 1016 1017 bsd_gidset = newcred->cr_groups; 1018 ngrp--; 1019 while (ngrp >= 0) { --- 6 unchanged lines hidden (view full) --- 1026 1027 setsugid(p); 1028 p->p_ucred = newcred; 1029 crfree(oldcred); 1030 return (0); 1031} 1032 1033int |
1083linux_getgroups(p, uap) 1084 struct proc *p; 1085 struct linux_getgroups_args *uap; | 1034linux_getgroups(struct proc *p, struct linux_getgroups_args *args) |
1086{ 1087 struct ucred *cred; | 1035{ 1036 struct ucred *cred; |
1088 linux_gid_t linux_gidset[NGROUPS]; | 1037 l_gid_t linux_gidset[NGROUPS]; |
1089 gid_t *bsd_gidset; 1090 int bsd_gidsetsz, ngrp, error; 1091 1092 cred = p->p_ucred; 1093 bsd_gidset = cred->cr_groups; 1094 bsd_gidsetsz = cred->cr_ngroups - 1; 1095 1096 /* 1097 * cr_groups[0] holds egid. Returning the whole set 1098 * here will cause a duplicate. Exclude cr_groups[0] 1099 * to prevent that. 1100 */ 1101 | 1038 gid_t *bsd_gidset; 1039 int bsd_gidsetsz, ngrp, error; 1040 1041 cred = p->p_ucred; 1042 bsd_gidset = cred->cr_groups; 1043 bsd_gidsetsz = cred->cr_ngroups - 1; 1044 1045 /* 1046 * cr_groups[0] holds egid. Returning the whole set 1047 * here will cause a duplicate. Exclude cr_groups[0] 1048 * to prevent that. 1049 */ 1050 |
1102 if ((ngrp = uap->gidsetsize) == 0) { | 1051 if ((ngrp = args->gidsetsize) == 0) { |
1103 p->p_retval[0] = bsd_gidsetsz; 1104 return (0); 1105 } 1106 1107 if (ngrp < bsd_gidsetsz) 1108 return (EINVAL); 1109 1110 ngrp = 0; 1111 while (ngrp < bsd_gidsetsz) { 1112 linux_gidset[ngrp] = bsd_gidset[ngrp + 1]; 1113 ngrp++; 1114 } 1115 | 1052 p->p_retval[0] = bsd_gidsetsz; 1053 return (0); 1054 } 1055 1056 if (ngrp < bsd_gidsetsz) 1057 return (EINVAL); 1058 1059 ngrp = 0; 1060 while (ngrp < bsd_gidsetsz) { 1061 linux_gidset[ngrp] = bsd_gidset[ngrp + 1]; 1062 ngrp++; 1063 } 1064 |
1116 if ((error = copyout((caddr_t)linux_gidset, (caddr_t)uap->gidset, 1117 ngrp * sizeof(linux_gid_t)))) | 1065 if ((error = copyout(linux_gidset, (caddr_t)args->grouplist, 1066 ngrp * sizeof(l_gid_t)))) |
1118 return (error); 1119 1120 p->p_retval[0] = ngrp; 1121 return (0); 1122} 1123 1124#ifndef __alpha__ 1125int | 1067 return (error); 1068 1069 p->p_retval[0] = ngrp; 1070 return (0); 1071} 1072 1073#ifndef __alpha__ 1074int |
1126linux_setrlimit(p, uap) 1127 struct proc *p; 1128 struct linux_setrlimit_args *uap; | 1075linux_setrlimit(struct proc *p, struct linux_setrlimit_args *args) |
1129{ 1130 struct __setrlimit_args bsd; | 1076{ 1077 struct __setrlimit_args bsd; |
1131 struct linux_rlimit rlim; | 1078 struct l_rlimit rlim; |
1132 int error; 1133 caddr_t sg = stackgap_init(); 1134 1135#ifdef DEBUG 1136 if (ldebug(setrlimit)) 1137 printf(ARGS(setrlimit, "%d, %p"), | 1079 int error; 1080 caddr_t sg = stackgap_init(); 1081 1082#ifdef DEBUG 1083 if (ldebug(setrlimit)) 1084 printf(ARGS(setrlimit, "%d, %p"), |
1138 uap->resource, (void *)uap->rlim); | 1085 args->resource, (void *)args->rlim); |
1139#endif 1140 | 1086#endif 1087 |
1141 if (uap->resource >= LINUX_RLIM_NLIMITS) | 1088 if (args->resource >= LINUX_RLIM_NLIMITS) |
1142 return (EINVAL); 1143 | 1089 return (EINVAL); 1090 |
1144 bsd.which = linux_to_bsd_resource[uap->resource]; | 1091 bsd.which = linux_to_bsd_resource[args->resource]; |
1145 if (bsd.which == -1) 1146 return (EINVAL); 1147 | 1092 if (bsd.which == -1) 1093 return (EINVAL); 1094 |
1148 error = copyin(uap->rlim, &rlim, sizeof(rlim)); | 1095 error = copyin((caddr_t)args->rlim, &rlim, sizeof(rlim)); |
1149 if (error) 1150 return (error); 1151 1152 bsd.rlp = stackgap_alloc(&sg, sizeof(struct rlimit)); 1153 bsd.rlp->rlim_cur = (rlim_t)rlim.rlim_cur; 1154 bsd.rlp->rlim_max = (rlim_t)rlim.rlim_max; 1155 return (setrlimit(p, &bsd)); 1156} 1157 1158int | 1096 if (error) 1097 return (error); 1098 1099 bsd.rlp = stackgap_alloc(&sg, sizeof(struct rlimit)); 1100 bsd.rlp->rlim_cur = (rlim_t)rlim.rlim_cur; 1101 bsd.rlp->rlim_max = (rlim_t)rlim.rlim_max; 1102 return (setrlimit(p, &bsd)); 1103} 1104 1105int |
1159linux_getrlimit(p, uap) 1160 struct proc *p; 1161 struct linux_getrlimit_args *uap; | 1106linux_old_getrlimit(struct proc *p, struct linux_old_getrlimit_args *args) |
1162{ 1163 struct __getrlimit_args bsd; | 1107{ 1108 struct __getrlimit_args bsd; |
1164 struct linux_rlimit rlim; | 1109 struct l_rlimit rlim; |
1165 int error; 1166 caddr_t sg = stackgap_init(); 1167 1168#ifdef DEBUG | 1110 int error; 1111 caddr_t sg = stackgap_init(); 1112 1113#ifdef DEBUG |
1169 if (ldebug(getrlimit)) 1170 printf(ARGS(getrlimit, "%d, %p"), 1171 uap->resource, (void *)uap->rlim); | 1114 if (ldebug(old_getrlimit)) 1115 printf(ARGS(old_getrlimit, "%d, %p"), 1116 args->resource, (void *)args->rlim); |
1172#endif 1173 | 1117#endif 1118 |
1174 if (uap->resource >= LINUX_RLIM_NLIMITS) | 1119 if (args->resource >= LINUX_RLIM_NLIMITS) |
1175 return (EINVAL); 1176 | 1120 return (EINVAL); 1121 |
1177 bsd.which = linux_to_bsd_resource[uap->resource]; | 1122 bsd.which = linux_to_bsd_resource[args->resource]; |
1178 if (bsd.which == -1) 1179 return (EINVAL); 1180 1181 bsd.rlp = stackgap_alloc(&sg, sizeof(struct rlimit)); 1182 error = getrlimit(p, &bsd); 1183 if (error) 1184 return (error); 1185 1186 rlim.rlim_cur = (unsigned long)bsd.rlp->rlim_cur; 1187 if (rlim.rlim_cur == ULONG_MAX) 1188 rlim.rlim_cur = LONG_MAX; 1189 rlim.rlim_max = (unsigned long)bsd.rlp->rlim_max; 1190 if (rlim.rlim_max == ULONG_MAX) 1191 rlim.rlim_max = LONG_MAX; | 1123 if (bsd.which == -1) 1124 return (EINVAL); 1125 1126 bsd.rlp = stackgap_alloc(&sg, sizeof(struct rlimit)); 1127 error = getrlimit(p, &bsd); 1128 if (error) 1129 return (error); 1130 1131 rlim.rlim_cur = (unsigned long)bsd.rlp->rlim_cur; 1132 if (rlim.rlim_cur == ULONG_MAX) 1133 rlim.rlim_cur = LONG_MAX; 1134 rlim.rlim_max = (unsigned long)bsd.rlp->rlim_max; 1135 if (rlim.rlim_max == ULONG_MAX) 1136 rlim.rlim_max = LONG_MAX; |
1192 return (copyout(&rlim, uap->rlim, sizeof(rlim))); | 1137 return (copyout(&rlim, (caddr_t)args->rlim, sizeof(rlim))); |
1193} | 1138} |
1139 1140int 1141linux_getrlimit(struct proc *p, struct linux_getrlimit_args *args) 1142{ 1143 struct __getrlimit_args bsd; 1144 struct l_rlimit rlim; 1145 int error; 1146 caddr_t sg = stackgap_init(); 1147 1148#ifdef DEBUG 1149 if (ldebug(getrlimit)) 1150 printf(ARGS(getrlimit, "%d, %p"), 1151 args->resource, (void *)args->rlim); 1152#endif 1153 1154 if (args->resource >= LINUX_RLIM_NLIMITS) 1155 return (EINVAL); 1156 1157 bsd.which = linux_to_bsd_resource[args->resource]; 1158 if (bsd.which == -1) 1159 return (EINVAL); 1160 1161 bsd.rlp = stackgap_alloc(&sg, sizeof(struct rlimit)); 1162 error = getrlimit(p, &bsd); 1163 if (error) 1164 return (error); 1165 1166 rlim.rlim_cur = (l_ulong)bsd.rlp->rlim_cur; 1167 rlim.rlim_max = (l_ulong)bsd.rlp->rlim_max; 1168 return (copyout(&rlim, (caddr_t)args->rlim, sizeof(rlim))); 1169} |
|
1194#endif /*!__alpha__*/ 1195 1196int | 1170#endif /*!__alpha__*/ 1171 1172int |
1197linux_sched_setscheduler(p, uap) 1198 struct proc *p; 1199 struct linux_sched_setscheduler_args *uap; | 1173linux_sched_setscheduler(struct proc *p, 1174 struct linux_sched_setscheduler_args *args) |
1200{ 1201 struct sched_setscheduler_args bsd; 1202 1203#ifdef DEBUG 1204 if (ldebug(sched_setscheduler)) 1205 printf(ARGS(sched_setscheduler, "%d, %d, %p"), | 1175{ 1176 struct sched_setscheduler_args bsd; 1177 1178#ifdef DEBUG 1179 if (ldebug(sched_setscheduler)) 1180 printf(ARGS(sched_setscheduler, "%d, %d, %p"), |
1206 uap->pid, uap->policy, (const void *)uap->param); | 1181 args->pid, args->policy, (const void *)args->param); |
1207#endif 1208 | 1182#endif 1183 |
1209 switch (uap->policy) { | 1184 switch (args->policy) { |
1210 case LINUX_SCHED_OTHER: 1211 bsd.policy = SCHED_OTHER; 1212 break; 1213 case LINUX_SCHED_FIFO: 1214 bsd.policy = SCHED_FIFO; 1215 break; 1216 case LINUX_SCHED_RR: 1217 bsd.policy = SCHED_RR; 1218 break; 1219 default: 1220 return EINVAL; 1221 } 1222 | 1185 case LINUX_SCHED_OTHER: 1186 bsd.policy = SCHED_OTHER; 1187 break; 1188 case LINUX_SCHED_FIFO: 1189 bsd.policy = SCHED_FIFO; 1190 break; 1191 case LINUX_SCHED_RR: 1192 bsd.policy = SCHED_RR; 1193 break; 1194 default: 1195 return EINVAL; 1196 } 1197 |
1223 bsd.pid = uap->pid; 1224 bsd.param = uap->param; | 1198 bsd.pid = args->pid; 1199 bsd.param = (struct sched_param *)args->param; |
1225 return sched_setscheduler(p, &bsd); 1226} 1227 1228int | 1200 return sched_setscheduler(p, &bsd); 1201} 1202 1203int |
1229linux_sched_getscheduler(p, uap) 1230 struct proc *p; 1231 struct linux_sched_getscheduler_args *uap; | 1204linux_sched_getscheduler(struct proc *p, 1205 struct linux_sched_getscheduler_args *args) |
1232{ 1233 struct sched_getscheduler_args bsd; 1234 int error; 1235 1236#ifdef DEBUG 1237 if (ldebug(sched_getscheduler)) | 1206{ 1207 struct sched_getscheduler_args bsd; 1208 int error; 1209 1210#ifdef DEBUG 1211 if (ldebug(sched_getscheduler)) |
1238 printf(ARGS(sched_getscheduler, "%d"), uap->pid); | 1212 printf(ARGS(sched_getscheduler, "%d"), args->pid); |
1239#endif 1240 | 1213#endif 1214 |
1241 bsd.pid = uap->pid; | 1215 bsd.pid = args->pid; |
1242 error = sched_getscheduler(p, &bsd); 1243 1244 switch (p->p_retval[0]) { 1245 case SCHED_OTHER: 1246 p->p_retval[0] = LINUX_SCHED_OTHER; 1247 break; 1248 case SCHED_FIFO: 1249 p->p_retval[0] = LINUX_SCHED_FIFO; 1250 break; 1251 case SCHED_RR: 1252 p->p_retval[0] = LINUX_SCHED_RR; 1253 break; 1254 } 1255 1256 return error; 1257} 1258 1259int | 1216 error = sched_getscheduler(p, &bsd); 1217 1218 switch (p->p_retval[0]) { 1219 case SCHED_OTHER: 1220 p->p_retval[0] = LINUX_SCHED_OTHER; 1221 break; 1222 case SCHED_FIFO: 1223 p->p_retval[0] = LINUX_SCHED_FIFO; 1224 break; 1225 case SCHED_RR: 1226 p->p_retval[0] = LINUX_SCHED_RR; 1227 break; 1228 } 1229 1230 return error; 1231} 1232 1233int |
1260linux_sched_get_priority_max(p, uap) 1261 struct proc *p; 1262 struct linux_sched_get_priority_max_args *uap; | 1234linux_sched_get_priority_max(struct proc *p, 1235 struct linux_sched_get_priority_max_args *args) |
1263{ 1264 struct sched_get_priority_max_args bsd; 1265 1266#ifdef DEBUG 1267 if (ldebug(sched_get_priority_max)) | 1236{ 1237 struct sched_get_priority_max_args bsd; 1238 1239#ifdef DEBUG 1240 if (ldebug(sched_get_priority_max)) |
1268 printf(ARGS(sched_get_priority_max, "%d"), uap->policy); | 1241 printf(ARGS(sched_get_priority_max, "%d"), args->policy); |
1269#endif 1270 | 1242#endif 1243 |
1271 switch (uap->policy) { | 1244 switch (args->policy) { |
1272 case LINUX_SCHED_OTHER: 1273 bsd.policy = SCHED_OTHER; 1274 break; 1275 case LINUX_SCHED_FIFO: 1276 bsd.policy = SCHED_FIFO; 1277 break; 1278 case LINUX_SCHED_RR: 1279 bsd.policy = SCHED_RR; 1280 break; 1281 default: 1282 return EINVAL; 1283 } 1284 return sched_get_priority_max(p, &bsd); 1285} 1286 1287int | 1245 case LINUX_SCHED_OTHER: 1246 bsd.policy = SCHED_OTHER; 1247 break; 1248 case LINUX_SCHED_FIFO: 1249 bsd.policy = SCHED_FIFO; 1250 break; 1251 case LINUX_SCHED_RR: 1252 bsd.policy = SCHED_RR; 1253 break; 1254 default: 1255 return EINVAL; 1256 } 1257 return sched_get_priority_max(p, &bsd); 1258} 1259 1260int |
1288linux_sched_get_priority_min(p, uap) 1289 struct proc *p; 1290 struct linux_sched_get_priority_min_args *uap; | 1261linux_sched_get_priority_min(struct proc *p, 1262 struct linux_sched_get_priority_min_args *args) |
1291{ 1292 struct sched_get_priority_min_args bsd; 1293 1294#ifdef DEBUG 1295 if (ldebug(sched_get_priority_min)) | 1263{ 1264 struct sched_get_priority_min_args bsd; 1265 1266#ifdef DEBUG 1267 if (ldebug(sched_get_priority_min)) |
1296 printf(ARGS(sched_get_priority_min, "%d"), uap->policy); | 1268 printf(ARGS(sched_get_priority_min, "%d"), args->policy); |
1297#endif 1298 | 1269#endif 1270 |
1299 switch (uap->policy) { | 1271 switch (args->policy) { |
1300 case LINUX_SCHED_OTHER: 1301 bsd.policy = SCHED_OTHER; 1302 break; 1303 case LINUX_SCHED_FIFO: 1304 bsd.policy = SCHED_FIFO; 1305 break; 1306 case LINUX_SCHED_RR: 1307 bsd.policy = SCHED_RR; --- 10 unchanged lines hidden (view full) --- 1318 1319int 1320linux_reboot(struct proc *p, struct linux_reboot_args *args) 1321{ 1322 struct reboot_args bsd_args; 1323 1324#ifdef DEBUG 1325 if (ldebug(reboot)) | 1272 case LINUX_SCHED_OTHER: 1273 bsd.policy = SCHED_OTHER; 1274 break; 1275 case LINUX_SCHED_FIFO: 1276 bsd.policy = SCHED_FIFO; 1277 break; 1278 case LINUX_SCHED_RR: 1279 bsd.policy = SCHED_RR; --- 10 unchanged lines hidden (view full) --- 1290 1291int 1292linux_reboot(struct proc *p, struct linux_reboot_args *args) 1293{ 1294 struct reboot_args bsd_args; 1295 1296#ifdef DEBUG 1297 if (ldebug(reboot)) |
1326 printf(ARGS(reboot, "0x%x"), args->opt); | 1298 printf(ARGS(reboot, "0x%x"), args->cmd); |
1327#endif | 1299#endif |
1328 if (args->opt == REBOOT_CAD_ON || args->opt == REBOOT_CAD_OFF) | 1300 if (args->cmd == REBOOT_CAD_ON || args->cmd == REBOOT_CAD_OFF) |
1329 return (0); | 1301 return (0); |
1330 bsd_args.opt = args->opt == REBOOT_HALT ? RB_HALT : 0; | 1302 bsd_args.opt = (args->cmd == REBOOT_HALT) ? RB_HALT : 0; |
1331 return (reboot(p, &bsd_args)); 1332} | 1303 return (reboot(p, &bsd_args)); 1304} |
1305 1306/* 1307 * The FreeBSD native getpid(2), getgid(2) and getuid(2) also modify 1308 * p->p_retval[1] when COMPAT_43 or COMPAT_SUNOS is defined. This 1309 * globbers registers that are assumed to be preserved. The following 1310 * lightweight syscalls fixes this. See also linux_getgid16() and 1311 * linux_getuid16() in linux_uid16.c. 1312 * 1313 * linux_getpid() - MP SAFE 1314 * linux_getgid() - MP SAFE 1315 * linux_getuid() - MP SAFE 1316 */ 1317 1318int 1319linux_getpid(struct proc *p, struct linux_getpid_args *args) 1320{ 1321 p->p_retval[0] = p->p_pid; 1322 return (0); 1323} 1324 1325int 1326linux_getgid(struct proc *p, struct linux_getgid_args *args) 1327{ 1328 p->p_retval[0] = p->p_ucred->cr_rgid; 1329 return (0); 1330} 1331 1332int 1333linux_getuid(struct proc *p, struct linux_getuid_args *args) 1334{ 1335 p->p_retval[0] = p->p_ucred->cr_ruid; 1336 return (0); 1337} |
|