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