linux_file.c revision 24672
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 9 * notice, this list of conditions and the following disclaimer 10 * in this position and unchanged. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software withough specific prior written permission 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 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 * $Id: linux_file.c,v 1.13 1997/04/05 14:50:56 dfr Exp $ 29 */ 30 31#include <sys/param.h> 32#include <sys/systm.h> 33#include <sys/sysproto.h> 34#include <sys/fcntl.h> 35#include <sys/file.h> 36#include <sys/filedesc.h> 37#include <sys/proc.h> 38#include <sys/vnode.h> 39#include <sys/malloc.h> 40#include <sys/dirent.h> 41#include <sys/conf.h> 42#include <sys/tty.h> 43 44#include <i386/linux/linux.h> 45#include <i386/linux/linux_proto.h> 46#include <i386/linux/linux_util.h> 47 48int 49linux_creat(struct proc *p, struct linux_creat_args *args, int *retval) 50{ 51 struct open_args /* { 52 char *path; 53 int flags; 54 int mode; 55 } */ bsd_open_args; 56 caddr_t sg; 57 58 sg = stackgap_init(); 59 CHECKALTCREAT(p, &sg, args->path); 60 61#ifdef DEBUG 62 printf("Linux-emul(%d): creat(%s, %d)\n", 63 p->p_pid, args->path, args->mode); 64#endif 65 bsd_open_args.path = args->path; 66 bsd_open_args.mode = args->mode; 67 bsd_open_args.flags = O_WRONLY | O_CREAT | O_TRUNC; 68 return open(p, &bsd_open_args, retval); 69} 70 71int 72linux_open(struct proc *p, struct linux_open_args *args, int *retval) 73{ 74 struct open_args /* { 75 char *path; 76 int flags; 77 int mode; 78 } */ bsd_open_args; 79 int error; 80 caddr_t sg; 81 82 sg = stackgap_init(); 83 84 if (args->flags & LINUX_O_CREAT) 85 CHECKALTCREAT(p, &sg, args->path); 86 else 87 CHECKALTEXIST(p, &sg, args->path); 88 89#ifdef DEBUG 90 printf("Linux-emul(%d): open(%s, 0x%x, 0x%x)\n", 91 p->p_pid, args->path, args->flags, args->mode); 92#endif 93 bsd_open_args.flags = 0; 94 if (args->flags & LINUX_O_RDONLY) 95 bsd_open_args.flags |= O_RDONLY; 96 if (args->flags & LINUX_O_WRONLY) 97 bsd_open_args.flags |= O_WRONLY; 98 if (args->flags & LINUX_O_RDWR) 99 bsd_open_args.flags |= O_RDWR; 100 if (args->flags & LINUX_O_NDELAY) 101 bsd_open_args.flags |= O_NONBLOCK; 102 if (args->flags & LINUX_O_APPEND) 103 bsd_open_args.flags |= O_APPEND; 104 if (args->flags & LINUX_O_SYNC) 105 bsd_open_args.flags |= O_FSYNC; 106 if (args->flags & LINUX_O_NONBLOCK) 107 bsd_open_args.flags |= O_NONBLOCK; 108 if (args->flags & LINUX_FASYNC) 109 bsd_open_args.flags |= O_ASYNC; 110 if (args->flags & LINUX_O_CREAT) 111 bsd_open_args.flags |= O_CREAT; 112 if (args->flags & LINUX_O_TRUNC) 113 bsd_open_args.flags |= O_TRUNC; 114 if (args->flags & LINUX_O_EXCL) 115 bsd_open_args.flags |= O_EXCL; 116 if (args->flags & LINUX_O_NOCTTY) 117 bsd_open_args.flags |= O_NOCTTY; 118 bsd_open_args.path = args->path; 119 bsd_open_args.mode = args->mode; 120 121 error = open(p, &bsd_open_args, retval); 122 if (!error && !(bsd_open_args.flags & O_NOCTTY) && 123 SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { 124 struct filedesc *fdp = p->p_fd; 125 struct file *fp = fdp->fd_ofiles[*retval]; 126 127 if (fp->f_type == DTYPE_VNODE) 128 (fp->f_ops->fo_ioctl)(fp, TIOCSCTTY, (caddr_t) 0, p); 129 } 130#ifdef DEBUG 131 printf("Linux-emul(%d): open returns error %d\n", 132 p->p_pid, error); 133#endif 134 return error; 135} 136 137struct linux_flock { 138 short l_type; 139 short l_whence; 140 linux_off_t l_start; 141 linux_off_t l_len; 142 linux_pid_t l_pid; 143}; 144 145static void 146linux_to_bsd_flock(struct linux_flock *linux_flock, struct flock *bsd_flock) 147{ 148 switch (linux_flock->l_type) { 149 case LINUX_F_RDLCK: 150 bsd_flock->l_type = F_RDLCK; 151 break; 152 case LINUX_F_WRLCK: 153 bsd_flock->l_type = F_WRLCK; 154 break; 155 case LINUX_F_UNLCK: 156 bsd_flock->l_type = F_UNLCK; 157 break; 158 } 159 bsd_flock->l_whence = linux_flock->l_whence; 160 bsd_flock->l_start = (off_t)linux_flock->l_start; 161 bsd_flock->l_len = (off_t)linux_flock->l_len; 162 bsd_flock->l_pid = (pid_t)linux_flock->l_pid; 163} 164 165static void 166bsd_to_linux_flock(struct flock *bsd_flock, struct linux_flock *linux_flock) 167{ 168 switch (bsd_flock->l_type) { 169 case F_RDLCK: 170 linux_flock->l_type = LINUX_F_RDLCK; 171 break; 172 case F_WRLCK: 173 linux_flock->l_type = LINUX_F_WRLCK; 174 break; 175 case F_UNLCK: 176 linux_flock->l_type = LINUX_F_UNLCK; 177 break; 178 } 179 linux_flock->l_whence = bsd_flock->l_whence; 180 linux_flock->l_start = (linux_off_t)bsd_flock->l_start; 181 linux_flock->l_len = (linux_off_t)bsd_flock->l_len; 182 linux_flock->l_pid = (linux_pid_t)bsd_flock->l_pid; 183} 184 185int 186linux_fcntl(struct proc *p, struct linux_fcntl_args *args, int *retval) 187{ 188 int error, result; 189 struct fcntl_args /* { 190 int fd; 191 int cmd; 192 int arg; 193 } */ fcntl_args; 194 struct linux_flock linux_flock; 195 struct flock *bsd_flock; 196 struct filedesc *fdp; 197 struct file *fp; 198 struct vnode *vp; 199 struct vattr va; 200 long pgid; 201 struct pgrp *pgrp; 202 struct tty *tp, *(*d_tty) __P((dev_t)); 203 caddr_t sg; 204 205 sg = stackgap_init(); 206 bsd_flock = (struct flock *)stackgap_alloc(&sg, sizeof(struct flock)); 207 d_tty = NULL; 208 209#ifdef DEBUG 210 printf("Linux-emul(%d): fcntl(%d, %08x, *)\n", 211 p->p_pid, args->fd, args->cmd); 212#endif 213 fcntl_args.fd = args->fd; 214 fcntl_args.arg = 0; 215 216 switch (args->cmd) { 217 case LINUX_F_DUPFD: 218 fcntl_args.cmd = F_DUPFD; 219 return fcntl(p, &fcntl_args, retval); 220 221 case LINUX_F_GETFD: 222 fcntl_args.cmd = F_GETFD; 223 return fcntl(p, &fcntl_args, retval); 224 225 case LINUX_F_SETFD: 226 fcntl_args.cmd = F_SETFD; 227 return fcntl(p, &fcntl_args, retval); 228 229 case LINUX_F_GETFL: 230 fcntl_args.cmd = F_GETFL; 231 error = fcntl(p, &fcntl_args, &result); 232 *retval = 0; 233 if (result & O_RDONLY) *retval |= LINUX_O_RDONLY; 234 if (result & O_WRONLY) *retval |= LINUX_O_WRONLY; 235 if (result & O_RDWR) *retval |= LINUX_O_RDWR; 236 if (result & O_NDELAY) *retval |= LINUX_O_NONBLOCK; 237 if (result & O_APPEND) *retval |= LINUX_O_APPEND; 238 if (result & O_FSYNC) *retval |= LINUX_O_SYNC; 239 return error; 240 241 case LINUX_F_SETFL: 242 if (args->arg & LINUX_O_NDELAY) fcntl_args.arg |= O_NONBLOCK; 243 if (args->arg & LINUX_O_APPEND) fcntl_args.arg |= O_APPEND; 244 if (args->arg & LINUX_O_SYNC) fcntl_args.arg |= O_FSYNC; 245 fcntl_args.cmd = F_SETFL; 246 return fcntl(p, &fcntl_args, retval); 247 248 case LINUX_F_GETLK: 249 if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock, 250 sizeof(struct linux_flock)))) 251 return error; 252 linux_to_bsd_flock(&linux_flock, bsd_flock); 253 fcntl_args.cmd = F_GETLK; 254 fcntl_args.arg = (int)bsd_flock; 255 if (error = fcntl(p, &fcntl_args, retval)) 256 return error; 257 bsd_to_linux_flock(bsd_flock, &linux_flock); 258 return copyout((caddr_t)&linux_flock, (caddr_t)args->arg, 259 sizeof(struct linux_flock)); 260 261 case LINUX_F_SETLK: 262 if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock, 263 sizeof(struct linux_flock)))) 264 return error; 265 linux_to_bsd_flock(&linux_flock, bsd_flock); 266 fcntl_args.cmd = F_SETLK; 267 fcntl_args.arg = (int)bsd_flock; 268 return fcntl(p, &fcntl_args, retval); 269 270 case LINUX_F_SETLKW: 271 if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock, 272 sizeof(struct linux_flock)))) 273 return error; 274 linux_to_bsd_flock(&linux_flock, bsd_flock); 275 fcntl_args.cmd = F_SETLKW; 276 fcntl_args.arg = (int)bsd_flock; 277 return fcntl(p, &fcntl_args, retval); 278 279 case LINUX_F_SETOWN: 280 case LINUX_F_GETOWN: 281 /* 282 * We need to route around the normal fcntl() for these calls, 283 * since it uses TIOC{G,S}PGRP, which is too restrictive for 284 * Linux F_{G,S}ETOWN semantics. For sockets, this problem 285 * does not exist. 286 */ 287 fdp = p->p_fd; 288 if ((u_int)args->fd >= fdp->fd_nfiles || 289 (fp = fdp->fd_ofiles[args->fd]) == NULL) 290 return EBADF; 291 if (fp->f_type == DTYPE_SOCKET) { 292 fcntl_args.cmd = args->cmd == LINUX_F_SETOWN ? F_SETOWN : F_GETOWN; 293 return fcntl(p, &fcntl_args, retval); 294 } 295 vp = (struct vnode *)fp->f_data; 296 if (vp->v_type != VCHR) 297 return EINVAL; 298 if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p))) 299 return error; 300 301 d_tty = cdevsw[major(va.va_rdev)]->d_devtotty; 302 if (!d_tty || (!(tp = (*d_tty)(va.va_rdev)))) 303 return EINVAL; 304 if (args->cmd == LINUX_F_GETOWN) { 305 retval[0] = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID; 306 return 0; 307 } 308 if ((long)args->arg <= 0) { 309 pgid = -(long)args->arg; 310 } else { 311 struct proc *p1 = pfind((long)args->arg); 312 if (p1 == 0) 313 return (ESRCH); 314 pgid = (long)p1->p_pgrp->pg_id; 315 } 316 pgrp = pgfind(pgid); 317 if (pgrp == NULL || pgrp->pg_session != p->p_session) 318 return EPERM; 319 tp->t_pgrp = pgrp; 320 return 0; 321 } 322 return EINVAL; 323} 324 325int 326linux_lseek(struct proc *p, struct linux_lseek_args *args, int *retval) 327{ 328 329 struct lseek_args /* { 330 int fd; 331 int pad; 332 off_t offset; 333 int whence; 334 } */ tmp_args; 335 int error; 336 337#ifdef DEBUG 338 printf("Linux-emul(%d): lseek(%d, %d, %d)\n", 339 p->p_pid, args->fdes, args->off, args->whence); 340#endif 341 tmp_args.fd = args->fdes; 342 tmp_args.offset = (off_t)args->off; 343 tmp_args.whence = args->whence; 344 error = lseek(p, &tmp_args, retval); 345 return error; 346} 347 348int 349linux_llseek(struct proc *p, struct linux_llseek_args *args, int *retval) 350{ 351 struct lseek_args bsd_args; 352 int error; 353 off_t off; 354 355#ifdef DEBUG 356 printf("Linux-emul(%d): llseek(%d, %d:%d, %d)\n", 357 p->p_pid, args->fd, args->ohigh, args->olow, args->whence); 358#endif 359 off = (args->olow) | (((off_t) args->ohigh) << 32); 360 361 bsd_args.fd = args->fd; 362 bsd_args.offset = off; 363 bsd_args.whence = args->whence; 364 365 if ((error = lseek(p, &bsd_args, retval))) 366 return error; 367 368 if ((error = copyout(retval, (caddr_t)args->res, sizeof (off_t)))) 369 return error; 370 371 retval[0] = 0; 372 return 0; 373} 374 375 376struct linux_dirent { 377 long dino; 378 linux_off_t doff; 379 unsigned short dreclen; 380 char dname[LINUX_NAME_MAX + 1]; 381}; 382 383#define LINUX_RECLEN(de,namlen) \ 384 ALIGN((((char *)&(de)->dname - (char *)de) + (namlen) + 1)) 385 386int 387linux_readdir(struct proc *p, struct linux_readdir_args *args, int *retval) 388{ 389 struct linux_getdents_args lda; 390 391 lda.fd = args->fd; 392 lda.dent = args->dent; 393 lda.count = 1; 394 return linux_getdents(p, &lda, retval); 395} 396 397int 398linux_getdents(struct proc *p, struct linux_getdents_args *args, int *retval) 399{ 400 register struct dirent *bdp; 401 struct vnode *vp; 402 caddr_t inp, buf; /* BSD-format */ 403 int len, reclen; /* BSD-format */ 404 caddr_t outp; /* Linux-format */ 405 int resid, linuxreclen=0; /* Linux-format */ 406 struct file *fp; 407 struct uio auio; 408 struct iovec aiov; 409 struct vattr va; 410 off_t off; 411 struct linux_dirent linux_dirent; 412 int buflen, error, eofflag, nbytes, justone; 413 u_long *cookies = NULL, *cookiep; 414 int ncookies; 415 416#ifdef DEBUG 417 printf("Linux-emul(%d): getdents(%d, *, %d)\n", 418 p->p_pid, args->fd, args->count); 419#endif 420 if ((error = getvnode(p->p_fd, args->fd, &fp)) != 0) { 421 return (error); 422 } 423 424 if ((fp->f_flag & FREAD) == 0) 425 return (EBADF); 426 427 vp = (struct vnode *) fp->f_data; 428 429 if (vp->v_type != VDIR) 430 return (EINVAL); 431 432 if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p))) { 433 return error; 434 } 435 436 nbytes = args->count; 437 if (nbytes == 1) { 438 nbytes = sizeof (struct linux_dirent); 439 justone = 1; 440 } 441 else 442 justone = 0; 443 444 off = fp->f_offset; 445#define DIRBLKSIZ 512 /* XXX we used to use ufs's DIRBLKSIZ */ 446 buflen = max(DIRBLKSIZ, nbytes); 447 buflen = min(buflen, MAXBSIZE); 448 buf = malloc(buflen, M_TEMP, M_WAITOK); 449 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 450again: 451 aiov.iov_base = buf; 452 aiov.iov_len = buflen; 453 auio.uio_iov = &aiov; 454 auio.uio_iovcnt = 1; 455 auio.uio_rw = UIO_READ; 456 auio.uio_segflg = UIO_SYSSPACE; 457 auio.uio_procp = p; 458 auio.uio_resid = buflen; 459 auio.uio_offset = off; 460 461 if (cookies) { 462 free(cookies, M_TEMP); 463 cookies = NULL; 464 } 465 466 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies, &cookies); 467 if (error) { 468 goto out; 469 } 470 471 inp = buf; 472 outp = (caddr_t) args->dent; 473 resid = nbytes; 474 if ((len = buflen - auio.uio_resid) <= 0) { 475 goto eof; 476 } 477 478 cookiep = cookies; 479 480 if (cookies) { 481 /* 482 * When using cookies, the vfs has the option of reading from 483 * a different offset than that supplied (UFS truncates the 484 * offset to a block boundary to make sure that it never reads 485 * partway through a directory entry, even if the directory 486 * has been compacted). 487 */ 488 while (len > 0 && ncookies > 0 && *cookiep <= off) { 489 bdp = (struct dirent *) inp; 490 len -= bdp->d_reclen; 491 inp += bdp->d_reclen; 492 cookiep++; 493 ncookies--; 494 } 495 } 496 497 while (len > 0) { 498 if (cookiep && ncookies == 0) 499 break; 500 bdp = (struct dirent *) inp; 501 reclen = bdp->d_reclen; 502 if (reclen & 3) { 503 printf("linux_readdir: reclen=%d\n", reclen); 504 error = EFAULT; 505 goto out; 506 } 507 508 if (bdp->d_fileno == 0) { 509 inp += reclen; 510 if (cookiep) { 511 off = *cookiep++; 512 ncookies--; 513 } else 514 off += reclen; 515 len -= reclen; 516 continue; 517 } 518 linuxreclen = LINUX_RECLEN(&linux_dirent, bdp->d_namlen); 519 if (reclen > len || resid < linuxreclen) { 520 outp++; 521 break; 522 } 523 linux_dirent.dino = (long) bdp->d_fileno; 524 if (justone) { 525 /* 526 * old linux-style readdir usage. 527 */ 528 linux_dirent.doff = (linux_off_t) linuxreclen; 529 linux_dirent.dreclen = (u_short) bdp->d_namlen; 530 } else { 531 linux_dirent.doff = (linux_off_t) off; 532 linux_dirent.dreclen = (u_short) linuxreclen; 533 } 534 strcpy(linux_dirent.dname, bdp->d_name); 535 if ((error = copyout((caddr_t)&linux_dirent, outp, linuxreclen))) { 536 goto out; 537 } 538 inp += reclen; 539 if (cookiep) { 540 off = *cookiep++; 541 ncookies--; 542 } else 543 off += reclen; 544 outp += linuxreclen; 545 resid -= linuxreclen; 546 len -= reclen; 547 if (justone) 548 break; 549 } 550 551 if (outp == (caddr_t) args->dent) 552 goto again; 553 fp->f_offset = off; 554 555 if (justone) 556 nbytes = resid + linuxreclen; 557 558eof: 559 *retval = nbytes - resid; 560out: 561 if (cookies) 562 free(cookies, M_TEMP); 563 VOP_UNLOCK(vp, 0, p); 564 free(buf, M_TEMP); 565 return error; 566} 567 568/* 569 * These exist mainly for hooks for doing /compat/linux translation. 570 */ 571 572int 573linux_access(struct proc *p, struct linux_access_args *args, int *retval) 574{ 575 struct access_args bsd; 576 caddr_t sg; 577 578 sg = stackgap_init(); 579 CHECKALTEXIST(p, &sg, args->path); 580 581#ifdef DEBUG 582 printf("Linux-emul(%d): access(%s, %d)\n", 583 p->p_pid, args->path, args->flags); 584#endif 585 bsd.path = args->path; 586 bsd.flags = args->flags; 587 588 return access(p, &bsd, retval); 589} 590 591int 592linux_unlink(struct proc *p, struct linux_unlink_args *args, int *retval) 593{ 594 struct unlink_args bsd; 595 caddr_t sg; 596 597 sg = stackgap_init(); 598 CHECKALTEXIST(p, &sg, args->path); 599 600#ifdef DEBUG 601 printf("Linux-emul(%d): unlink(%s)\n", 602 p->p_pid, args->path); 603#endif 604 bsd.path = args->path; 605 606 return unlink(p, &bsd, retval); 607} 608 609int 610linux_chdir(struct proc *p, struct linux_chdir_args *args, int *retval) 611{ 612 struct chdir_args bsd; 613 caddr_t sg; 614 615 sg = stackgap_init(); 616 CHECKALTEXIST(p, &sg, args->path); 617 618#ifdef DEBUG 619 printf("Linux-emul(%d): chdir(%s)\n", 620 p->p_pid, args->path); 621#endif 622 bsd.path = args->path; 623 624 return chdir(p, &bsd, retval); 625} 626 627int 628linux_chmod(struct proc *p, struct linux_chmod_args *args, int *retval) 629{ 630 struct chmod_args bsd; 631 caddr_t sg; 632 633 sg = stackgap_init(); 634 CHECKALTEXIST(p, &sg, args->path); 635 636#ifdef DEBUG 637 printf("Linux-emul(%d): chmod(%s, %d)\n", 638 p->p_pid, args->path, args->mode); 639#endif 640 bsd.path = args->path; 641 bsd.mode = args->mode; 642 643 return chmod(p, &bsd, retval); 644} 645 646int 647linux_chown(struct proc *p, struct linux_chown_args *args, int *retval) 648{ 649 struct chown_args bsd; 650 caddr_t sg; 651 652 sg = stackgap_init(); 653 CHECKALTEXIST(p, &sg, args->path); 654 655#ifdef DEBUG 656 printf("Linux-emul(%d): chown(%s, %d, %d)\n", 657 p->p_pid, args->path, args->uid, args->gid); 658#endif 659 bsd.path = args->path; 660 /* XXX size casts here */ 661 bsd.uid = args->uid; 662 bsd.gid = args->gid; 663 664 return chown(p, &bsd, retval); 665} 666 667int 668linux_mkdir(struct proc *p, struct linux_mkdir_args *args, int *retval) 669{ 670 struct mkdir_args bsd; 671 caddr_t sg; 672 673 sg = stackgap_init(); 674 CHECKALTCREAT(p, &sg, args->path); 675 676#ifdef DEBUG 677 printf("Linux-emul(%d): mkdir(%s, %d)\n", 678 p->p_pid, args->path, args->mode); 679#endif 680 bsd.path = args->path; 681 bsd.mode = args->mode; 682 683 return mkdir(p, &bsd, retval); 684} 685 686int 687linux_rmdir(struct proc *p, struct linux_rmdir_args *args, int *retval) 688{ 689 struct rmdir_args bsd; 690 caddr_t sg; 691 692 sg = stackgap_init(); 693 CHECKALTEXIST(p, &sg, args->path); 694 695#ifdef DEBUG 696 printf("Linux-emul(%d): rmdir(%s)\n", 697 p->p_pid, args->path); 698#endif 699 bsd.path = args->path; 700 701 return rmdir(p, &bsd, retval); 702} 703 704int 705linux_rename(struct proc *p, struct linux_rename_args *args, int *retval) 706{ 707 struct rename_args bsd; 708 caddr_t sg; 709 710 sg = stackgap_init(); 711 CHECKALTEXIST(p, &sg, args->from); 712 CHECKALTCREAT(p, &sg, args->to); 713 714#ifdef DEBUG 715 printf("Linux-emul(%d): rename(%s, %s)\n", 716 p->p_pid, args->from, args->to); 717#endif 718 bsd.from = args->from; 719 bsd.to = args->to; 720 721 return rename(p, &bsd, retval); 722} 723 724int 725linux_symlink(struct proc *p, struct linux_symlink_args *args, int *retval) 726{ 727 struct symlink_args bsd; 728 caddr_t sg; 729 730 sg = stackgap_init(); 731 CHECKALTEXIST(p, &sg, args->path); 732 CHECKALTCREAT(p, &sg, args->to); 733 734#ifdef DEBUG 735 printf("Linux-emul(%d): symlink(%s, %s)\n", 736 p->p_pid, args->path, args->to); 737#endif 738 bsd.path = args->path; 739 bsd.link = args->to; 740 741 return symlink(p, &bsd, retval); 742} 743 744int 745linux_execve(struct proc *p, struct linux_execve_args *args, int *retval) 746{ 747 struct execve_args bsd; 748 caddr_t sg; 749 750 sg = stackgap_init(); 751 CHECKALTEXIST(p, &sg, args->path); 752 753#ifdef DEBUG 754 printf("Linux-emul(%d): execve(%s)\n", 755 p->p_pid, args->path); 756#endif 757 bsd.fname = args->path; 758 bsd.argv = args->argp; 759 bsd.envv = args->envp; 760 761 return execve(p, &bsd, retval); 762} 763 764int 765linux_readlink(struct proc *p, struct linux_readlink_args *args, int *retval) 766{ 767 struct readlink_args bsd; 768 caddr_t sg; 769 770 sg = stackgap_init(); 771 CHECKALTEXIST(p, &sg, args->name); 772 773#ifdef DEBUG 774 printf("Linux-emul(%d): readlink(%s, 0x%x, %d)\n", 775 p->p_pid, args->name, args->buf, args->count); 776#endif 777 bsd.path = args->name; 778 bsd.buf = args->buf; 779 bsd.count = args->count; 780 781 return readlink(p, &bsd, retval); 782} 783 784int 785linux_truncate(struct proc *p, struct linux_truncate_args *args, int *retval) 786{ 787 struct otruncate_args bsd; 788 caddr_t sg; 789 790 sg = stackgap_init(); 791 CHECKALTEXIST(p, &sg, args->path); 792 793#ifdef DEBUG 794 printf("Linux-emul(%d): truncate(%s)\n", 795 p->p_pid, args->path); 796#endif 797 bsd.path = args->path; 798 799 return otruncate(p, &bsd, retval); 800} 801 802