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