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