115 116 if ((vm_offset_t)args->dsend < (vm_offset_t)vm->vm_daddr) 117 return EINVAL; 118 if (((caddr_t)args->dsend - (caddr_t)vm->vm_daddr) 119 > p->p_rlimit[RLIMIT_DATA].rlim_cur) 120 return ENOMEM; 121 122 old = round_page((vm_offset_t)vm->vm_daddr) + ctob(vm->vm_dsize); 123 new = round_page((vm_offset_t)args->dsend); 124 *retval = old; 125 if ((new-old) > 0) { 126 if (swap_pager_full) 127 return ENOMEM; 128 error = vm_map_find(&vm->vm_map, NULL, 0, &old, (new-old), FALSE); 129 if (error) 130 return error; 131 vm->vm_dsize += btoc((new-old)); 132 *retval = (int)(vm->vm_daddr + ctob(vm->vm_dsize)); 133 } 134 return 0; 135#else 136 struct vmspace *vm = p->p_vmspace; 137 vm_offset_t new, old; 138 struct obreak_args { 139 vm_offset_t newsize; 140 } tmp; 141 142#ifdef DEBUG 143 printf("Linux-emul(%d): brk(%08x)\n", p->p_pid, args->dsend); 144#endif 145 old = (vm_offset_t)vm->vm_daddr + ctob(vm->vm_dsize); 146 new = (vm_offset_t)args->dsend; 147 tmp.newsize = new; 148 if (((caddr_t)new > vm->vm_daddr) && !obreak(p, &tmp, retval)) 149 retval[0] = (int)new; 150 else 151 retval[0] = (int)old; 152 153 return 0; 154#endif 155} 156 157struct linux_uselib_args { 158 char *library; 159}; 160 161int 162linux_uselib(struct proc *p, struct linux_uselib_args *args, int *retval) 163{ 164 struct nameidata ni; 165 struct vnode *vp; 166 struct exec *a_out = 0; 167 struct vattr attr; 168 unsigned long vmaddr, virtual_offset, file_offset; 169 unsigned long buffer, bss_size; 170 char *ptr; 171 char path[MAXPATHLEN]; 172 const char *prefix = "/compat/linux"; 173 size_t sz, len; 174 int error; 175 176#ifdef DEBUG 177 printf("Linux-emul(%d): uselib(%s)\n", p->p_pid, args->library); 178#endif 179 180 for (ptr = path; (*ptr = *prefix) != '\0'; ptr++, prefix++) ; 181 sz = MAXPATHLEN - (ptr - path); 182 if (error = copyinstr(args->library, ptr, sz, &len)) 183 return error; 184 if (*ptr != '/') 185 return EINVAL; 186 187#ifdef DEBUG 188 printf("Linux-emul(%d): uselib(%s)\n", p->p_pid, path); 189#endif 190 191 NDINIT(&ni, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p); 192 if (error = namei(&ni)) 193 return error; 194 195 vp = ni.ni_vp; 196 if (vp == NULL) 197 return ENOEXEC; 198 199 if (vp->v_writecount) { 200 VOP_UNLOCK(vp); 201 return ETXTBSY; 202 } 203 204 if (error = VOP_GETATTR(vp, &attr, p->p_ucred, p)) { 205 VOP_UNLOCK(vp); 206 return error; 207 } 208 209 if ((vp->v_mount->mnt_flag & MNT_NOEXEC) 210 || ((attr.va_mode & 0111) == 0) 211 || (attr.va_type != VREG)) { 212 VOP_UNLOCK(vp); 213 return ENOEXEC; 214 } 215 216 if (attr.va_size == 0) { 217 VOP_UNLOCK(vp); 218 return ENOEXEC; 219 } 220 221 if (error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p)) { 222 VOP_UNLOCK(vp); 223 return error; 224 } 225 226 if (error = VOP_OPEN(vp, FREAD, p->p_ucred, p)) { 227 VOP_UNLOCK(vp); 228 return error; 229 } 230 231 VOP_UNLOCK(vp); /* lock no longer needed */ 232 233 error = vm_mmap(kernel_map, (vm_offset_t *)&a_out, 1024, 234 VM_PROT_READ, VM_PROT_READ, 0, (caddr_t)vp, 0); 235 if (error) 236 return (error); 237 238 /* 239 * Is it a Linux binary ? 240 */ 241 if (((a_out->a_magic >> 16) & 0xff) != 0x64) 242 return ENOEXEC; 243 244 /* 245 * Set file/virtual offset based on a.out variant. 246 */ 247 switch ((int)(a_out->a_magic & 0xffff)) { 248 case 0413: /* ZMAGIC */ 249 virtual_offset = 0; 250 file_offset = 1024; 251 break; 252 case 0314: /* QMAGIC */ 253 virtual_offset = 4096; 254 file_offset = 0; 255 break; 256 default: 257 return ENOEXEC; 258 } 259 260 vp->v_flag |= VTEXT; 261 bss_size = round_page(a_out->a_bss); 262 /* 263 * Check if file_offset page aligned,. 264 * Currently we cannot handle misalinged file offsets, 265 * and so we read in the entire image (what a waste). 266 */ 267 if (file_offset & PGOFSET) { 268#ifdef DEBUG 269printf("uselib: Non page aligned binary %d\n", file_offset); 270#endif 271 /* 272 * Map text+data read/write/execute 273 */ 274 vmaddr = virtual_offset + round_page(a_out->a_entry); 275 error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr, 276 round_page(a_out->a_text + a_out->a_data), FALSE); 277 if (error) 278 return error; 279 280 error = vm_mmap(kernel_map, &buffer, 281 round_page(a_out->a_text + a_out->a_data + file_offset), 282 VM_PROT_READ, VM_PROT_READ, MAP_FILE, 283 (caddr_t)vp, trunc_page(file_offset)); 284 if (error) 285 return error; 286 287 error = copyout((caddr_t)(buffer + file_offset), (caddr_t)vmaddr, 288 a_out->a_text + a_out->a_data); 289 if (error) 290 return error; 291 292 vm_map_remove(kernel_map, trunc_page(vmaddr), 293 round_page(a_out->a_text + a_out->a_data + file_offset)); 294 295 error = vm_map_protect(&p->p_vmspace->vm_map, vmaddr, 296 round_page(a_out->a_text + a_out->a_data), 297 VM_PROT_ALL, TRUE); 298 if (error) 299 return error; 300 } 301 else { 302#ifdef DEBUG 303printf("uselib: Page aligned binary %d\n", file_offset); 304#endif 305 vmaddr = virtual_offset + round_page(a_out->a_entry); 306 error = vm_mmap(&p->p_vmspace->vm_map, &vmaddr, 307 a_out->a_text + a_out->a_data, 308 VM_PROT_ALL, VM_PROT_ALL, MAP_PRIVATE | MAP_FIXED, 309 (caddr_t)vp, file_offset); 310 if (error) 311 return (error); 312 } 313#ifdef DEBUG 314printf("mem=%08x = %08x %08x\n", vmaddr, ((int*)vmaddr)[0], ((int*)vmaddr)[1]); 315#endif 316 if (bss_size != 0) { 317 vmaddr = virtual_offset + round_page(a_out->a_entry) + 318 round_page(a_out->a_text + a_out->a_data); 319 error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr, 320 bss_size, FALSE); 321 if (error) 322 return error; 323 error = vm_map_protect(&p->p_vmspace->vm_map, vmaddr, bss_size, 324 VM_PROT_ALL, TRUE); 325 if (error) 326 return error; 327 } 328 return 0; 329} 330 331struct linux_select_args { 332 void *ptr; 333}; 334 335int 336linux_select(struct proc *p, struct linux_select_args *args, int *retval) 337{ 338 struct { 339 int nfds; 340 fd_set *readfds; 341 fd_set *writefds; 342 fd_set *exceptfds; 343 struct timeval *timeout; 344 } linux_args; 345 struct { 346 unsigned int nd; 347 fd_set *in; 348 fd_set *ou; 349 fd_set *ex; 350 struct timeval *tv; 351 } bsd_args; 352 int error; 353 354 if ((error = copyin((caddr_t)args->ptr, (caddr_t)&linux_args, 355 sizeof(linux_args)))) 356 return error; 357#ifdef DEBUG 358 printf("Linux-emul(%d): select(%d, %d, %d, %d, %d)\n", 359 p->p_pid, linux_args.nfds, linux_args.readfds, 360 linux_args.writefds, linux_args.exceptfds, 361 linux_args.timeout); 362#endif 363 bsd_args.nd = linux_args.nfds; 364 bsd_args.in = linux_args.readfds; 365 bsd_args.ou = linux_args.writefds; 366 bsd_args.ex = linux_args.exceptfds; 367 bsd_args.tv = linux_args.timeout; 368 return select(p, &bsd_args, retval); 369} 370 371struct linux_getpgid_args { 372 int pid; 373}; 374 375int 376linux_getpgid(struct proc *p, struct linux_getpgid_args *args, int *retval) 377{ 378 struct proc *curproc; 379 380#ifdef DEBUG 381 printf("Linux-emul(%d): getpgid(%d)\n", p->p_pid, args->pid); 382#endif 383 if (args->pid != p->p_pid) { 384 if (!(curproc = pfind(args->pid))) 385 return ESRCH; 386 } 387 else 388 curproc = p; 389 *retval = curproc->p_pgid; 390 return 0; 391} 392 393int 394linux_fork(struct proc *p, void *args, int *retval) 395{ 396 int error; 397 398#ifdef DEBUG 399 printf("Linux-emul(%d): fork()\n", p->p_pid); 400#endif 401 if (error = fork(p, args, retval)) 402 return error; 403 if (retval[1] == 1) 404 retval[0] = 0; 405 return 0; 406} 407 408struct linux_mmap_args { 409 void *ptr; 410}; 411 412int 413linux_mmap(struct proc *p, struct linux_mmap_args *args, int *retval) 414{ 415 struct { 416 linux_caddr_t addr; 417 int len; 418 int prot; 419 int flags; 420 int fd; 421 int pos; 422 } linux_args; 423 struct { 424 caddr_t addr; 425 size_t len; 426 int prot; 427 int flags; 428 int fd; 429 long pad; 430 off_t pos; 431 } bsd_args; 432 int error; 433 434 if ((error = copyin((caddr_t)args->ptr, (caddr_t)&linux_args, 435 sizeof(linux_args)))) 436 return error; 437#ifdef DEBUG 438 printf("Linux-emul(%d): mmap(%08x, %d, %d, %08x, %d, %d)\n", 439 p->p_pid, linux_args.addr, linux_args.len, linux_args.prot, 440 linux_args.flags, linux_args.fd, linux_args.pos); 441#endif 442 bsd_args.flags = 0; 443 if (linux_args.flags & LINUX_MAP_SHARED) 444 bsd_args.flags |= MAP_SHARED; 445 if (linux_args.flags & LINUX_MAP_PRIVATE) 446 bsd_args.flags |= MAP_PRIVATE; 447 if (linux_args.flags & LINUX_MAP_FIXED) 448 bsd_args.flags |= MAP_FIXED; 449 if (linux_args.flags & LINUX_MAP_ANON) 450 bsd_args.flags |= MAP_ANON; 451 bsd_args.addr = linux_args.addr; 452 bsd_args.len = linux_args.len; 453 bsd_args.prot = linux_args.prot; 454 bsd_args.fd = linux_args.fd; 455 bsd_args.pos = linux_args.pos; 456 bsd_args.pad = 0; 457 return mmap(p, &bsd_args, retval); 458} 459 460struct linux_pipe_args { 461 int *pipefds; 462}; 463 464int 465linux_pipe(struct proc *p, struct linux_pipe_args *args, int *retval) 466{ 467 int error; 468 469#ifdef DEBUG 470 printf("Linux-emul(%d): pipe(*)\n", p->p_pid); 471#endif 472 if (error = pipe(p, 0, retval)) 473 return error; 474 if (error = copyout(retval, args->pipefds, 2*sizeof(int))) 475 return error; 476 *retval = 0; 477 return 0; 478} 479 480struct linux_time_args { 481 linux_time_t *tm; 482}; 483 484int 485linux_time(struct proc *p, struct linux_time_args *args, int *retval) 486{ 487 struct timeval tv; 488 linux_time_t tm; 489 int error; 490 491#ifdef DEBUG 492 printf("Linux-emul(%d): time(*)\n", p->p_pid); 493#endif 494 microtime(&tv); 495 tm = tv.tv_sec; 496 if (error = copyout(&tm, args->tm, sizeof(linux_time_t))) 497 return error; 498 *retval = tv.tv_sec; 499 return 0; 500} 501 502struct linux_tms { 503 long tms_utime; 504 long tms_stime; 505 long tms_cutime; 506 long tms_cstime; 507}; 508 509struct linux_tms_args { 510 char *buf; 511}; 512 513int 514linux_times(struct proc *p, struct linux_tms_args *args, int *retval) 515{
| 114 115 if ((vm_offset_t)args->dsend < (vm_offset_t)vm->vm_daddr) 116 return EINVAL; 117 if (((caddr_t)args->dsend - (caddr_t)vm->vm_daddr) 118 > p->p_rlimit[RLIMIT_DATA].rlim_cur) 119 return ENOMEM; 120 121 old = round_page((vm_offset_t)vm->vm_daddr) + ctob(vm->vm_dsize); 122 new = round_page((vm_offset_t)args->dsend); 123 *retval = old; 124 if ((new-old) > 0) { 125 if (swap_pager_full) 126 return ENOMEM; 127 error = vm_map_find(&vm->vm_map, NULL, 0, &old, (new-old), FALSE); 128 if (error) 129 return error; 130 vm->vm_dsize += btoc((new-old)); 131 *retval = (int)(vm->vm_daddr + ctob(vm->vm_dsize)); 132 } 133 return 0; 134#else 135 struct vmspace *vm = p->p_vmspace; 136 vm_offset_t new, old; 137 struct obreak_args { 138 vm_offset_t newsize; 139 } tmp; 140 141#ifdef DEBUG 142 printf("Linux-emul(%d): brk(%08x)\n", p->p_pid, args->dsend); 143#endif 144 old = (vm_offset_t)vm->vm_daddr + ctob(vm->vm_dsize); 145 new = (vm_offset_t)args->dsend; 146 tmp.newsize = new; 147 if (((caddr_t)new > vm->vm_daddr) && !obreak(p, &tmp, retval)) 148 retval[0] = (int)new; 149 else 150 retval[0] = (int)old; 151 152 return 0; 153#endif 154} 155 156struct linux_uselib_args { 157 char *library; 158}; 159 160int 161linux_uselib(struct proc *p, struct linux_uselib_args *args, int *retval) 162{ 163 struct nameidata ni; 164 struct vnode *vp; 165 struct exec *a_out = 0; 166 struct vattr attr; 167 unsigned long vmaddr, virtual_offset, file_offset; 168 unsigned long buffer, bss_size; 169 char *ptr; 170 char path[MAXPATHLEN]; 171 const char *prefix = "/compat/linux"; 172 size_t sz, len; 173 int error; 174 175#ifdef DEBUG 176 printf("Linux-emul(%d): uselib(%s)\n", p->p_pid, args->library); 177#endif 178 179 for (ptr = path; (*ptr = *prefix) != '\0'; ptr++, prefix++) ; 180 sz = MAXPATHLEN - (ptr - path); 181 if (error = copyinstr(args->library, ptr, sz, &len)) 182 return error; 183 if (*ptr != '/') 184 return EINVAL; 185 186#ifdef DEBUG 187 printf("Linux-emul(%d): uselib(%s)\n", p->p_pid, path); 188#endif 189 190 NDINIT(&ni, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p); 191 if (error = namei(&ni)) 192 return error; 193 194 vp = ni.ni_vp; 195 if (vp == NULL) 196 return ENOEXEC; 197 198 if (vp->v_writecount) { 199 VOP_UNLOCK(vp); 200 return ETXTBSY; 201 } 202 203 if (error = VOP_GETATTR(vp, &attr, p->p_ucred, p)) { 204 VOP_UNLOCK(vp); 205 return error; 206 } 207 208 if ((vp->v_mount->mnt_flag & MNT_NOEXEC) 209 || ((attr.va_mode & 0111) == 0) 210 || (attr.va_type != VREG)) { 211 VOP_UNLOCK(vp); 212 return ENOEXEC; 213 } 214 215 if (attr.va_size == 0) { 216 VOP_UNLOCK(vp); 217 return ENOEXEC; 218 } 219 220 if (error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p)) { 221 VOP_UNLOCK(vp); 222 return error; 223 } 224 225 if (error = VOP_OPEN(vp, FREAD, p->p_ucred, p)) { 226 VOP_UNLOCK(vp); 227 return error; 228 } 229 230 VOP_UNLOCK(vp); /* lock no longer needed */ 231 232 error = vm_mmap(kernel_map, (vm_offset_t *)&a_out, 1024, 233 VM_PROT_READ, VM_PROT_READ, 0, (caddr_t)vp, 0); 234 if (error) 235 return (error); 236 237 /* 238 * Is it a Linux binary ? 239 */ 240 if (((a_out->a_magic >> 16) & 0xff) != 0x64) 241 return ENOEXEC; 242 243 /* 244 * Set file/virtual offset based on a.out variant. 245 */ 246 switch ((int)(a_out->a_magic & 0xffff)) { 247 case 0413: /* ZMAGIC */ 248 virtual_offset = 0; 249 file_offset = 1024; 250 break; 251 case 0314: /* QMAGIC */ 252 virtual_offset = 4096; 253 file_offset = 0; 254 break; 255 default: 256 return ENOEXEC; 257 } 258 259 vp->v_flag |= VTEXT; 260 bss_size = round_page(a_out->a_bss); 261 /* 262 * Check if file_offset page aligned,. 263 * Currently we cannot handle misalinged file offsets, 264 * and so we read in the entire image (what a waste). 265 */ 266 if (file_offset & PGOFSET) { 267#ifdef DEBUG 268printf("uselib: Non page aligned binary %d\n", file_offset); 269#endif 270 /* 271 * Map text+data read/write/execute 272 */ 273 vmaddr = virtual_offset + round_page(a_out->a_entry); 274 error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr, 275 round_page(a_out->a_text + a_out->a_data), FALSE); 276 if (error) 277 return error; 278 279 error = vm_mmap(kernel_map, &buffer, 280 round_page(a_out->a_text + a_out->a_data + file_offset), 281 VM_PROT_READ, VM_PROT_READ, MAP_FILE, 282 (caddr_t)vp, trunc_page(file_offset)); 283 if (error) 284 return error; 285 286 error = copyout((caddr_t)(buffer + file_offset), (caddr_t)vmaddr, 287 a_out->a_text + a_out->a_data); 288 if (error) 289 return error; 290 291 vm_map_remove(kernel_map, trunc_page(vmaddr), 292 round_page(a_out->a_text + a_out->a_data + file_offset)); 293 294 error = vm_map_protect(&p->p_vmspace->vm_map, vmaddr, 295 round_page(a_out->a_text + a_out->a_data), 296 VM_PROT_ALL, TRUE); 297 if (error) 298 return error; 299 } 300 else { 301#ifdef DEBUG 302printf("uselib: Page aligned binary %d\n", file_offset); 303#endif 304 vmaddr = virtual_offset + round_page(a_out->a_entry); 305 error = vm_mmap(&p->p_vmspace->vm_map, &vmaddr, 306 a_out->a_text + a_out->a_data, 307 VM_PROT_ALL, VM_PROT_ALL, MAP_PRIVATE | MAP_FIXED, 308 (caddr_t)vp, file_offset); 309 if (error) 310 return (error); 311 } 312#ifdef DEBUG 313printf("mem=%08x = %08x %08x\n", vmaddr, ((int*)vmaddr)[0], ((int*)vmaddr)[1]); 314#endif 315 if (bss_size != 0) { 316 vmaddr = virtual_offset + round_page(a_out->a_entry) + 317 round_page(a_out->a_text + a_out->a_data); 318 error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr, 319 bss_size, FALSE); 320 if (error) 321 return error; 322 error = vm_map_protect(&p->p_vmspace->vm_map, vmaddr, bss_size, 323 VM_PROT_ALL, TRUE); 324 if (error) 325 return error; 326 } 327 return 0; 328} 329 330struct linux_select_args { 331 void *ptr; 332}; 333 334int 335linux_select(struct proc *p, struct linux_select_args *args, int *retval) 336{ 337 struct { 338 int nfds; 339 fd_set *readfds; 340 fd_set *writefds; 341 fd_set *exceptfds; 342 struct timeval *timeout; 343 } linux_args; 344 struct { 345 unsigned int nd; 346 fd_set *in; 347 fd_set *ou; 348 fd_set *ex; 349 struct timeval *tv; 350 } bsd_args; 351 int error; 352 353 if ((error = copyin((caddr_t)args->ptr, (caddr_t)&linux_args, 354 sizeof(linux_args)))) 355 return error; 356#ifdef DEBUG 357 printf("Linux-emul(%d): select(%d, %d, %d, %d, %d)\n", 358 p->p_pid, linux_args.nfds, linux_args.readfds, 359 linux_args.writefds, linux_args.exceptfds, 360 linux_args.timeout); 361#endif 362 bsd_args.nd = linux_args.nfds; 363 bsd_args.in = linux_args.readfds; 364 bsd_args.ou = linux_args.writefds; 365 bsd_args.ex = linux_args.exceptfds; 366 bsd_args.tv = linux_args.timeout; 367 return select(p, &bsd_args, retval); 368} 369 370struct linux_getpgid_args { 371 int pid; 372}; 373 374int 375linux_getpgid(struct proc *p, struct linux_getpgid_args *args, int *retval) 376{ 377 struct proc *curproc; 378 379#ifdef DEBUG 380 printf("Linux-emul(%d): getpgid(%d)\n", p->p_pid, args->pid); 381#endif 382 if (args->pid != p->p_pid) { 383 if (!(curproc = pfind(args->pid))) 384 return ESRCH; 385 } 386 else 387 curproc = p; 388 *retval = curproc->p_pgid; 389 return 0; 390} 391 392int 393linux_fork(struct proc *p, void *args, int *retval) 394{ 395 int error; 396 397#ifdef DEBUG 398 printf("Linux-emul(%d): fork()\n", p->p_pid); 399#endif 400 if (error = fork(p, args, retval)) 401 return error; 402 if (retval[1] == 1) 403 retval[0] = 0; 404 return 0; 405} 406 407struct linux_mmap_args { 408 void *ptr; 409}; 410 411int 412linux_mmap(struct proc *p, struct linux_mmap_args *args, int *retval) 413{ 414 struct { 415 linux_caddr_t addr; 416 int len; 417 int prot; 418 int flags; 419 int fd; 420 int pos; 421 } linux_args; 422 struct { 423 caddr_t addr; 424 size_t len; 425 int prot; 426 int flags; 427 int fd; 428 long pad; 429 off_t pos; 430 } bsd_args; 431 int error; 432 433 if ((error = copyin((caddr_t)args->ptr, (caddr_t)&linux_args, 434 sizeof(linux_args)))) 435 return error; 436#ifdef DEBUG 437 printf("Linux-emul(%d): mmap(%08x, %d, %d, %08x, %d, %d)\n", 438 p->p_pid, linux_args.addr, linux_args.len, linux_args.prot, 439 linux_args.flags, linux_args.fd, linux_args.pos); 440#endif 441 bsd_args.flags = 0; 442 if (linux_args.flags & LINUX_MAP_SHARED) 443 bsd_args.flags |= MAP_SHARED; 444 if (linux_args.flags & LINUX_MAP_PRIVATE) 445 bsd_args.flags |= MAP_PRIVATE; 446 if (linux_args.flags & LINUX_MAP_FIXED) 447 bsd_args.flags |= MAP_FIXED; 448 if (linux_args.flags & LINUX_MAP_ANON) 449 bsd_args.flags |= MAP_ANON; 450 bsd_args.addr = linux_args.addr; 451 bsd_args.len = linux_args.len; 452 bsd_args.prot = linux_args.prot; 453 bsd_args.fd = linux_args.fd; 454 bsd_args.pos = linux_args.pos; 455 bsd_args.pad = 0; 456 return mmap(p, &bsd_args, retval); 457} 458 459struct linux_pipe_args { 460 int *pipefds; 461}; 462 463int 464linux_pipe(struct proc *p, struct linux_pipe_args *args, int *retval) 465{ 466 int error; 467 468#ifdef DEBUG 469 printf("Linux-emul(%d): pipe(*)\n", p->p_pid); 470#endif 471 if (error = pipe(p, 0, retval)) 472 return error; 473 if (error = copyout(retval, args->pipefds, 2*sizeof(int))) 474 return error; 475 *retval = 0; 476 return 0; 477} 478 479struct linux_time_args { 480 linux_time_t *tm; 481}; 482 483int 484linux_time(struct proc *p, struct linux_time_args *args, int *retval) 485{ 486 struct timeval tv; 487 linux_time_t tm; 488 int error; 489 490#ifdef DEBUG 491 printf("Linux-emul(%d): time(*)\n", p->p_pid); 492#endif 493 microtime(&tv); 494 tm = tv.tv_sec; 495 if (error = copyout(&tm, args->tm, sizeof(linux_time_t))) 496 return error; 497 *retval = tv.tv_sec; 498 return 0; 499} 500 501struct linux_tms { 502 long tms_utime; 503 long tms_stime; 504 long tms_cutime; 505 long tms_cstime; 506}; 507 508struct linux_tms_args { 509 char *buf; 510}; 511 512int 513linux_times(struct proc *p, struct linux_tms_args *args, int *retval) 514{
|
554 555#ifdef DEBUG 556 printf("Linux-emul(%d): newuname(*)\n", p->p_pid); 557#endif 558 bzero(&linux_newuname, sizeof(struct linux_newuname_args)); 559 strncpy(linux_newuname.sysname, ostype, 64); 560 strncpy(linux_newuname.nodename, hostname, 64); 561 strncpy(linux_newuname.release, osrelease, 64); 562 strncpy(linux_newuname.version, version, 64); 563 strncpy(linux_newuname.machine, machine, 64); 564 strncpy(linux_newuname.domainname, domainname, 64); 565 return (copyout((caddr_t)&linux_newuname, (caddr_t)args->buf, 566 sizeof(struct linux_newuname_t))); 567} 568 569struct linux_utime_args { 570 char *fname; 571 linux_time_t *timeptr; 572}; 573 574int 575linux_utime(struct proc *p, struct linux_utime_args *args, int *retval) 576{ 577 struct bsd_utimes_args { 578 char *fname; 579 struct timeval *tptr; 580 } bsdutimes; 581 struct timeval tv; 582 583#ifdef DEBUG 584 printf("Linux-emul(%d): utime(%s, *)\n", p->p_pid, args->fname); 585#endif 586 tv.tv_sec = (long)args->timeptr; 587 tv.tv_usec = 0; 588 bsdutimes.tptr = &tv; 589 bsdutimes.fname = args->fname; 590 return utimes(p, &bsdutimes, retval); 591} 592 593struct linux_waitpid_args { 594 int pid; 595 int *status; 596 int options; 597}; 598 599int 600linux_waitpid(struct proc *p, struct linux_waitpid_args *args, int *retval) 601{ 602 struct wait4_args { 603 int pid; 604 int *status; 605 int options; 606 struct rusage *rusage; 607 int compat; 608 } tmp; 609 int error, tmpstat; 610 611#ifdef DEBUG 612 printf("Linux-emul(%d): waitpid(%d, *, %d)\n", 613 p->p_pid, args->pid, args->options); 614#endif 615 tmp.pid = args->pid; 616 tmp.status = args->status; 617 tmp.options = args->options; 618 tmp.rusage = NULL; 619 tmp.compat = 0; 620 621 if (error = wait4(p, &tmp, retval)) 622 return error; 623 if (error = copyin(args->status, &tmpstat, sizeof(int))) 624 return error; 625 if (WIFSIGNALED(tmpstat)) 626 tmpstat = (tmpstat & 0xffffff80) | 627 bsd_to_linux_signal[WTERMSIG(tmpstat)]; 628 else if (WIFSTOPPED(tmpstat)) 629 tmpstat = (tmpstat & 0xffff00ff) | 630 (bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8); 631 return copyout(&tmpstat, args->status, sizeof(int)); 632} 633 634struct linux_wait4_args { 635 int pid; 636 int *status; 637 int options; 638 struct rusage *rusage; 639}; 640 641int 642linux_wait4(struct proc *p, struct linux_wait4_args *args, int *retval) 643{ 644 struct wait4_args { 645 int pid; 646 int *status; 647 int options; 648 struct rusage *rusage; 649 int compat; 650 } tmp; 651 int error, tmpstat; 652 653#ifdef DEBUG 654 printf("Linux-emul(%d): wait4(%d, *, %d, *)\n", 655 p->p_pid, args->pid, args->options); 656#endif 657 tmp.pid = args->pid; 658 tmp.status = args->status; 659 tmp.options = args->options; 660 tmp.rusage = args->rusage; 661 tmp.compat = 0; 662 663 if (error = wait4(p, &tmp, retval)) 664 return error; 665 if (error = copyin(args->status, &tmpstat, sizeof(int))) 666 return error; 667 if (WIFSIGNALED(tmpstat)) 668 tmpstat = (tmpstat & 0xffffff80) | 669 bsd_to_linux_signal[WTERMSIG(tmpstat)]; 670 else if (WIFSTOPPED(tmpstat)) 671 tmpstat = (tmpstat & 0xffff00ff) | 672 (bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8); 673 return copyout(&tmpstat, args->status, sizeof(int)); 674}
| 550 551#ifdef DEBUG 552 printf("Linux-emul(%d): newuname(*)\n", p->p_pid); 553#endif 554 bzero(&linux_newuname, sizeof(struct linux_newuname_args)); 555 strncpy(linux_newuname.sysname, ostype, 64); 556 strncpy(linux_newuname.nodename, hostname, 64); 557 strncpy(linux_newuname.release, osrelease, 64); 558 strncpy(linux_newuname.version, version, 64); 559 strncpy(linux_newuname.machine, machine, 64); 560 strncpy(linux_newuname.domainname, domainname, 64); 561 return (copyout((caddr_t)&linux_newuname, (caddr_t)args->buf, 562 sizeof(struct linux_newuname_t))); 563} 564 565struct linux_utime_args { 566 char *fname; 567 linux_time_t *timeptr; 568}; 569 570int 571linux_utime(struct proc *p, struct linux_utime_args *args, int *retval) 572{ 573 struct bsd_utimes_args { 574 char *fname; 575 struct timeval *tptr; 576 } bsdutimes; 577 struct timeval tv; 578 579#ifdef DEBUG 580 printf("Linux-emul(%d): utime(%s, *)\n", p->p_pid, args->fname); 581#endif 582 tv.tv_sec = (long)args->timeptr; 583 tv.tv_usec = 0; 584 bsdutimes.tptr = &tv; 585 bsdutimes.fname = args->fname; 586 return utimes(p, &bsdutimes, retval); 587} 588 589struct linux_waitpid_args { 590 int pid; 591 int *status; 592 int options; 593}; 594 595int 596linux_waitpid(struct proc *p, struct linux_waitpid_args *args, int *retval) 597{ 598 struct wait4_args { 599 int pid; 600 int *status; 601 int options; 602 struct rusage *rusage; 603 int compat; 604 } tmp; 605 int error, tmpstat; 606 607#ifdef DEBUG 608 printf("Linux-emul(%d): waitpid(%d, *, %d)\n", 609 p->p_pid, args->pid, args->options); 610#endif 611 tmp.pid = args->pid; 612 tmp.status = args->status; 613 tmp.options = args->options; 614 tmp.rusage = NULL; 615 tmp.compat = 0; 616 617 if (error = wait4(p, &tmp, retval)) 618 return error; 619 if (error = copyin(args->status, &tmpstat, sizeof(int))) 620 return error; 621 if (WIFSIGNALED(tmpstat)) 622 tmpstat = (tmpstat & 0xffffff80) | 623 bsd_to_linux_signal[WTERMSIG(tmpstat)]; 624 else if (WIFSTOPPED(tmpstat)) 625 tmpstat = (tmpstat & 0xffff00ff) | 626 (bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8); 627 return copyout(&tmpstat, args->status, sizeof(int)); 628} 629 630struct linux_wait4_args { 631 int pid; 632 int *status; 633 int options; 634 struct rusage *rusage; 635}; 636 637int 638linux_wait4(struct proc *p, struct linux_wait4_args *args, int *retval) 639{ 640 struct wait4_args { 641 int pid; 642 int *status; 643 int options; 644 struct rusage *rusage; 645 int compat; 646 } tmp; 647 int error, tmpstat; 648 649#ifdef DEBUG 650 printf("Linux-emul(%d): wait4(%d, *, %d, *)\n", 651 p->p_pid, args->pid, args->options); 652#endif 653 tmp.pid = args->pid; 654 tmp.status = args->status; 655 tmp.options = args->options; 656 tmp.rusage = args->rusage; 657 tmp.compat = 0; 658 659 if (error = wait4(p, &tmp, retval)) 660 return error; 661 if (error = copyin(args->status, &tmpstat, sizeof(int))) 662 return error; 663 if (WIFSIGNALED(tmpstat)) 664 tmpstat = (tmpstat & 0xffffff80) | 665 bsd_to_linux_signal[WTERMSIG(tmpstat)]; 666 else if (WIFSTOPPED(tmpstat)) 667 tmpstat = (tmpstat & 0xffff00ff) | 668 (bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8); 669 return copyout(&tmpstat, args->status, sizeof(int)); 670}
|