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