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