1 /* $NetBSD: linux_file.c,v 1.56 2003/01/18 08:02:52 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Frank van der Linden and Eric Haszlakiewicz. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /* 40 * Functions in multiarch: 41 * linux_sys_llseek : linux_llseek.c 42 */ 43 44 #include <sys/cdefs.h> 45 __KERNEL_RCSID(0, "$NetBSD: linux_file.c,v 1.56 2003/01/18 08:02:52 thorpej Exp $"); 46 47 #include <sys/param.h> 48 #include <sys/systm.h> 49 #include <sys/namei.h> 50 #include <sys/proc.h> 51 #include <sys/file.h> 52 #include <sys/stat.h> 53 #include <sys/filedesc.h> 54 #include <sys/ioctl.h> 55 #include <sys/kernel.h> 56 #include <sys/mount.h> 57 #include <sys/malloc.h> 58 #include <sys/vnode.h> 59 #include <sys/tty.h> 60 #include <sys/socketvar.h> 61 #include <sys/conf.h> 62 #include <sys/pipe.h> 63 64 #include <sys/sa.h> 65 #include <sys/syscallargs.h> 66 67 #include <compat/linux/common/linux_types.h> 68 #include <compat/linux/common/linux_signal.h> 69 #include <compat/linux/common/linux_fcntl.h> 70 #include <compat/linux/common/linux_util.h> 71 #include <compat/linux/common/linux_machdep.h> 72 73 #include <compat/linux/linux_syscallargs.h> 74 75 static int linux_to_bsd_ioflags __P((int)); 76 static int bsd_to_linux_ioflags __P((int)); 77 static void bsd_to_linux_flock __P((struct flock *, struct linux_flock *)); 78 static void linux_to_bsd_flock __P((struct linux_flock *, struct flock *)); 79 static void bsd_to_linux_stat __P((struct stat *, struct linux_stat *)); 80 static int linux_stat1 __P((struct lwp *, void *, register_t *, int)); 81 82 /* 83 * Some file-related calls are handled here. The usual flag conversion 84 * an structure conversion is done, and alternate emul path searching. 85 */ 86 87 /* 88 * The next two functions convert between the Linux and NetBSD values 89 * of the flags used in open(2) and fcntl(2). 90 */ 91 static int 92 linux_to_bsd_ioflags(lflags) 93 int lflags; 94 { 95 int res = 0; 96 97 res |= cvtto_bsd_mask(lflags, LINUX_O_WRONLY, O_WRONLY); 98 res |= cvtto_bsd_mask(lflags, LINUX_O_RDONLY, O_RDONLY); 99 res |= cvtto_bsd_mask(lflags, LINUX_O_RDWR, O_RDWR); 100 res |= cvtto_bsd_mask(lflags, LINUX_O_CREAT, O_CREAT); 101 res |= cvtto_bsd_mask(lflags, LINUX_O_EXCL, O_EXCL); 102 res |= cvtto_bsd_mask(lflags, LINUX_O_NOCTTY, O_NOCTTY); 103 res |= cvtto_bsd_mask(lflags, LINUX_O_TRUNC, O_TRUNC); 104 res |= cvtto_bsd_mask(lflags, LINUX_O_NDELAY, O_NDELAY); 105 res |= cvtto_bsd_mask(lflags, LINUX_O_SYNC, O_FSYNC); 106 res |= cvtto_bsd_mask(lflags, LINUX_FASYNC, O_ASYNC); 107 res |= cvtto_bsd_mask(lflags, LINUX_O_APPEND, O_APPEND); 108 109 return res; 110 } 111 112 static int 113 bsd_to_linux_ioflags(bflags) 114 int bflags; 115 { 116 int res = 0; 117 118 res |= cvtto_linux_mask(bflags, O_WRONLY, LINUX_O_WRONLY); 119 res |= cvtto_linux_mask(bflags, O_RDONLY, LINUX_O_RDONLY); 120 res |= cvtto_linux_mask(bflags, O_RDWR, LINUX_O_RDWR); 121 res |= cvtto_linux_mask(bflags, O_CREAT, LINUX_O_CREAT); 122 res |= cvtto_linux_mask(bflags, O_EXCL, LINUX_O_EXCL); 123 res |= cvtto_linux_mask(bflags, O_NOCTTY, LINUX_O_NOCTTY); 124 res |= cvtto_linux_mask(bflags, O_TRUNC, LINUX_O_TRUNC); 125 res |= cvtto_linux_mask(bflags, O_NDELAY, LINUX_O_NDELAY); 126 res |= cvtto_linux_mask(bflags, O_FSYNC, LINUX_O_SYNC); 127 res |= cvtto_linux_mask(bflags, O_ASYNC, LINUX_FASYNC); 128 res |= cvtto_linux_mask(bflags, O_APPEND, LINUX_O_APPEND); 129 130 return res; 131 } 132 133 /* 134 * creat(2) is an obsolete function, but it's present as a Linux 135 * system call, so let's deal with it. 136 * 137 * Note: On the Alpha this doesn't really exist in Linux, but it's defined 138 * in syscalls.master anyway so this doesn't have to be special cased. 139 * 140 * Just call open(2) with the TRUNC, CREAT and WRONLY flags. 141 */ 142 int 143 linux_sys_creat(l, v, retval) 144 struct lwp *l; 145 void *v; 146 register_t *retval; 147 { 148 struct linux_sys_creat_args /* { 149 syscallarg(const char *) path; 150 syscallarg(int) mode; 151 } */ *uap = v; 152 struct proc *p = l->l_proc; 153 struct sys_open_args oa; 154 caddr_t sg; 155 156 sg = stackgap_init(p, 0); 157 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path)); 158 159 SCARG(&oa, path) = SCARG(uap, path); 160 SCARG(&oa, flags) = O_CREAT | O_TRUNC | O_WRONLY; 161 SCARG(&oa, mode) = SCARG(uap, mode); 162 163 return sys_open(l, &oa, retval); 164 } 165 166 /* 167 * open(2). Take care of the different flag values, and let the 168 * NetBSD syscall do the real work. See if this operation 169 * gives the current process a controlling terminal. 170 * (XXX is this necessary?) 171 */ 172 int 173 linux_sys_open(l, v, retval) 174 struct lwp *l; 175 void *v; 176 register_t *retval; 177 { 178 struct linux_sys_open_args /* { 179 syscallarg(const char *) path; 180 syscallarg(int) flags; 181 syscallarg(int) mode; 182 } */ *uap = v; 183 struct proc *p = l->l_proc; 184 int error, fl; 185 struct sys_open_args boa; 186 caddr_t sg; 187 188 sg = stackgap_init(p, 0); 189 190 fl = linux_to_bsd_ioflags(SCARG(uap, flags)); 191 192 if (fl & O_CREAT) 193 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path)); 194 else 195 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 196 197 SCARG(&boa, path) = SCARG(uap, path); 198 SCARG(&boa, flags) = fl; 199 SCARG(&boa, mode) = SCARG(uap, mode); 200 201 if ((error = sys_open(l, &boa, retval))) 202 return error; 203 204 /* 205 * this bit from sunos_misc.c (and svr4_fcntl.c). 206 * If we are a session leader, and we don't have a controlling 207 * terminal yet, and the O_NOCTTY flag is not set, try to make 208 * this the controlling terminal. 209 */ 210 if (!(fl & O_NOCTTY) && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { 211 struct filedesc *fdp = p->p_fd; 212 struct file *fp; 213 214 fp = fd_getfile(fdp, *retval); 215 216 /* ignore any error, just give it a try */ 217 if (fp != NULL && fp->f_type == DTYPE_VNODE) 218 (fp->f_ops->fo_ioctl) (fp, TIOCSCTTY, (caddr_t) 0, p); 219 } 220 return 0; 221 } 222 223 /* 224 * The next two functions take care of converting the flock 225 * structure back and forth between Linux and NetBSD format. 226 * The only difference in the structures is the order of 227 * the fields, and the 'whence' value. 228 */ 229 static void 230 bsd_to_linux_flock(bfp, lfp) 231 struct flock *bfp; 232 struct linux_flock *lfp; 233 { 234 235 lfp->l_start = bfp->l_start; 236 lfp->l_len = bfp->l_len; 237 lfp->l_pid = bfp->l_pid; 238 lfp->l_whence = bfp->l_whence; 239 switch (bfp->l_type) { 240 case F_RDLCK: 241 lfp->l_type = LINUX_F_RDLCK; 242 break; 243 case F_UNLCK: 244 lfp->l_type = LINUX_F_UNLCK; 245 break; 246 case F_WRLCK: 247 lfp->l_type = LINUX_F_WRLCK; 248 break; 249 } 250 } 251 252 static void 253 linux_to_bsd_flock(lfp, bfp) 254 struct linux_flock *lfp; 255 struct flock *bfp; 256 { 257 258 bfp->l_start = lfp->l_start; 259 bfp->l_len = lfp->l_len; 260 bfp->l_pid = lfp->l_pid; 261 bfp->l_whence = lfp->l_whence; 262 switch (lfp->l_type) { 263 case LINUX_F_RDLCK: 264 bfp->l_type = F_RDLCK; 265 break; 266 case LINUX_F_UNLCK: 267 bfp->l_type = F_UNLCK; 268 break; 269 case LINUX_F_WRLCK: 270 bfp->l_type = F_WRLCK; 271 break; 272 } 273 } 274 275 /* 276 * Most actions in the fcntl() call are straightforward; simply 277 * pass control to the NetBSD system call. A few commands need 278 * conversions after the actual system call has done its work, 279 * because the flag values and lock structure are different. 280 */ 281 int 282 linux_sys_fcntl(l, v, retval) 283 struct lwp *l; 284 void *v; 285 register_t *retval; 286 { 287 struct linux_sys_fcntl_args /* { 288 syscallarg(int) fd; 289 syscallarg(int) cmd; 290 syscallarg(void *) arg; 291 } */ *uap = v; 292 struct proc *p = l->l_proc; 293 int fd, cmd, error; 294 u_long val; 295 caddr_t arg, sg; 296 struct linux_flock lfl; 297 struct flock *bfp, bfl; 298 struct sys_fcntl_args fca; 299 struct filedesc *fdp; 300 struct file *fp; 301 struct vnode *vp; 302 struct vattr va; 303 const struct cdevsw *cdev; 304 long pgid; 305 struct pgrp *pgrp; 306 struct tty *tp, *(*d_tty) __P((dev_t)); 307 308 fd = SCARG(uap, fd); 309 cmd = SCARG(uap, cmd); 310 arg = (caddr_t) SCARG(uap, arg); 311 312 switch (cmd) { 313 case LINUX_F_DUPFD: 314 cmd = F_DUPFD; 315 break; 316 case LINUX_F_GETFD: 317 cmd = F_GETFD; 318 break; 319 case LINUX_F_SETFD: 320 cmd = F_SETFD; 321 break; 322 case LINUX_F_GETFL: 323 SCARG(&fca, fd) = fd; 324 SCARG(&fca, cmd) = F_GETFL; 325 SCARG(&fca, arg) = arg; 326 if ((error = sys_fcntl(l, &fca, retval))) 327 return error; 328 retval[0] = bsd_to_linux_ioflags(retval[0]); 329 return 0; 330 case LINUX_F_SETFL: { 331 struct file *fp = NULL; 332 333 val = linux_to_bsd_ioflags((unsigned long)SCARG(uap, arg)); 334 /* 335 * Linux seems to have same semantics for sending SIGIO to the 336 * read side of socket, but slighly different semantics 337 * for SIGIO to the write side. Rather than sending the SIGIO 338 * every time it's possible to write (directly) more data, it 339 * only sends SIGIO if last write(2) failed due to insufficient 340 * memory to hold the data. This is compatible enough 341 * with NetBSD semantics to not do anything about the 342 * difference. 343 * 344 * Linux does NOT send SIGIO for pipes. Deal with socketpair 345 * ones and DTYPE_PIPE ones. For these, we don't set 346 * the underlying flags (we don't pass O_ASYNC flag down 347 * to sys_fcntl()), but set the FASYNC flag for file descriptor, 348 * so that F_GETFL would report the ASYNC i/o is on. 349 */ 350 if (val & O_ASYNC) { 351 if (((fp = fd_getfile(p->p_fd, fd)) == NULL)) 352 return (EBADF); 353 354 FILE_USE(fp); 355 356 if (((fp->f_type == DTYPE_SOCKET) && fp->f_data 357 && ((struct socket *)fp->f_data)->so_state & SS_ISAPIPE) 358 || (fp->f_type == DTYPE_PIPE)) 359 val &= ~O_ASYNC; 360 else { 361 /* not a pipe, do not modify anything */ 362 FILE_UNUSE(fp, p); 363 fp = NULL; 364 } 365 } 366 367 SCARG(&fca, fd) = fd; 368 SCARG(&fca, cmd) = F_SETFL; 369 SCARG(&fca, arg) = (caddr_t) val; 370 371 error = sys_fcntl(l, &fca, retval); 372 373 /* Now set the FASYNC flag for pipes */ 374 if (fp) { 375 if (!error) 376 fp->f_flag |= FASYNC; 377 FILE_UNUSE(fp, p); 378 } 379 380 return (error); 381 } 382 case LINUX_F_GETLK: 383 sg = stackgap_init(p, 0); 384 bfp = (struct flock *) stackgap_alloc(p, &sg, sizeof *bfp); 385 if ((error = copyin(arg, &lfl, sizeof lfl))) 386 return error; 387 linux_to_bsd_flock(&lfl, &bfl); 388 if ((error = copyout(&bfl, bfp, sizeof bfl))) 389 return error; 390 SCARG(&fca, fd) = fd; 391 SCARG(&fca, cmd) = F_GETLK; 392 SCARG(&fca, arg) = bfp; 393 if ((error = sys_fcntl(l, &fca, retval))) 394 return error; 395 if ((error = copyin(bfp, &bfl, sizeof bfl))) 396 return error; 397 bsd_to_linux_flock(&bfl, &lfl); 398 return copyout(&lfl, arg, sizeof lfl); 399 400 case LINUX_F_SETLK: 401 case LINUX_F_SETLKW: 402 cmd = (cmd == LINUX_F_SETLK ? F_SETLK : F_SETLKW); 403 if ((error = copyin(arg, &lfl, sizeof lfl))) 404 return error; 405 linux_to_bsd_flock(&lfl, &bfl); 406 sg = stackgap_init(p, 0); 407 bfp = (struct flock *) stackgap_alloc(p, &sg, sizeof *bfp); 408 if ((error = copyout(&bfl, bfp, sizeof bfl))) 409 return error; 410 arg = (caddr_t)bfp; 411 break; 412 413 case LINUX_F_SETOWN: 414 case LINUX_F_GETOWN: 415 /* 416 * We need to route fcntl() for tty descriptors around normal 417 * fcntl(), since NetBSD tty TIOC{G,S}PGRP semantics is too 418 * restrictive for Linux F_{G,S}ETOWN. For non-tty descriptors, 419 * this is not a problem. 420 */ 421 fdp = p->p_fd; 422 if ((fp = fd_getfile(fdp, fd)) == NULL) 423 return EBADF; 424 /* FILE_USE() not needed here */ 425 if (fp->f_type != DTYPE_VNODE) { 426 not_tty: 427 /* Not a tty, proceed with common fcntl() */ 428 cmd = cmd == LINUX_F_SETOWN ? F_SETOWN : F_GETOWN; 429 break; 430 } 431 432 /* check that the vnode is a tty */ 433 vp = (struct vnode *)fp->f_data; 434 if (vp->v_type != VCHR) 435 goto not_tty; 436 if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p))) 437 return error; 438 cdev = cdevsw_lookup(va.va_rdev); 439 if (cdev == NULL) 440 return (ENXIO); 441 d_tty = cdev->d_tty; 442 if (!d_tty || (!(tp = (*d_tty)(va.va_rdev)))) 443 goto not_tty; 444 445 /* set tty pg_id appropriately */ 446 if (cmd == LINUX_F_GETOWN) { 447 retval[0] = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID; 448 return 0; 449 } 450 if ((long)arg <= 0) { 451 pgid = -(long)arg; 452 } else { 453 struct proc *p1 = pfind((long)arg); 454 if (p1 == NULL) 455 return (ESRCH); 456 pgid = (long)p1->p_pgrp->pg_id; 457 } 458 pgrp = pgfind(pgid); 459 if (pgrp == NULL || pgrp->pg_session != p->p_session) 460 return EPERM; 461 tp->t_pgrp = pgrp; 462 return 0; 463 464 default: 465 return EOPNOTSUPP; 466 } 467 468 SCARG(&fca, fd) = fd; 469 SCARG(&fca, cmd) = cmd; 470 SCARG(&fca, arg) = arg; 471 472 return sys_fcntl(l, &fca, retval); 473 } 474 475 /* 476 * Convert a NetBSD stat structure to a Linux stat structure. 477 * Only the order of the fields and the padding in the structure 478 * is different. linux_fakedev is a machine-dependent function 479 * which optionally converts device driver major/minor numbers 480 * (XXX horrible, but what can you do against code that compares 481 * things against constant major device numbers? sigh) 482 */ 483 static void 484 bsd_to_linux_stat(bsp, lsp) 485 struct stat *bsp; 486 struct linux_stat *lsp; 487 { 488 489 lsp->lst_dev = linux_fakedev(bsp->st_dev, 0); 490 lsp->lst_ino = bsp->st_ino; 491 lsp->lst_mode = (linux_mode_t)bsp->st_mode; 492 if (bsp->st_nlink >= (1 << 15)) 493 lsp->lst_nlink = (1 << 15) - 1; 494 else 495 lsp->lst_nlink = (linux_nlink_t)bsp->st_nlink; 496 lsp->lst_uid = bsp->st_uid; 497 lsp->lst_gid = bsp->st_gid; 498 lsp->lst_rdev = linux_fakedev(bsp->st_rdev, 1); 499 lsp->lst_size = bsp->st_size; 500 lsp->lst_blksize = bsp->st_blksize; 501 lsp->lst_blocks = bsp->st_blocks; 502 lsp->lst_atime = bsp->st_atime; 503 lsp->lst_mtime = bsp->st_mtime; 504 lsp->lst_ctime = bsp->st_ctime; 505 } 506 507 /* 508 * The stat functions below are plain sailing. stat and lstat are handled 509 * by one function to avoid code duplication. 510 */ 511 int 512 linux_sys_fstat(l, v, retval) 513 struct lwp *l; 514 void *v; 515 register_t *retval; 516 { 517 struct linux_sys_fstat_args /* { 518 syscallarg(int) fd; 519 syscallarg(linux_stat *) sp; 520 } */ *uap = v; 521 struct proc *p = l->l_proc; 522 struct sys___fstat13_args fsa; 523 struct linux_stat tmplst; 524 struct stat *st,tmpst; 525 caddr_t sg; 526 int error; 527 528 sg = stackgap_init(p, 0); 529 530 st = stackgap_alloc(p, &sg, sizeof (struct stat)); 531 532 SCARG(&fsa, fd) = SCARG(uap, fd); 533 SCARG(&fsa, sb) = st; 534 535 if ((error = sys___fstat13(l, &fsa, retval))) 536 return error; 537 538 if ((error = copyin(st, &tmpst, sizeof tmpst))) 539 return error; 540 541 bsd_to_linux_stat(&tmpst, &tmplst); 542 543 if ((error = copyout(&tmplst, SCARG(uap, sp), sizeof tmplst))) 544 return error; 545 546 return 0; 547 } 548 549 static int 550 linux_stat1(l, v, retval, dolstat) 551 struct lwp *l; 552 void *v; 553 register_t *retval; 554 int dolstat; 555 { 556 struct sys___stat13_args sa; 557 struct linux_stat tmplst; 558 struct stat *st, tmpst; 559 struct proc *p = l->l_proc; 560 caddr_t sg; 561 int error; 562 struct linux_sys_stat_args *uap = v; 563 564 sg = stackgap_init(p, 0); 565 st = stackgap_alloc(p, &sg, sizeof (struct stat)); 566 if (dolstat) 567 CHECK_ALT_SYMLINK(p, &sg, SCARG(uap, path)); 568 else 569 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 570 571 SCARG(&sa, ub) = st; 572 SCARG(&sa, path) = SCARG(uap, path); 573 574 if ((error = (dolstat ? sys___lstat13(l, &sa, retval) : 575 sys___stat13(l, &sa, retval)))) 576 return error; 577 578 if ((error = copyin(st, &tmpst, sizeof tmpst))) 579 return error; 580 581 bsd_to_linux_stat(&tmpst, &tmplst); 582 583 if ((error = copyout(&tmplst, SCARG(uap, sp), sizeof tmplst))) 584 return error; 585 586 return 0; 587 } 588 589 int 590 linux_sys_stat(l, v, retval) 591 struct lwp *l; 592 void *v; 593 register_t *retval; 594 { 595 struct linux_sys_stat_args /* { 596 syscallarg(const char *) path; 597 syscallarg(struct linux_stat *) sp; 598 } */ *uap = v; 599 600 return linux_stat1(l, uap, retval, 0); 601 } 602 603 /* Note: this is "newlstat" in the Linux sources */ 604 /* (we don't bother with the old lstat currently) */ 605 int 606 linux_sys_lstat(l, v, retval) 607 struct lwp *l; 608 void *v; 609 register_t *retval; 610 { 611 struct linux_sys_lstat_args /* { 612 syscallarg(const char *) path; 613 syscallarg(struct linux_stat *) sp; 614 } */ *uap = v; 615 616 return linux_stat1(l, uap, retval, 1); 617 } 618 619 /* 620 * The following syscalls are mostly here because of the alternate path check. 621 */ 622 int 623 linux_sys_access(l, v, retval) 624 struct lwp *l; 625 void *v; 626 register_t *retval; 627 { 628 struct linux_sys_access_args /* { 629 syscallarg(const char *) path; 630 syscallarg(int) flags; 631 } */ *uap = v; 632 struct proc *p = l->l_proc; 633 caddr_t sg = stackgap_init(p, 0); 634 635 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 636 637 return sys_access(l, uap, retval); 638 } 639 640 int 641 linux_sys_unlink(l, v, retval) 642 struct lwp *l; 643 void *v; 644 register_t *retval; 645 646 { 647 struct linux_sys_unlink_args /* { 648 syscallarg(const char *) path; 649 } */ *uap = v; 650 struct proc *p = l->l_proc; 651 caddr_t sg = stackgap_init(p, 0); 652 653 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 654 655 return sys_unlink(l, uap, retval); 656 } 657 658 int 659 linux_sys_chdir(l, v, retval) 660 struct lwp *l; 661 void *v; 662 register_t *retval; 663 { 664 struct linux_sys_chdir_args /* { 665 syscallarg(const char *) path; 666 } */ *uap = v; 667 struct proc *p = l->l_proc; 668 caddr_t sg = stackgap_init(p, 0); 669 670 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 671 672 return sys_chdir(l, uap, retval); 673 } 674 675 int 676 linux_sys_mknod(l, v, retval) 677 struct lwp *l; 678 void *v; 679 register_t *retval; 680 { 681 struct linux_sys_mknod_args /* { 682 syscallarg(const char *) path; 683 syscallarg(int) mode; 684 syscallarg(int) dev; 685 } */ *uap = v; 686 struct proc *p = l->l_proc; 687 caddr_t sg = stackgap_init(p, 0); 688 689 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path)); 690 691 /* 692 * BSD handles FIFOs separately 693 */ 694 if (SCARG(uap, mode) & S_IFIFO) { 695 struct sys_mkfifo_args bma; 696 697 SCARG(&bma, path) = SCARG(uap, path); 698 SCARG(&bma, mode) = SCARG(uap, mode); 699 return sys_mkfifo(l, &bma, retval); 700 } else { 701 struct sys_mknod_args bma; 702 703 SCARG(&bma, path) = SCARG(uap, path); 704 SCARG(&bma, mode) = SCARG(uap, mode); 705 /* 706 * Linux device numbers uses 8 bits for minor and 8 bits 707 * for major. Due to how we map our major and minor, 708 * this just fints into our dev_t. Just mask off the 709 * upper 16bit to remove any random junk. 710 */ 711 SCARG(&bma, dev) = SCARG(uap, dev) & 0xffff; 712 return sys_mknod(l, &bma, retval); 713 } 714 } 715 716 int 717 linux_sys_chmod(l, v, retval) 718 struct lwp *l; 719 void *v; 720 register_t *retval; 721 { 722 struct linux_sys_chmod_args /* { 723 syscallarg(const char *) path; 724 syscallarg(int) mode; 725 } */ *uap = v; 726 struct proc *p = l->l_proc; 727 caddr_t sg = stackgap_init(p, 0); 728 729 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 730 731 return sys_chmod(l, uap, retval); 732 } 733 734 #if defined(__i386__) || defined(__m68k__) || defined(__arm__) 735 int 736 linux_sys_chown16(l, v, retval) 737 struct lwp *l; 738 void *v; 739 register_t *retval; 740 { 741 struct linux_sys_chown16_args /* { 742 syscallarg(const char *) path; 743 syscallarg(int) uid; 744 syscallarg(int) gid; 745 } */ *uap = v; 746 struct proc *p = l->l_proc; 747 struct sys___posix_chown_args bca; 748 caddr_t sg = stackgap_init(p, 0); 749 750 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 751 752 SCARG(&bca, path) = SCARG(uap, path); 753 SCARG(&bca, uid) = ((linux_uid_t)SCARG(uap, uid) == (linux_uid_t)-1) ? 754 (uid_t)-1 : SCARG(uap, uid); 755 SCARG(&bca, gid) = ((linux_gid_t)SCARG(uap, gid) == (linux_gid_t)-1) ? 756 (gid_t)-1 : SCARG(uap, gid); 757 758 return sys___posix_chown(l, &bca, retval); 759 } 760 761 int 762 linux_sys_fchown16(l, v, retval) 763 struct lwp *l; 764 void *v; 765 register_t *retval; 766 { 767 struct linux_sys_fchown16_args /* { 768 syscallarg(int) fd; 769 syscallarg(int) uid; 770 syscallarg(int) gid; 771 } */ *uap = v; 772 struct sys___posix_fchown_args bfa; 773 774 SCARG(&bfa, fd) = SCARG(uap, fd); 775 SCARG(&bfa, uid) = ((linux_uid_t)SCARG(uap, uid) == (linux_uid_t)-1) ? 776 (uid_t)-1 : SCARG(uap, uid); 777 SCARG(&bfa, gid) = ((linux_gid_t)SCARG(uap, gid) == (linux_gid_t)-1) ? 778 (gid_t)-1 : SCARG(uap, gid); 779 780 return sys___posix_fchown(l, &bfa, retval); 781 } 782 783 int 784 linux_sys_lchown16(l, v, retval) 785 struct lwp *l; 786 void *v; 787 register_t *retval; 788 { 789 struct linux_sys_lchown16_args /* { 790 syscallarg(char *) path; 791 syscallarg(int) uid; 792 syscallarg(int) gid; 793 } */ *uap = v; 794 struct proc *p = l->l_proc; 795 struct sys___posix_lchown_args bla; 796 caddr_t sg = stackgap_init(p, 0); 797 798 CHECK_ALT_SYMLINK(p, &sg, SCARG(uap, path)); 799 800 SCARG(&bla, path) = SCARG(uap, path); 801 SCARG(&bla, uid) = ((linux_uid_t)SCARG(uap, uid) == (linux_uid_t)-1) ? 802 (uid_t)-1 : SCARG(uap, uid); 803 SCARG(&bla, gid) = ((linux_gid_t)SCARG(uap, gid) == (linux_gid_t)-1) ? 804 (gid_t)-1 : SCARG(uap, gid); 805 806 return sys___posix_lchown(l, &bla, retval); 807 } 808 #endif /* __i386__ || __m68k__ || __arm__ */ 809 #if defined (__i386__) || defined (__m68k__) || \ 810 defined (__powerpc__) || defined (__mips__) || defined(__arm__) 811 int 812 linux_sys_chown(l, v, retval) 813 struct lwp *l; 814 void *v; 815 register_t *retval; 816 { 817 struct linux_sys_chown_args /* { 818 syscallarg(char *) path; 819 syscallarg(int) uid; 820 syscallarg(int) gid; 821 } */ *uap = v; 822 struct proc *p = l->l_proc; 823 caddr_t sg = stackgap_init(p, 0); 824 825 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 826 827 return sys___posix_chown(l, uap, retval); 828 } 829 830 int 831 linux_sys_lchown(l, v, retval) 832 struct lwp *l; 833 void *v; 834 register_t *retval; 835 { 836 struct linux_sys_lchown_args /* { 837 syscallarg(char *) path; 838 syscallarg(int) uid; 839 syscallarg(int) gid; 840 } */ *uap = v; 841 struct proc *p = l->l_proc; 842 caddr_t sg = stackgap_init(p, 0); 843 844 CHECK_ALT_SYMLINK(p, &sg, SCARG(uap, path)); 845 846 return sys___posix_lchown(l, uap, retval); 847 } 848 #endif /* __i386__ || __m68k__ || __powerpc__ || __mips__ || __arm__ */ 849 850 int 851 linux_sys_rename(l, v, retval) 852 struct lwp *l; 853 void *v; 854 register_t *retval; 855 { 856 struct linux_sys_rename_args /* { 857 syscallarg(const char *) from; 858 syscallarg(const char *) to; 859 } */ *uap = v; 860 struct proc *p = l->l_proc; 861 caddr_t sg = stackgap_init(p, 0); 862 863 CHECK_ALT_EXIST(p, &sg, SCARG(uap, from)); 864 CHECK_ALT_CREAT(p, &sg, SCARG(uap, to)); 865 866 return sys___posix_rename(l, uap, retval); 867 } 868 869 int 870 linux_sys_mkdir(l, v, retval) 871 struct lwp *l; 872 void *v; 873 register_t *retval; 874 { 875 struct linux_sys_mkdir_args /* { 876 syscallarg(const char *) path; 877 syscallarg(int) mode; 878 } */ *uap = v; 879 struct proc *p = l->l_proc; 880 caddr_t sg = stackgap_init(p, 0); 881 882 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path)); 883 884 return sys_mkdir(l, uap, retval); 885 } 886 887 int 888 linux_sys_rmdir(l, v, retval) 889 struct lwp *l; 890 void *v; 891 register_t *retval; 892 { 893 struct linux_sys_rmdir_args /* { 894 syscallarg(const char *) path; 895 } */ *uap = v; 896 struct proc *p = l->l_proc; 897 caddr_t sg = stackgap_init(p, 0); 898 899 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 900 901 return sys_rmdir(l, uap, retval); 902 } 903 904 int 905 linux_sys_symlink(l, v, retval) 906 struct lwp *l; 907 void *v; 908 register_t *retval; 909 { 910 struct linux_sys_symlink_args /* { 911 syscallarg(const char *) path; 912 syscallarg(const char *) to; 913 } */ *uap = v; 914 struct proc *p = l->l_proc; 915 caddr_t sg = stackgap_init(p, 0); 916 917 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 918 CHECK_ALT_CREAT(p, &sg, SCARG(uap, to)); 919 920 return sys_symlink(l, uap, retval); 921 } 922 923 int 924 linux_sys_link(l, v, retval) 925 struct lwp *l; 926 void *v; 927 register_t *retval; 928 { 929 struct linux_sys_link_args /* { 930 syscallarg(const char *) path; 931 syscallarg(const char *) link; 932 } */ *uap = v; 933 struct proc *p = l->l_proc; 934 caddr_t sg = stackgap_init(p, 0); 935 936 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 937 CHECK_ALT_CREAT(p, &sg, SCARG(uap, link)); 938 939 return sys_link(l, uap, retval); 940 } 941 942 int 943 linux_sys_readlink(l, v, retval) 944 struct lwp *l; 945 void *v; 946 register_t *retval; 947 { 948 struct linux_sys_readlink_args /* { 949 syscallarg(const char *) name; 950 syscallarg(char *) buf; 951 syscallarg(int) count; 952 } */ *uap = v; 953 struct proc *p = l->l_proc; 954 caddr_t sg = stackgap_init(p, 0); 955 956 CHECK_ALT_SYMLINK(p, &sg, SCARG(uap, name)); 957 958 return sys_readlink(l, uap, retval); 959 } 960 961 int 962 linux_sys_truncate(l, v, retval) 963 struct lwp *l; 964 void *v; 965 register_t *retval; 966 { 967 struct linux_sys_truncate_args /* { 968 syscallarg(const char *) path; 969 syscallarg(long) length; 970 } */ *uap = v; 971 struct proc *p = l->l_proc; 972 caddr_t sg = stackgap_init(p, 0); 973 974 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 975 976 return compat_43_sys_truncate(l, uap, retval); 977 } 978 979 /* 980 * This is just fsync() for now (just as it is in the Linux kernel) 981 * Note: this is not implemented under Linux on Alpha and Arm 982 * but should still be defined in our syscalls.master. 983 * (syscall #148 on the arm) 984 */ 985 int 986 linux_sys_fdatasync(l, v, retval) 987 struct lwp *l; 988 void *v; 989 register_t *retval; 990 { 991 #ifdef notdef 992 struct linux_sys_fdatasync_args /* { 993 syscallarg(int) fd; 994 } */ *uap = v; 995 #endif 996 return sys_fsync(l, v, retval); 997 } 998 999 /* 1000 * pread(2). 1001 */ 1002 int 1003 linux_sys_pread(l, v, retval) 1004 struct lwp *l; 1005 void *v; 1006 register_t *retval; 1007 { 1008 struct linux_sys_pread_args /* { 1009 syscallarg(int) fd; 1010 syscallarg(void *) buf; 1011 syscallarg(size_t) nbyte; 1012 syscallarg(linux_off_t) offset; 1013 } */ *uap = v; 1014 struct sys_pread_args pra; 1015 1016 SCARG(&pra, fd) = SCARG(uap, fd); 1017 SCARG(&pra, buf) = SCARG(uap, buf); 1018 SCARG(&pra, nbyte) = SCARG(uap, nbyte); 1019 SCARG(&pra, offset) = SCARG(uap, offset); 1020 1021 return sys_read(l, &pra, retval); 1022 } 1023 1024 /* 1025 * pwrite(2). 1026 */ 1027 int 1028 linux_sys_pwrite(l, v, retval) 1029 struct lwp *l; 1030 void *v; 1031 register_t *retval; 1032 { 1033 struct linux_sys_pwrite_args /* { 1034 syscallarg(int) fd; 1035 syscallarg(void *) buf; 1036 syscallarg(size_t) nbyte; 1037 syscallarg(linux_off_t) offset; 1038 } */ *uap = v; 1039 struct sys_pwrite_args pra; 1040 1041 SCARG(&pra, fd) = SCARG(uap, fd); 1042 SCARG(&pra, buf) = SCARG(uap, buf); 1043 SCARG(&pra, nbyte) = SCARG(uap, nbyte); 1044 SCARG(&pra, offset) = SCARG(uap, offset); 1045 1046 return sys_write(l, &pra, retval); 1047 } 1048