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