vfs_vnops.c revision 1.1.1.2 1 1.1.1.2 fvdl /*
2 1.1.1.2 fvdl * Copyright (c) 1982, 1986, 1989, 1993
3 1.1.1.2 fvdl * The Regents of the University of California. All rights reserved.
4 1.1.1.2 fvdl * (c) UNIX System Laboratories, Inc.
5 1.1.1.2 fvdl * All or some portions of this file are derived from material licensed
6 1.1.1.2 fvdl * to the University of California by American Telephone and Telegraph
7 1.1.1.2 fvdl * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 1.1.1.2 fvdl * the permission of UNIX System Laboratories, Inc.
9 1.1.1.2 fvdl *
10 1.1.1.2 fvdl * Redistribution and use in source and binary forms, with or without
11 1.1.1.2 fvdl * modification, are permitted provided that the following conditions
12 1.1.1.2 fvdl * are met:
13 1.1.1.2 fvdl * 1. Redistributions of source code must retain the above copyright
14 1.1.1.2 fvdl * notice, this list of conditions and the following disclaimer.
15 1.1.1.2 fvdl * 2. Redistributions in binary form must reproduce the above copyright
16 1.1.1.2 fvdl * notice, this list of conditions and the following disclaimer in the
17 1.1.1.2 fvdl * documentation and/or other materials provided with the distribution.
18 1.1.1.2 fvdl * 3. All advertising materials mentioning features or use of this software
19 1.1.1.2 fvdl * must display the following acknowledgement:
20 1.1.1.2 fvdl * This product includes software developed by the University of
21 1.1.1.2 fvdl * California, Berkeley and its contributors.
22 1.1.1.2 fvdl * 4. Neither the name of the University nor the names of its contributors
23 1.1.1.2 fvdl * may be used to endorse or promote products derived from this software
24 1.1.1.2 fvdl * without specific prior written permission.
25 1.1.1.2 fvdl *
26 1.1.1.2 fvdl * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 1.1.1.2 fvdl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 1.1.1.2 fvdl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 1.1.1.2 fvdl * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 1.1.1.2 fvdl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 1.1.1.2 fvdl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 1.1.1.2 fvdl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 1.1.1.2 fvdl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 1.1.1.2 fvdl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 1.1.1.2 fvdl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 1.1.1.2 fvdl * SUCH DAMAGE.
37 1.1.1.2 fvdl *
38 1.1.1.2 fvdl * @(#)vfs_vnops.c 8.2 (Berkeley) 1/21/94
39 1.1.1.2 fvdl */
40 1.1.1.2 fvdl
41 1.1.1.2 fvdl #include <sys/param.h>
42 1.1.1.2 fvdl #include <sys/systm.h>
43 1.1.1.2 fvdl #include <sys/kernel.h>
44 1.1.1.2 fvdl #include <sys/file.h>
45 1.1.1.2 fvdl #include <sys/stat.h>
46 1.1.1.2 fvdl #include <sys/buf.h>
47 1.1.1.2 fvdl #include <sys/proc.h>
48 1.1.1.2 fvdl #include <sys/mount.h>
49 1.1.1.2 fvdl #include <sys/namei.h>
50 1.1.1.2 fvdl #include <sys/vnode.h>
51 1.1.1.2 fvdl #include <sys/ioctl.h>
52 1.1.1.2 fvdl #include <sys/tty.h>
53 1.1.1.2 fvdl
54 1.1.1.2 fvdl #include <vm/vm.h>
55 1.1.1.2 fvdl
56 1.1.1.2 fvdl struct fileops vnops =
57 1.1.1.2 fvdl { vn_read, vn_write, vn_ioctl, vn_select, vn_closefile };
58 1.1.1.2 fvdl
59 1.1.1.2 fvdl /*
60 1.1.1.2 fvdl * Common code for vnode open operations.
61 1.1.1.2 fvdl * Check permissions, and call the VOP_OPEN or VOP_CREATE routine.
62 1.1.1.2 fvdl */
63 1.1.1.2 fvdl vn_open(ndp, fmode, cmode)
64 1.1.1.2 fvdl register struct nameidata *ndp;
65 1.1.1.2 fvdl int fmode, cmode;
66 1.1.1.2 fvdl {
67 1.1.1.2 fvdl register struct vnode *vp;
68 1.1.1.2 fvdl register struct proc *p = ndp->ni_cnd.cn_proc;
69 1.1.1.2 fvdl register struct ucred *cred = p->p_ucred;
70 1.1.1.2 fvdl struct vattr vat;
71 1.1.1.2 fvdl struct vattr *vap = &vat;
72 1.1.1.2 fvdl int error;
73 1.1.1.2 fvdl
74 1.1.1.2 fvdl if (fmode & O_CREAT) {
75 1.1.1.2 fvdl ndp->ni_cnd.cn_nameiop = CREATE;
76 1.1.1.2 fvdl ndp->ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF;
77 1.1.1.2 fvdl if ((fmode & O_EXCL) == 0)
78 1.1.1.2 fvdl ndp->ni_cnd.cn_flags |= FOLLOW;
79 1.1.1.2 fvdl if (error = namei(ndp))
80 1.1.1.2 fvdl return (error);
81 1.1.1.2 fvdl if (ndp->ni_vp == NULL) {
82 1.1.1.2 fvdl VATTR_NULL(vap);
83 1.1.1.2 fvdl vap->va_type = VREG;
84 1.1.1.2 fvdl vap->va_mode = cmode;
85 1.1.1.2 fvdl LEASE_CHECK(ndp->ni_dvp, p, cred, LEASE_WRITE);
86 1.1.1.2 fvdl if (error = VOP_CREATE(ndp->ni_dvp, &ndp->ni_vp,
87 1.1.1.2 fvdl &ndp->ni_cnd, vap))
88 1.1.1.2 fvdl return (error);
89 1.1.1.2 fvdl fmode &= ~O_TRUNC;
90 1.1.1.2 fvdl vp = ndp->ni_vp;
91 1.1.1.2 fvdl } else {
92 1.1.1.2 fvdl VOP_ABORTOP(ndp->ni_dvp, &ndp->ni_cnd);
93 1.1.1.2 fvdl if (ndp->ni_dvp == ndp->ni_vp)
94 1.1.1.2 fvdl vrele(ndp->ni_dvp);
95 1.1.1.2 fvdl else
96 1.1.1.2 fvdl vput(ndp->ni_dvp);
97 1.1.1.2 fvdl ndp->ni_dvp = NULL;
98 1.1.1.2 fvdl vp = ndp->ni_vp;
99 1.1.1.2 fvdl if (fmode & O_EXCL) {
100 1.1.1.2 fvdl error = EEXIST;
101 1.1.1.2 fvdl goto bad;
102 1.1.1.2 fvdl }
103 1.1.1.2 fvdl fmode &= ~O_CREAT;
104 1.1.1.2 fvdl }
105 1.1.1.2 fvdl } else {
106 1.1.1.2 fvdl ndp->ni_cnd.cn_nameiop = LOOKUP;
107 1.1.1.2 fvdl ndp->ni_cnd.cn_flags = FOLLOW | LOCKLEAF;
108 1.1.1.2 fvdl if (error = namei(ndp))
109 1.1.1.2 fvdl return (error);
110 1.1.1.2 fvdl vp = ndp->ni_vp;
111 1.1.1.2 fvdl }
112 1.1.1.2 fvdl if (vp->v_type == VSOCK) {
113 1.1.1.2 fvdl error = EOPNOTSUPP;
114 1.1.1.2 fvdl goto bad;
115 1.1.1.2 fvdl }
116 1.1.1.2 fvdl if ((fmode & O_CREAT) == 0) {
117 1.1.1.2 fvdl if (fmode & FREAD) {
118 1.1.1.2 fvdl if (error = VOP_ACCESS(vp, VREAD, cred, p))
119 1.1.1.2 fvdl goto bad;
120 1.1.1.2 fvdl }
121 1.1.1.2 fvdl if (fmode & (FWRITE | O_TRUNC)) {
122 1.1.1.2 fvdl if (vp->v_type == VDIR) {
123 1.1.1.2 fvdl error = EISDIR;
124 1.1.1.2 fvdl goto bad;
125 1.1.1.2 fvdl }
126 1.1.1.2 fvdl if ((error = vn_writechk(vp)) ||
127 1.1.1.2 fvdl (error = VOP_ACCESS(vp, VWRITE, cred, p)))
128 1.1.1.2 fvdl goto bad;
129 1.1.1.2 fvdl }
130 1.1.1.2 fvdl }
131 1.1.1.2 fvdl if (fmode & O_TRUNC) {
132 1.1.1.2 fvdl VOP_UNLOCK(vp); /* XXX */
133 1.1.1.2 fvdl LEASE_CHECK(vp, p, cred, LEASE_WRITE);
134 1.1.1.2 fvdl VOP_LOCK(vp); /* XXX */
135 1.1.1.2 fvdl VATTR_NULL(vap);
136 1.1.1.2 fvdl vap->va_size = 0;
137 1.1.1.2 fvdl if (error = VOP_SETATTR(vp, vap, cred, p))
138 1.1.1.2 fvdl goto bad;
139 1.1.1.2 fvdl }
140 1.1.1.2 fvdl if (error = VOP_OPEN(vp, fmode, cred, p))
141 1.1.1.2 fvdl goto bad;
142 1.1.1.2 fvdl if (fmode & FWRITE)
143 1.1.1.2 fvdl vp->v_writecount++;
144 1.1.1.2 fvdl return (0);
145 1.1.1.2 fvdl bad:
146 1.1.1.2 fvdl vput(vp);
147 1.1.1.2 fvdl return (error);
148 1.1.1.2 fvdl }
149 1.1.1.2 fvdl
150 1.1.1.2 fvdl /*
151 1.1.1.2 fvdl * Check for write permissions on the specified vnode.
152 1.1.1.2 fvdl * The read-only status of the file system is checked.
153 1.1.1.2 fvdl * Also, prototype text segments cannot be written.
154 1.1.1.2 fvdl */
155 1.1.1.2 fvdl vn_writechk(vp)
156 1.1.1.2 fvdl register struct vnode *vp;
157 1.1.1.2 fvdl {
158 1.1.1.2 fvdl
159 1.1.1.2 fvdl /*
160 1.1.1.2 fvdl * Disallow write attempts on read-only file systems;
161 1.1.1.2 fvdl * unless the file is a socket or a block or character
162 1.1.1.2 fvdl * device resident on the file system.
163 1.1.1.2 fvdl */
164 1.1.1.2 fvdl if (vp->v_mount->mnt_flag & MNT_RDONLY) {
165 1.1.1.2 fvdl switch (vp->v_type) {
166 1.1.1.2 fvdl case VREG: case VDIR: case VLNK:
167 1.1.1.2 fvdl return (EROFS);
168 1.1.1.2 fvdl }
169 1.1.1.2 fvdl }
170 1.1.1.2 fvdl /*
171 1.1.1.2 fvdl * If there's shared text associated with
172 1.1.1.2 fvdl * the vnode, try to free it up once. If
173 1.1.1.2 fvdl * we fail, we can't allow writing.
174 1.1.1.2 fvdl */
175 1.1.1.2 fvdl if ((vp->v_flag & VTEXT) && !vnode_pager_uncache(vp))
176 1.1.1.2 fvdl return (ETXTBSY);
177 1.1.1.2 fvdl return (0);
178 1.1.1.2 fvdl }
179 1.1.1.2 fvdl
180 1.1.1.2 fvdl /*
181 1.1.1.2 fvdl * Vnode close call
182 1.1.1.2 fvdl */
183 1.1.1.2 fvdl vn_close(vp, flags, cred, p)
184 1.1.1.2 fvdl register struct vnode *vp;
185 1.1.1.2 fvdl int flags;
186 1.1.1.2 fvdl struct ucred *cred;
187 1.1.1.2 fvdl struct proc *p;
188 1.1.1.2 fvdl {
189 1.1.1.2 fvdl int error;
190 1.1.1.2 fvdl
191 1.1.1.2 fvdl if (flags & FWRITE)
192 1.1.1.2 fvdl vp->v_writecount--;
193 1.1.1.2 fvdl error = VOP_CLOSE(vp, flags, cred, p);
194 1.1.1.2 fvdl vrele(vp);
195 1.1.1.2 fvdl return (error);
196 1.1.1.2 fvdl }
197 1.1.1.2 fvdl
198 1.1.1.2 fvdl /*
199 1.1.1.2 fvdl * Package up an I/O request on a vnode into a uio and do it.
200 1.1.1.2 fvdl */
201 1.1.1.2 fvdl vn_rdwr(rw, vp, base, len, offset, segflg, ioflg, cred, aresid, p)
202 1.1.1.2 fvdl enum uio_rw rw;
203 1.1.1.2 fvdl struct vnode *vp;
204 1.1.1.2 fvdl caddr_t base;
205 1.1.1.2 fvdl int len;
206 1.1.1.2 fvdl off_t offset;
207 1.1.1.2 fvdl enum uio_seg segflg;
208 1.1.1.2 fvdl int ioflg;
209 1.1.1.2 fvdl struct ucred *cred;
210 1.1.1.2 fvdl int *aresid;
211 1.1.1.2 fvdl struct proc *p;
212 1.1.1.2 fvdl {
213 1.1.1.2 fvdl struct uio auio;
214 1.1.1.2 fvdl struct iovec aiov;
215 1.1.1.2 fvdl int error;
216 1.1.1.2 fvdl
217 1.1.1.2 fvdl if ((ioflg & IO_NODELOCKED) == 0)
218 1.1.1.2 fvdl VOP_LOCK(vp);
219 1.1.1.2 fvdl auio.uio_iov = &aiov;
220 1.1.1.2 fvdl auio.uio_iovcnt = 1;
221 1.1.1.2 fvdl aiov.iov_base = base;
222 1.1.1.2 fvdl aiov.iov_len = len;
223 1.1.1.2 fvdl auio.uio_resid = len;
224 1.1.1.2 fvdl auio.uio_offset = offset;
225 1.1.1.2 fvdl auio.uio_segflg = segflg;
226 1.1.1.2 fvdl auio.uio_rw = rw;
227 1.1.1.2 fvdl auio.uio_procp = p;
228 1.1.1.2 fvdl if (rw == UIO_READ) {
229 1.1.1.2 fvdl error = VOP_READ(vp, &auio, ioflg, cred);
230 1.1.1.2 fvdl } else {
231 1.1.1.2 fvdl error = VOP_WRITE(vp, &auio, ioflg, cred);
232 1.1.1.2 fvdl }
233 1.1.1.2 fvdl if (aresid)
234 1.1.1.2 fvdl *aresid = auio.uio_resid;
235 1.1.1.2 fvdl else
236 1.1.1.2 fvdl if (auio.uio_resid && error == 0)
237 1.1.1.2 fvdl error = EIO;
238 1.1.1.2 fvdl if ((ioflg & IO_NODELOCKED) == 0)
239 1.1.1.2 fvdl VOP_UNLOCK(vp);
240 1.1.1.2 fvdl return (error);
241 1.1.1.2 fvdl }
242 1.1.1.2 fvdl
243 1.1.1.2 fvdl /*
244 1.1.1.2 fvdl * File table vnode read routine.
245 1.1.1.2 fvdl */
246 1.1.1.2 fvdl vn_read(fp, uio, cred)
247 1.1.1.2 fvdl struct file *fp;
248 1.1.1.2 fvdl struct uio *uio;
249 1.1.1.2 fvdl struct ucred *cred;
250 1.1.1.2 fvdl {
251 1.1.1.2 fvdl register struct vnode *vp = (struct vnode *)fp->f_data;
252 1.1.1.2 fvdl int count, error;
253 1.1.1.2 fvdl
254 1.1.1.2 fvdl LEASE_CHECK(vp, uio->uio_procp, cred, LEASE_READ);
255 1.1.1.2 fvdl VOP_LOCK(vp);
256 1.1.1.2 fvdl uio->uio_offset = fp->f_offset;
257 1.1.1.2 fvdl count = uio->uio_resid;
258 1.1.1.2 fvdl error = VOP_READ(vp, uio, (fp->f_flag & FNONBLOCK) ? IO_NDELAY : 0,
259 1.1.1.2 fvdl cred);
260 1.1.1.2 fvdl fp->f_offset += count - uio->uio_resid;
261 1.1.1.2 fvdl VOP_UNLOCK(vp);
262 1.1.1.2 fvdl return (error);
263 1.1.1.2 fvdl }
264 1.1.1.2 fvdl
265 1.1.1.2 fvdl /*
266 1.1.1.2 fvdl * File table vnode write routine.
267 1.1.1.2 fvdl */
268 1.1.1.2 fvdl vn_write(fp, uio, cred)
269 1.1.1.2 fvdl struct file *fp;
270 1.1.1.2 fvdl struct uio *uio;
271 1.1.1.2 fvdl struct ucred *cred;
272 1.1.1.2 fvdl {
273 1.1.1.2 fvdl register struct vnode *vp = (struct vnode *)fp->f_data;
274 1.1.1.2 fvdl int count, error, ioflag = 0;
275 1.1.1.2 fvdl
276 1.1.1.2 fvdl if (vp->v_type == VREG && (fp->f_flag & O_APPEND))
277 1.1.1.2 fvdl ioflag |= IO_APPEND;
278 1.1.1.2 fvdl if (fp->f_flag & FNONBLOCK)
279 1.1.1.2 fvdl ioflag |= IO_NDELAY;
280 1.1.1.2 fvdl LEASE_CHECK(vp, uio->uio_procp, cred, LEASE_WRITE);
281 1.1.1.2 fvdl VOP_LOCK(vp);
282 1.1.1.2 fvdl uio->uio_offset = fp->f_offset;
283 1.1.1.2 fvdl count = uio->uio_resid;
284 1.1.1.2 fvdl error = VOP_WRITE(vp, uio, ioflag, cred);
285 1.1.1.2 fvdl if (ioflag & IO_APPEND)
286 1.1.1.2 fvdl fp->f_offset = uio->uio_offset;
287 1.1.1.2 fvdl else
288 1.1.1.2 fvdl fp->f_offset += count - uio->uio_resid;
289 1.1.1.2 fvdl VOP_UNLOCK(vp);
290 1.1.1.2 fvdl return (error);
291 1.1.1.2 fvdl }
292 1.1.1.2 fvdl
293 1.1.1.2 fvdl /*
294 1.1.1.2 fvdl * File table vnode stat routine.
295 1.1.1.2 fvdl */
296 1.1.1.2 fvdl vn_stat(vp, sb, p)
297 1.1.1.2 fvdl struct vnode *vp;
298 1.1.1.2 fvdl register struct stat *sb;
299 1.1.1.2 fvdl struct proc *p;
300 1.1.1.2 fvdl {
301 1.1.1.2 fvdl struct vattr vattr;
302 1.1.1.2 fvdl register struct vattr *vap;
303 1.1.1.2 fvdl int error;
304 1.1.1.2 fvdl u_short mode;
305 1.1.1.2 fvdl
306 1.1.1.2 fvdl vap = &vattr;
307 1.1.1.2 fvdl error = VOP_GETATTR(vp, vap, p->p_ucred, p);
308 1.1.1.2 fvdl if (error)
309 1.1.1.2 fvdl return (error);
310 1.1.1.2 fvdl /*
311 1.1.1.2 fvdl * Copy from vattr table
312 1.1.1.2 fvdl */
313 1.1.1.2 fvdl sb->st_dev = vap->va_fsid;
314 1.1.1.2 fvdl sb->st_ino = vap->va_fileid;
315 1.1.1.2 fvdl mode = vap->va_mode;
316 1.1.1.2 fvdl switch (vp->v_type) {
317 1.1.1.2 fvdl case VREG:
318 1.1.1.2 fvdl mode |= S_IFREG;
319 1.1.1.2 fvdl break;
320 1.1.1.2 fvdl case VDIR:
321 1.1.1.2 fvdl mode |= S_IFDIR;
322 1.1.1.2 fvdl break;
323 1.1.1.2 fvdl case VBLK:
324 1.1.1.2 fvdl mode |= S_IFBLK;
325 1.1.1.2 fvdl break;
326 1.1.1.2 fvdl case VCHR:
327 1.1.1.2 fvdl mode |= S_IFCHR;
328 1.1.1.2 fvdl break;
329 1.1.1.2 fvdl case VLNK:
330 1.1.1.2 fvdl mode |= S_IFLNK;
331 1.1.1.2 fvdl break;
332 1.1.1.2 fvdl case VSOCK:
333 1.1.1.2 fvdl mode |= S_IFSOCK;
334 1.1.1.2 fvdl break;
335 1.1.1.2 fvdl case VFIFO:
336 1.1.1.2 fvdl mode |= S_IFIFO;
337 1.1.1.2 fvdl break;
338 1.1.1.2 fvdl default:
339 1.1.1.2 fvdl return (EBADF);
340 1.1.1.2 fvdl };
341 1.1.1.2 fvdl sb->st_mode = mode;
342 1.1.1.2 fvdl sb->st_nlink = vap->va_nlink;
343 1.1.1.2 fvdl sb->st_uid = vap->va_uid;
344 1.1.1.2 fvdl sb->st_gid = vap->va_gid;
345 1.1.1.2 fvdl sb->st_rdev = vap->va_rdev;
346 1.1.1.2 fvdl sb->st_size = vap->va_size;
347 1.1.1.2 fvdl sb->st_atimespec = vap->va_atime;
348 1.1.1.2 fvdl sb->st_mtimespec= vap->va_mtime;
349 1.1.1.2 fvdl sb->st_ctimespec = vap->va_ctime;
350 1.1.1.2 fvdl sb->st_blksize = vap->va_blocksize;
351 1.1.1.2 fvdl sb->st_flags = vap->va_flags;
352 1.1.1.2 fvdl sb->st_gen = vap->va_gen;
353 1.1.1.2 fvdl sb->st_blocks = vap->va_bytes / S_BLKSIZE;
354 1.1.1.2 fvdl return (0);
355 1.1.1.2 fvdl }
356 1.1.1.2 fvdl
357 1.1.1.2 fvdl /*
358 1.1.1.2 fvdl * File table vnode ioctl routine.
359 1.1.1.2 fvdl */
360 1.1.1.2 fvdl vn_ioctl(fp, com, data, p)
361 1.1.1.2 fvdl struct file *fp;
362 1.1.1.2 fvdl int com;
363 1.1.1.2 fvdl caddr_t data;
364 1.1.1.2 fvdl struct proc *p;
365 1.1.1.2 fvdl {
366 1.1.1.2 fvdl register struct vnode *vp = ((struct vnode *)fp->f_data);
367 1.1.1.2 fvdl struct vattr vattr;
368 1.1.1.2 fvdl int error;
369 1.1.1.2 fvdl
370 1.1.1.2 fvdl switch (vp->v_type) {
371 1.1.1.2 fvdl
372 1.1.1.2 fvdl case VREG:
373 1.1.1.2 fvdl case VDIR:
374 1.1.1.2 fvdl if (com == FIONREAD) {
375 1.1.1.2 fvdl if (error = VOP_GETATTR(vp, &vattr, p->p_ucred, p))
376 1.1.1.2 fvdl return (error);
377 1.1.1.2 fvdl *(int *)data = vattr.va_size - fp->f_offset;
378 1.1.1.2 fvdl return (0);
379 1.1.1.2 fvdl }
380 1.1.1.2 fvdl if (com == FIONBIO || com == FIOASYNC) /* XXX */
381 1.1.1.2 fvdl return (0); /* XXX */
382 1.1.1.2 fvdl /* fall into ... */
383 1.1.1.2 fvdl
384 1.1.1.2 fvdl default:
385 1.1.1.2 fvdl return (ENOTTY);
386 1.1.1.2 fvdl
387 1.1.1.2 fvdl case VFIFO:
388 1.1.1.2 fvdl case VCHR:
389 1.1.1.2 fvdl case VBLK:
390 1.1.1.2 fvdl error = VOP_IOCTL(vp, com, data, fp->f_flag, p->p_ucred, p);
391 1.1.1.2 fvdl if (error == 0 && com == TIOCSCTTY) {
392 1.1.1.2 fvdl p->p_session->s_ttyvp = vp;
393 1.1.1.2 fvdl VREF(vp);
394 1.1.1.2 fvdl }
395 1.1.1.2 fvdl return (error);
396 1.1.1.2 fvdl }
397 1.1.1.2 fvdl }
398 1.1.1.2 fvdl
399 1.1.1.2 fvdl /*
400 1.1.1.2 fvdl * File table vnode select routine.
401 1.1.1.2 fvdl */
402 1.1.1.2 fvdl vn_select(fp, which, p)
403 1.1.1.2 fvdl struct file *fp;
404 1.1.1.2 fvdl int which;
405 1.1.1.2 fvdl struct proc *p;
406 1.1.1.2 fvdl {
407 1.1.1.2 fvdl
408 1.1.1.2 fvdl return (VOP_SELECT(((struct vnode *)fp->f_data), which, fp->f_flag,
409 1.1.1.2 fvdl fp->f_cred, p));
410 1.1.1.2 fvdl }
411 1.1.1.2 fvdl
412 1.1.1.2 fvdl /*
413 1.1.1.2 fvdl * File table vnode close routine.
414 1.1.1.2 fvdl */
415 1.1.1.2 fvdl vn_closefile(fp, p)
416 1.1.1.2 fvdl struct file *fp;
417 1.1.1.2 fvdl struct proc *p;
418 1.1.1.2 fvdl {
419 1.1.1.2 fvdl
420 1.1.1.2 fvdl return (vn_close(((struct vnode *)fp->f_data), fp->f_flag,
421 1.1.1.2 fvdl fp->f_cred, p));
422 1.1.1.2 fvdl }
423