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