Annotation of sys/compat/common/vfs_syscalls_43.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: vfs_syscalls_43.c,v 1.27 2005/05/26 01:15:12 pedro Exp $ */
2: /* $NetBSD: vfs_syscalls_43.c,v 1.4 1996/03/14 19:31:52 christos Exp $ */
3:
4: /*
5: * Copyright (c) 1989, 1993
6: * The Regents of the University of California. All rights reserved.
7: * (c) UNIX System Laboratories, Inc.
8: * All or some portions of this file are derived from material licensed
9: * to the University of California by American Telephone and Telegraph
10: * Co. or Unix System Laboratories, Inc. and are reproduced herein with
11: * the permission of UNIX System Laboratories, Inc.
12: *
13: * Redistribution and use in source and binary forms, with or without
14: * modification, are permitted provided that the following conditions
15: * are met:
16: * 1. Redistributions of source code must retain the above copyright
17: * notice, this list of conditions and the following disclaimer.
18: * 2. Redistributions in binary form must reproduce the above copyright
19: * notice, this list of conditions and the following disclaimer in the
20: * documentation and/or other materials provided with the distribution.
21: * 3. Neither the name of the University nor the names of its contributors
22: * may be used to endorse or promote products derived from this software
23: * without specific prior written permission.
24: *
25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35: * SUCH DAMAGE.
36: *
37: * @(#)vfs_syscalls.c 8.28 (Berkeley) 12/10/94
38: */
39:
40: #include <sys/param.h>
41: #include <sys/systm.h>
42: #include <sys/filedesc.h>
43: #include <sys/kernel.h>
44: #include <sys/proc.h>
45: #include <sys/file.h>
46: #include <sys/vnode.h>
47: #include <sys/namei.h>
48: #include <sys/dirent.h>
49: #include <sys/socket.h>
50: #include <sys/socketvar.h>
51: #include <sys/stat.h>
52: #include <sys/ioctl.h>
53: #include <sys/fcntl.h>
54: #include <sys/malloc.h>
55: #include <sys/syslog.h>
56: #include <sys/unistd.h>
57: #include <sys/resourcevar.h>
58:
59: #include <sys/mount.h>
60: #include <sys/syscallargs.h>
61:
62: #include <uvm/uvm_extern.h>
63:
64: #include <sys/pipe.h>
65:
66: static void cvtstat(struct stat *, struct stat43 *);
67:
68: /*
69: * Convert from a new to an old stat structure.
70: */
71: static void
72: cvtstat(st, ost)
73: struct stat *st;
74: struct stat43 *ost;
75: {
76:
77: ost->st_dev = st->st_dev;
78: ost->st_ino = st->st_ino;
79: ost->st_mode = st->st_mode;
80: ost->st_nlink = st->st_nlink;
81: ost->st_uid = st->st_uid;
82: ost->st_gid = st->st_gid;
83: ost->st_rdev = st->st_rdev;
84: if (st->st_size < (quad_t)1 << 32)
85: ost->st_size = st->st_size;
86: else
87: ost->st_size = -2;
88: ost->st_atime = st->st_atime;
89: ost->st_mtime = st->st_mtime;
90: ost->st_ctime = st->st_ctime;
91: ost->st_blksize = st->st_blksize;
92: ost->st_blocks = st->st_blocks;
93: ost->st_flags = st->st_flags;
94: ost->st_gen = st->st_gen;
95: }
96:
97: /*
98: * Get file status; this version follows links.
99: */
100: /* ARGSUSED */
101: int
102: compat_43_sys_stat(p, v, retval)
103: struct proc *p;
104: void *v;
105: register_t *retval;
106: {
107: register struct compat_43_sys_stat_args /* {
108: syscallarg(char *) path;
109: syscallarg(struct stat43 *) ub;
110: } */ *uap = v;
111: struct stat sb;
112: struct stat43 osb;
113: int error;
114: struct nameidata nd;
115:
116: NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
117: SCARG(uap, path), p);
118: if ((error = namei(&nd)) != 0)
119: return (error);
120: error = vn_stat(nd.ni_vp, &sb, p);
121: vput(nd.ni_vp);
122: if (error)
123: return (error);
124: /* Don't let non-root see generation numbers (for NFS security) */
125: if (suser(p, 0))
126: sb.st_gen = 0;
127: cvtstat(&sb, &osb);
128: error = copyout(&osb, SCARG(uap, ub), sizeof(osb));
129: return (error);
130: }
131:
132:
133: /*
134: * Get file status; this version does not follow links.
135: */
136: /* ARGSUSED */
137: int
138: compat_43_sys_lstat(p, v, retval)
139: struct proc *p;
140: void *v;
141: register_t *retval;
142: {
143: register struct compat_43_sys_lstat_args /* {
144: syscallarg(char *) path;
145: syscallarg(struct stat43 *) ub;
146: } */ *uap = v;
147: struct stat sb;
148: struct stat43 osb;
149: int error;
150: struct nameidata nd;
151:
152: NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE,
153: SCARG(uap, path), p);
154: if ((error = namei(&nd)) != 0)
155: return (error);
156: error = vn_stat(nd.ni_vp, &sb, p);
157: vput(nd.ni_vp);
158: if (error)
159: return (error);
160: /* Don't let non-root see generation numbers (for NFS security) */
161: if (suser(p, 0))
162: sb.st_gen = 0;
163: cvtstat(&sb, &osb);
164: error = copyout(&osb, SCARG(uap, ub), sizeof(osb));
165: return (error);
166: }
167:
168: /*
169: * Return status information about a file descriptor.
170: */
171: /* ARGSUSED */
172: int
173: compat_43_sys_fstat(p, v, retval)
174: struct proc *p;
175: void *v;
176: register_t *retval;
177: {
178: struct compat_43_sys_fstat_args /* {
179: syscallarg(int) fd;
180: syscallarg(struct stat43 *) sb;
181: } */ *uap = v;
182: int fd = SCARG(uap, fd);
183: struct filedesc *fdp = p->p_fd;
184: struct file *fp;
185: struct stat ub;
186: struct stat43 oub;
187: int error;
188:
189: if ((fp = fd_getfile(fdp, fd)) == NULL)
190: return (EBADF);
191: FREF(fp);
192: error = (*fp->f_ops->fo_stat)(fp, &ub, p);
193: FRELE(fp);
194: if (error == 0) {
195: /* Don't let non-root see generation numbers
196: (for NFS security) */
197: if (suser(p, 0))
198: ub.st_gen = 0;
199: cvtstat(&ub, &oub);
200: error = copyout(&oub, SCARG(uap, sb), sizeof(oub));
201: }
202: return (error);
203: }
204:
205: /*
206: * Truncate a file given a file descriptor.
207: */
208: /* ARGSUSED */
209: int
210: compat_43_sys_ftruncate(p, v, retval)
211: struct proc *p;
212: void *v;
213: register_t *retval;
214: {
215: register struct compat_43_sys_ftruncate_args /* {
216: syscallarg(int) fd;
217: syscallarg(long) length;
218: } */ *uap = v;
219: struct sys_ftruncate_args /* {
220: syscallarg(int) fd;
221: syscallarg(int) pad;
222: syscallarg(off_t) length;
223: } */ nuap;
224:
225: SCARG(&nuap, fd) = SCARG(uap, fd);
226: SCARG(&nuap, length) = SCARG(uap, length);
227: return (sys_ftruncate(p, &nuap, retval));
228: }
229:
230: /*
231: * Truncate a file given its path name.
232: */
233: /* ARGSUSED */
234: int
235: compat_43_sys_truncate(p, v, retval)
236: struct proc *p;
237: void *v;
238: register_t *retval;
239: {
240: register struct compat_43_sys_truncate_args /* {
241: syscallarg(char *) path;
242: syscallarg(long) length;
243: } */ *uap = v;
244: struct sys_truncate_args /* {
245: syscallarg(char *) path;
246: syscallarg(int) pad;
247: syscallarg(off_t) length;
248: } */ nuap;
249:
250: SCARG(&nuap, path) = SCARG(uap, path);
251: SCARG(&nuap, length) = SCARG(uap, length);
252: return (sys_truncate(p, &nuap, retval));
253: }
254:
255:
256: /*
257: * Reposition read/write file offset.
258: */
259: int
260: compat_43_sys_lseek(p, v, retval)
261: struct proc *p;
262: void *v;
263: register_t *retval;
264: {
265: register struct compat_43_sys_lseek_args /* {
266: syscallarg(int) fd;
267: syscallarg(long) offset;
268: syscallarg(int) whence;
269: } */ *uap = v;
270: struct sys_lseek_args /* {
271: syscallarg(int) fd;
272: syscallarg(int) pad;
273: syscallarg(off_t) offset;
274: syscallarg(int) whence;
275: } */ nuap;
276: off_t qret;
277: int error;
278:
279: SCARG(&nuap, fd) = SCARG(uap, fd);
280: SCARG(&nuap, offset) = SCARG(uap, offset);
281: SCARG(&nuap, whence) = SCARG(uap, whence);
282: error = sys_lseek(p, &nuap, (register_t *)&qret);
283: *(long *)retval = qret;
284: return (error);
285: }
286:
287:
288: /*
289: * Create a file.
290: */
291: int
292: compat_43_sys_creat(p, v, retval)
293: struct proc *p;
294: void *v;
295: register_t *retval;
296: {
297: register struct compat_43_sys_creat_args /* {
298: syscallarg(char *) path;
299: syscallarg(mode_t) mode;
300: } */ *uap = v;
301: struct sys_open_args /* {
302: syscallarg(char *) path;
303: syscallarg(int) flags;
304: syscallarg(mode_t) mode;
305: } */ nuap;
306:
307: SCARG(&nuap, path) = SCARG(uap, path);
308: SCARG(&nuap, mode) = SCARG(uap, mode);
309: SCARG(&nuap, flags) = O_WRONLY | O_CREAT | O_TRUNC;
310: return (sys_open(p, &nuap, retval));
311: }
312:
313: /*ARGSUSED*/
314: int
315: compat_43_sys_quota(p, v, retval)
316: struct proc *p;
317: void *v;
318: register_t *retval;
319: {
320:
321: return (ENOSYS);
322: }
323:
324:
325: /*
326: * Read a block of directory entries in a file system independent format.
327: */
328: int
329: compat_43_sys_getdirentries(p, v, retval)
330: struct proc *p;
331: void *v;
332: register_t *retval;
333: {
334: register struct compat_43_sys_getdirentries_args /* {
335: syscallarg(int) fd;
336: syscallarg(char *) buf;
337: syscallarg(int) count;
338: syscallarg(long *) basep;
339: } */ *uap = v;
340: struct vnode *vp;
341: struct file *fp;
342: struct uio auio, kuio;
343: struct iovec aiov, kiov;
344: struct dirent *dp, *edp;
345: caddr_t dirbuf;
346: int error, eofflag, readcnt;
347: long loff;
348:
349: if (SCARG(uap, count) < 0)
350: return EINVAL;
351: if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
352: return (error);
353: if ((fp->f_flag & FREAD) == 0) {
354: error = EBADF;
355: goto bad;
356: }
357: vp = (struct vnode *)fp->f_data;
358: if (vp->v_type != VDIR) {
359: error = EINVAL;
360: goto bad;
361: }
362: aiov.iov_base = SCARG(uap, buf);
363: aiov.iov_len = SCARG(uap, count);
364: auio.uio_iov = &aiov;
365: auio.uio_iovcnt = 1;
366: auio.uio_rw = UIO_READ;
367: auio.uio_segflg = UIO_USERSPACE;
368: auio.uio_procp = p;
369: auio.uio_resid = SCARG(uap, count);
370:
371: vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
372: loff = auio.uio_offset = fp->f_offset;
373: # if (BYTE_ORDER != LITTLE_ENDIAN)
374: if (vp->v_mount->mnt_maxsymlinklen <= 0) {
375: error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag,
376: (int *)0, (u_long **)0);
377: fp->f_offset = auio.uio_offset;
378: } else
379: # endif
380: {
381: u_int nbytes = SCARG(uap, count);
382:
383: nbytes = min(nbytes, MAXBSIZE);
384:
385: kuio = auio;
386: kuio.uio_iov = &kiov;
387: kuio.uio_segflg = UIO_SYSSPACE;
388: kiov.iov_len = nbytes;
389: dirbuf = (caddr_t)malloc(nbytes, M_TEMP, M_WAITOK);
390: kiov.iov_base = dirbuf;
391:
392: error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag,
393: 0, 0);
394: fp->f_offset = kuio.uio_offset;
395: if (error == 0) {
396: readcnt = nbytes - kuio.uio_resid;
397: edp = (struct dirent *)&dirbuf[readcnt];
398: for (dp = (struct dirent *)dirbuf; dp < edp; ) {
399: # if (BYTE_ORDER == LITTLE_ENDIAN)
400: /*
401: * The expected low byte of
402: * dp->d_namlen is our dp->d_type.
403: * The high MBZ byte of dp->d_namlen
404: * is our dp->d_namlen.
405: */
406: dp->d_type = dp->d_namlen;
407: dp->d_namlen = 0;
408: # else
409: /*
410: * The dp->d_type is the high byte
411: * of the expected dp->d_namlen,
412: * so must be zero'ed.
413: */
414: dp->d_type = 0;
415: # endif
416: if (dp->d_reclen > 0) {
417: dp = (struct dirent *)
418: ((char *)dp + dp->d_reclen);
419: } else {
420: error = EIO;
421: break;
422: }
423: }
424: if (dp >= edp)
425: error = uiomove(dirbuf, readcnt, &auio);
426: }
427: FREE(dirbuf, M_TEMP);
428: }
429: VOP_UNLOCK(vp, 0, p);
430: if (error)
431: goto bad;
432: error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep),
433: sizeof(long));
434: *retval = SCARG(uap, count) - auio.uio_resid;
435: bad:
436: FRELE(fp);
437: return (error);
438: }
CVSweb