Deleted Added
full compact
kern_descrip.c (87905) kern_descrip.c (89306)
1/*
2 * Copyright (c) 1982, 1986, 1989, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.

--- 22 unchanged lines hidden (view full) ---

31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)kern_descrip.c 8.6 (Berkeley) 4/19/94
1/*
2 * Copyright (c) 1982, 1986, 1989, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.

--- 22 unchanged lines hidden (view full) ---

31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)kern_descrip.c 8.6 (Berkeley) 4/19/94
39 * $FreeBSD: head/sys/kern/kern_descrip.c 87905 2001-12-14 19:02:57Z jlemon $
39 * $FreeBSD: head/sys/kern/kern_descrip.c 89306 2002-01-13 11:58:06Z alfred $
40 */
41
42#include "opt_compat.h"
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/lock.h>
47#include <sys/malloc.h>

--- 56 unchanged lines hidden (view full) ---

104static int badfo_close __P((struct file *fp, struct thread *td));
105
106/*
107 * Descriptor management.
108 */
109struct filelist filehead; /* head of list of open files */
110int nfiles; /* actual number of open files */
111extern int cmask;
40 */
41
42#include "opt_compat.h"
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/lock.h>
47#include <sys/malloc.h>

--- 56 unchanged lines hidden (view full) ---

104static int badfo_close __P((struct file *fp, struct thread *td));
105
106/*
107 * Descriptor management.
108 */
109struct filelist filehead; /* head of list of open files */
110int nfiles; /* actual number of open files */
111extern int cmask;
112struct sx filelist_lock; /* sx to protect filelist */
112
113/*
114 * System calls on descriptors.
115 */
116#ifndef _SYS_SYSPROTO_H_
117struct getdtablesize_args {
118 int dummy;
119};

--- 38 unchanged lines hidden (view full) ---

158 struct dup2_args *uap;
159{
160 struct proc *p = td->td_proc;
161 register struct filedesc *fdp = td->td_proc->p_fd;
162 register u_int old = uap->from, new = uap->to;
163 int i, error;
164
165 mtx_lock(&Giant);
113
114/*
115 * System calls on descriptors.
116 */
117#ifndef _SYS_SYSPROTO_H_
118struct getdtablesize_args {
119 int dummy;
120};

--- 38 unchanged lines hidden (view full) ---

159 struct dup2_args *uap;
160{
161 struct proc *p = td->td_proc;
162 register struct filedesc *fdp = td->td_proc->p_fd;
163 register u_int old = uap->from, new = uap->to;
164 int i, error;
165
166 mtx_lock(&Giant);
167 FILEDESC_LOCK(fdp);
166retry:
167 if (old >= fdp->fd_nfiles ||
168 fdp->fd_ofiles[old] == NULL ||
169 new >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
170 new >= maxfilesperproc) {
168retry:
169 if (old >= fdp->fd_nfiles ||
170 fdp->fd_ofiles[old] == NULL ||
171 new >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
172 new >= maxfilesperproc) {
173 FILEDESC_UNLOCK(fdp);
171 error = EBADF;
172 goto done2;
173 }
174 if (old == new) {
175 td->td_retval[0] = new;
174 error = EBADF;
175 goto done2;
176 }
177 if (old == new) {
178 td->td_retval[0] = new;
179 FILEDESC_UNLOCK(fdp);
176 error = 0;
177 goto done2;
178 }
179 if (new >= fdp->fd_nfiles) {
180 error = 0;
181 goto done2;
182 }
183 if (new >= fdp->fd_nfiles) {
180 if ((error = fdalloc(td, new, &i)))
184 if ((error = fdalloc(td, new, &i))) {
185 FILEDESC_UNLOCK(fdp);
181 goto done2;
186 goto done2;
187 }
182 if (new != i)
183 panic("dup2: fdalloc");
184 /*
185 * fdalloc() may block, retest everything.
186 */
187 goto retry;
188 }
189 error = do_dup(fdp, (int)old, (int)new, td->td_retval, td);

--- 21 unchanged lines hidden (view full) ---

211{
212 register struct filedesc *fdp;
213 u_int old;
214 int new, error;
215
216 mtx_lock(&Giant);
217 old = uap->fd;
218 fdp = td->td_proc->p_fd;
188 if (new != i)
189 panic("dup2: fdalloc");
190 /*
191 * fdalloc() may block, retest everything.
192 */
193 goto retry;
194 }
195 error = do_dup(fdp, (int)old, (int)new, td->td_retval, td);

--- 21 unchanged lines hidden (view full) ---

217{
218 register struct filedesc *fdp;
219 u_int old;
220 int new, error;
221
222 mtx_lock(&Giant);
223 old = uap->fd;
224 fdp = td->td_proc->p_fd;
225 FILEDESC_LOCK(fdp);
219 if (old >= fdp->fd_nfiles || fdp->fd_ofiles[old] == NULL) {
226 if (old >= fdp->fd_nfiles || fdp->fd_ofiles[old] == NULL) {
227 FILEDESC_UNLOCK(fdp);
220 error = EBADF;
221 goto done2;
222 }
228 error = EBADF;
229 goto done2;
230 }
223 if ((error = fdalloc(td, 0, &new)))
231 if ((error = fdalloc(td, 0, &new))) {
232 FILEDESC_UNLOCK(fdp);
224 goto done2;
233 goto done2;
234 }
225 error = do_dup(fdp, (int)old, new, td->td_retval, td);
226done2:
227 mtx_unlock(&Giant);
228 return (error);
229}
230
231/*
232 * The file control system call.

--- 17 unchanged lines hidden (view full) ---

250 register struct proc *p = td->td_proc;
251 register struct filedesc *fdp;
252 register struct file *fp;
253 register char *pop;
254 struct vnode *vp;
255 int i, tmp, error = 0, flg = F_POSIX;
256 struct flock fl;
257 u_int newmin;
235 error = do_dup(fdp, (int)old, new, td->td_retval, td);
236done2:
237 mtx_unlock(&Giant);
238 return (error);
239}
240
241/*
242 * The file control system call.

--- 17 unchanged lines hidden (view full) ---

260 register struct proc *p = td->td_proc;
261 register struct filedesc *fdp;
262 register struct file *fp;
263 register char *pop;
264 struct vnode *vp;
265 int i, tmp, error = 0, flg = F_POSIX;
266 struct flock fl;
267 u_int newmin;
268 struct proc *leaderp;
258
259 mtx_lock(&Giant);
260
261 fdp = p->p_fd;
269
270 mtx_lock(&Giant);
271
272 fdp = p->p_fd;
273 FILEDESC_LOCK(fdp);
262 if ((unsigned)uap->fd >= fdp->fd_nfiles ||
263 (fp = fdp->fd_ofiles[uap->fd]) == NULL) {
274 if ((unsigned)uap->fd >= fdp->fd_nfiles ||
275 (fp = fdp->fd_ofiles[uap->fd]) == NULL) {
276 FILEDESC_UNLOCK(fdp);
264 error = EBADF;
265 goto done2;
266 }
267 pop = &fdp->fd_ofileflags[uap->fd];
268
269 switch (uap->cmd) {
270 case F_DUPFD:
271 newmin = uap->arg;
272 if (newmin >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
273 newmin >= maxfilesperproc) {
277 error = EBADF;
278 goto done2;
279 }
280 pop = &fdp->fd_ofileflags[uap->fd];
281
282 switch (uap->cmd) {
283 case F_DUPFD:
284 newmin = uap->arg;
285 if (newmin >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
286 newmin >= maxfilesperproc) {
287 FILEDESC_UNLOCK(fdp);
274 error = EINVAL;
275 break;
276 }
288 error = EINVAL;
289 break;
290 }
277 if ((error = fdalloc(td, newmin, &i)))
291 if ((error = fdalloc(td, newmin, &i))) {
292 FILEDESC_UNLOCK(fdp);
278 break;
293 break;
294 }
279 error = do_dup(fdp, uap->fd, i, td->td_retval, td);
280 break;
281
282 case F_GETFD:
283 td->td_retval[0] = *pop & 1;
295 error = do_dup(fdp, uap->fd, i, td->td_retval, td);
296 break;
297
298 case F_GETFD:
299 td->td_retval[0] = *pop & 1;
300 FILEDESC_UNLOCK(fdp);
284 break;
285
286 case F_SETFD:
287 *pop = (*pop &~ 1) | (uap->arg & 1);
301 break;
302
303 case F_SETFD:
304 *pop = (*pop &~ 1) | (uap->arg & 1);
305 FILEDESC_UNLOCK(fdp);
288 break;
289
290 case F_GETFL:
306 break;
307
308 case F_GETFL:
309 FILE_LOCK(fp);
310 FILEDESC_UNLOCK(fdp);
291 td->td_retval[0] = OFLAGS(fp->f_flag);
311 td->td_retval[0] = OFLAGS(fp->f_flag);
312 FILE_UNLOCK(fp);
292 break;
293
294 case F_SETFL:
295 fhold(fp);
313 break;
314
315 case F_SETFL:
316 fhold(fp);
317 FILEDESC_UNLOCK(fdp);
296 fp->f_flag &= ~FCNTLFLAGS;
297 fp->f_flag |= FFLAGS(uap->arg & ~O_ACCMODE) & FCNTLFLAGS;
298 tmp = fp->f_flag & FNONBLOCK;
299 error = fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, td);
300 if (error) {
301 fdrop(fp, td);
302 break;
303 }

--- 6 unchanged lines hidden (view full) ---

310 fp->f_flag &= ~FNONBLOCK;
311 tmp = 0;
312 (void)fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, td);
313 fdrop(fp, td);
314 break;
315
316 case F_GETOWN:
317 fhold(fp);
318 fp->f_flag &= ~FCNTLFLAGS;
319 fp->f_flag |= FFLAGS(uap->arg & ~O_ACCMODE) & FCNTLFLAGS;
320 tmp = fp->f_flag & FNONBLOCK;
321 error = fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, td);
322 if (error) {
323 fdrop(fp, td);
324 break;
325 }

--- 6 unchanged lines hidden (view full) ---

332 fp->f_flag &= ~FNONBLOCK;
333 tmp = 0;
334 (void)fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, td);
335 fdrop(fp, td);
336 break;
337
338 case F_GETOWN:
339 fhold(fp);
340 FILEDESC_UNLOCK(fdp);
318 error = fo_ioctl(fp, FIOGETOWN, (caddr_t)td->td_retval, td);
319 fdrop(fp, td);
320 break;
321
322 case F_SETOWN:
323 fhold(fp);
341 error = fo_ioctl(fp, FIOGETOWN, (caddr_t)td->td_retval, td);
342 fdrop(fp, td);
343 break;
344
345 case F_SETOWN:
346 fhold(fp);
347 FILEDESC_UNLOCK(fdp);
324 error = fo_ioctl(fp, FIOSETOWN, (caddr_t)&uap->arg, td);
325 fdrop(fp, td);
326 break;
327
328 case F_SETLKW:
329 flg |= F_WAIT;
330 /* Fall into F_SETLK */
331
332 case F_SETLK:
333 if (fp->f_type != DTYPE_VNODE) {
348 error = fo_ioctl(fp, FIOSETOWN, (caddr_t)&uap->arg, td);
349 fdrop(fp, td);
350 break;
351
352 case F_SETLKW:
353 flg |= F_WAIT;
354 /* Fall into F_SETLK */
355
356 case F_SETLK:
357 if (fp->f_type != DTYPE_VNODE) {
358 FILEDESC_UNLOCK(fdp);
334 error = EBADF;
335 break;
336 }
337 vp = (struct vnode *)fp->f_data;
359 error = EBADF;
360 break;
361 }
362 vp = (struct vnode *)fp->f_data;
338
339 /*
340 * copyin/lockop may block
341 */
342 fhold(fp);
363 /*
364 * copyin/lockop may block
365 */
366 fhold(fp);
367 FILEDESC_UNLOCK(fdp);
368 vp = (struct vnode *)fp->f_data;
369
343 /* Copy in the lock structure */
344 error = copyin((caddr_t)(intptr_t)uap->arg, (caddr_t)&fl,
345 sizeof(fl));
346 if (error) {
347 fdrop(fp, td);
348 break;
349 }
350 if (fl.l_whence == SEEK_CUR) {

--- 8 unchanged lines hidden (view full) ---

359 }
360
361 switch (fl.l_type) {
362 case F_RDLCK:
363 if ((fp->f_flag & FREAD) == 0) {
364 error = EBADF;
365 break;
366 }
370 /* Copy in the lock structure */
371 error = copyin((caddr_t)(intptr_t)uap->arg, (caddr_t)&fl,
372 sizeof(fl));
373 if (error) {
374 fdrop(fp, td);
375 break;
376 }
377 if (fl.l_whence == SEEK_CUR) {

--- 8 unchanged lines hidden (view full) ---

386 }
387
388 switch (fl.l_type) {
389 case F_RDLCK:
390 if ((fp->f_flag & FREAD) == 0) {
391 error = EBADF;
392 break;
393 }
394 PROC_LOCK(p);
367 p->p_flag |= P_ADVLOCK;
395 p->p_flag |= P_ADVLOCK;
368 error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_SETLK,
396 leaderp = p->p_leader;
397 PROC_UNLOCK(p);
398 error = VOP_ADVLOCK(vp, (caddr_t)leaderp, F_SETLK,
369 &fl, flg);
370 break;
371 case F_WRLCK:
372 if ((fp->f_flag & FWRITE) == 0) {
373 error = EBADF;
374 break;
375 }
399 &fl, flg);
400 break;
401 case F_WRLCK:
402 if ((fp->f_flag & FWRITE) == 0) {
403 error = EBADF;
404 break;
405 }
406 PROC_LOCK(p);
376 p->p_flag |= P_ADVLOCK;
407 p->p_flag |= P_ADVLOCK;
377 error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_SETLK,
408 leaderp = p->p_leader;
409 PROC_UNLOCK(p);
410 error = VOP_ADVLOCK(vp, (caddr_t)leaderp, F_SETLK,
378 &fl, flg);
379 break;
380 case F_UNLCK:
411 &fl, flg);
412 break;
413 case F_UNLCK:
381 error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_UNLCK,
414 PROC_LOCK(p);
415 leaderp = p->p_leader;
416 PROC_UNLOCK(p);
417 error = VOP_ADVLOCK(vp, (caddr_t)leaderp, F_UNLCK,
382 &fl, F_POSIX);
383 break;
384 default:
385 error = EINVAL;
386 break;
387 }
388 fdrop(fp, td);
389 break;
390
391 case F_GETLK:
392 if (fp->f_type != DTYPE_VNODE) {
418 &fl, F_POSIX);
419 break;
420 default:
421 error = EINVAL;
422 break;
423 }
424 fdrop(fp, td);
425 break;
426
427 case F_GETLK:
428 if (fp->f_type != DTYPE_VNODE) {
429 FILEDESC_UNLOCK(fdp);
393 error = EBADF;
394 break;
395 }
396 vp = (struct vnode *)fp->f_data;
397 /*
398 * copyin/lockop may block
399 */
400 fhold(fp);
430 error = EBADF;
431 break;
432 }
433 vp = (struct vnode *)fp->f_data;
434 /*
435 * copyin/lockop may block
436 */
437 fhold(fp);
438 FILEDESC_UNLOCK(fdp);
439 vp = (struct vnode *)fp->f_data;
440
401 /* Copy in the lock structure */
402 error = copyin((caddr_t)(intptr_t)uap->arg, (caddr_t)&fl,
403 sizeof(fl));
404 if (error) {
405 fdrop(fp, td);
406 break;
407 }
408 if (fl.l_type != F_RDLCK && fl.l_type != F_WRLCK &&

--- 17 unchanged lines hidden (view full) ---

426 &fl, F_POSIX);
427 fdrop(fp, td);
428 if (error == 0) {
429 error = copyout((caddr_t)&fl,
430 (caddr_t)(intptr_t)uap->arg, sizeof(fl));
431 }
432 break;
433 default:
441 /* Copy in the lock structure */
442 error = copyin((caddr_t)(intptr_t)uap->arg, (caddr_t)&fl,
443 sizeof(fl));
444 if (error) {
445 fdrop(fp, td);
446 break;
447 }
448 if (fl.l_type != F_RDLCK && fl.l_type != F_WRLCK &&

--- 17 unchanged lines hidden (view full) ---

466 &fl, F_POSIX);
467 fdrop(fp, td);
468 if (error == 0) {
469 error = copyout((caddr_t)&fl,
470 (caddr_t)(intptr_t)uap->arg, sizeof(fl));
471 }
472 break;
473 default:
474 FILEDESC_UNLOCK(fdp);
434 error = EINVAL;
435 break;
436 }
437done2:
438 mtx_unlock(&Giant);
439 return (error);
440}
441
442/*
443 * Common code for dup, dup2, and fcntl(F_DUPFD).
475 error = EINVAL;
476 break;
477 }
478done2:
479 mtx_unlock(&Giant);
480 return (error);
481}
482
483/*
484 * Common code for dup, dup2, and fcntl(F_DUPFD).
485 * filedesc must be locked, but will be unlocked as a side effect.
444 */
445static int
446do_dup(fdp, old, new, retval, td)
447 register struct filedesc *fdp;
448 register int old, new;
449 register_t *retval;
450 struct thread *td;
451{
452 struct file *fp;
453 struct file *delfp;
454
486 */
487static int
488do_dup(fdp, old, new, retval, td)
489 register struct filedesc *fdp;
490 register int old, new;
491 register_t *retval;
492 struct thread *td;
493{
494 struct file *fp;
495 struct file *delfp;
496
497 FILEDESC_LOCK_ASSERT(fdp, MA_OWNED);
498
455 /*
456 * Save info on the descriptor being overwritten. We have
457 * to do the unmap now, but we cannot close it without
458 * introducing an ownership race for the slot.
459 */
460 delfp = fdp->fd_ofiles[new];
461#if 0
462 if (delfp && (fdp->fd_ofileflags[new] & UF_MAPPED))

--- 6 unchanged lines hidden (view full) ---

469 fp = fdp->fd_ofiles[old];
470 fdp->fd_ofiles[new] = fp;
471 fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] &~ UF_EXCLOSE;
472 fhold(fp);
473 if (new > fdp->fd_lastfile)
474 fdp->fd_lastfile = new;
475 *retval = new;
476
499 /*
500 * Save info on the descriptor being overwritten. We have
501 * to do the unmap now, but we cannot close it without
502 * introducing an ownership race for the slot.
503 */
504 delfp = fdp->fd_ofiles[new];
505#if 0
506 if (delfp && (fdp->fd_ofileflags[new] & UF_MAPPED))

--- 6 unchanged lines hidden (view full) ---

513 fp = fdp->fd_ofiles[old];
514 fdp->fd_ofiles[new] = fp;
515 fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] &~ UF_EXCLOSE;
516 fhold(fp);
517 if (new > fdp->fd_lastfile)
518 fdp->fd_lastfile = new;
519 *retval = new;
520
521 FILEDESC_UNLOCK(fdp);
522
477 /*
478 * If we dup'd over a valid file, we now own the reference to it
479 * and must dispose of it using closef() semantics (as if a
480 * close() were performed on it).
481 */
482 if (delfp)
483 (void) closef(delfp, td);
484 return (0);

--- 142 unchanged lines hidden (view full) ---

627{
628 register struct filedesc *fdp;
629 register struct file *fp;
630 register int fd = uap->fd;
631 int error = 0;
632
633 mtx_lock(&Giant);
634 fdp = td->td_proc->p_fd;
523 /*
524 * If we dup'd over a valid file, we now own the reference to it
525 * and must dispose of it using closef() semantics (as if a
526 * close() were performed on it).
527 */
528 if (delfp)
529 (void) closef(delfp, td);
530 return (0);

--- 142 unchanged lines hidden (view full) ---

673{
674 register struct filedesc *fdp;
675 register struct file *fp;
676 register int fd = uap->fd;
677 int error = 0;
678
679 mtx_lock(&Giant);
680 fdp = td->td_proc->p_fd;
681 FILEDESC_LOCK(fdp);
635 if ((unsigned)fd >= fdp->fd_nfiles ||
636 (fp = fdp->fd_ofiles[fd]) == NULL) {
682 if ((unsigned)fd >= fdp->fd_nfiles ||
683 (fp = fdp->fd_ofiles[fd]) == NULL) {
684 FILEDESC_UNLOCK(fdp);
637 error = EBADF;
638 goto done2;
639 }
640#if 0
641 if (fdp->fd_ofileflags[fd] & UF_MAPPED)
642 (void) munmapfd(td, fd);
643#endif
644 fdp->fd_ofiles[fd] = NULL;
645 fdp->fd_ofileflags[fd] = 0;
646
647 /*
648 * we now hold the fp reference that used to be owned by the descriptor
649 * array.
650 */
651 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
652 fdp->fd_lastfile--;
653 if (fd < fdp->fd_freefile)
654 fdp->fd_freefile = fd;
685 error = EBADF;
686 goto done2;
687 }
688#if 0
689 if (fdp->fd_ofileflags[fd] & UF_MAPPED)
690 (void) munmapfd(td, fd);
691#endif
692 fdp->fd_ofiles[fd] = NULL;
693 fdp->fd_ofileflags[fd] = 0;
694
695 /*
696 * we now hold the fp reference that used to be owned by the descriptor
697 * array.
698 */
699 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
700 fdp->fd_lastfile--;
701 if (fd < fdp->fd_freefile)
702 fdp->fd_freefile = fd;
655 if (fd < fdp->fd_knlistsize)
703 if (fd < fdp->fd_knlistsize) {
704 FILEDESC_UNLOCK(fdp);
656 knote_fdclose(td, fd);
705 knote_fdclose(td, fd);
706 } else
707 FILEDESC_UNLOCK(fdp);
708
657 error = closef(fp, td);
658done2:
659 mtx_unlock(&Giant);
660 return(error);
661}
662
663#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
664/*

--- 86 unchanged lines hidden (view full) ---

751 struct thread *td;
752 register struct nfstat_args *uap;
753{
754 struct file *fp;
755 struct stat ub;
756 struct nstat nub;
757 int error;
758
709 error = closef(fp, td);
710done2:
711 mtx_unlock(&Giant);
712 return(error);
713}
714
715#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
716/*

--- 86 unchanged lines hidden (view full) ---

803 struct thread *td;
804 register struct nfstat_args *uap;
805{
806 struct file *fp;
807 struct stat ub;
808 struct nstat nub;
809 int error;
810
759 mtx_lock(&Giant);
760 if ((error = fget(td, uap->fd, &fp)) != 0)
761 goto done2;
762 error = fo_stat(fp, &ub, td);
763 if (error == 0) {
764 cvtnstat(&ub, &nub);
765 error = copyout((caddr_t)&nub, (caddr_t)uap->sb, sizeof (nub));
766 }
767 fdrop(fp, td);

--- 19 unchanged lines hidden (view full) ---

787fpathconf(td, uap)
788 struct thread *td;
789 register struct fpathconf_args *uap;
790{
791 struct file *fp;
792 struct vnode *vp;
793 int error;
794
811 if ((error = fget(td, uap->fd, &fp)) != 0)
812 goto done2;
813 error = fo_stat(fp, &ub, td);
814 if (error == 0) {
815 cvtnstat(&ub, &nub);
816 error = copyout((caddr_t)&nub, (caddr_t)uap->sb, sizeof (nub));
817 }
818 fdrop(fp, td);

--- 19 unchanged lines hidden (view full) ---

838fpathconf(td, uap)
839 struct thread *td;
840 register struct fpathconf_args *uap;
841{
842 struct file *fp;
843 struct vnode *vp;
844 int error;
845
846 fp = ffind_hold(td, uap->fd);
847 if (fp == NULL)
848 return (EBADF);
795 mtx_lock(&Giant);
796 if ((error = fget(td, uap->fd, &fp)) != 0)
797 goto done2;
798
799 switch (fp->f_type) {
800 case DTYPE_PIPE:
801 case DTYPE_SOCKET:
802 if (uap->name != _PC_PIPE_BUF) {
849 mtx_lock(&Giant);
850 if ((error = fget(td, uap->fd, &fp)) != 0)
851 goto done2;
852
853 switch (fp->f_type) {
854 case DTYPE_PIPE:
855 case DTYPE_SOCKET:
856 if (uap->name != _PC_PIPE_BUF) {
857 fdrop(fp, td);
803 error = EINVAL;
804 goto done2;
805 }
806 td->td_retval[0] = PIPE_BUF;
807 error = 0;
808 break;
809 case DTYPE_FIFO:
810 case DTYPE_VNODE:

--- 21 unchanged lines hidden (view full) ---

832 struct thread *td;
833 int want;
834 int *result;
835{
836 struct proc *p = td->td_proc;
837 register struct filedesc *fdp = td->td_proc->p_fd;
838 register int i;
839 int lim, last, nfiles;
858 error = EINVAL;
859 goto done2;
860 }
861 td->td_retval[0] = PIPE_BUF;
862 error = 0;
863 break;
864 case DTYPE_FIFO:
865 case DTYPE_VNODE:

--- 21 unchanged lines hidden (view full) ---

887 struct thread *td;
888 int want;
889 int *result;
890{
891 struct proc *p = td->td_proc;
892 register struct filedesc *fdp = td->td_proc->p_fd;
893 register int i;
894 int lim, last, nfiles;
840 struct file **newofile;
895 struct file **newofile, **oldofile;
841 char *newofileflags;
842
896 char *newofileflags;
897
898 FILEDESC_LOCK_ASSERT(fdp, MA_OWNED);
899
843 /*
844 * Search for a free descriptor starting at the higher
845 * of want or fd_freefile. If that fails, consider
846 * expanding the ofile array.
847 */
848 lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
849 for (;;) {
850 last = min(fdp->fd_nfiles, lim);

--- 15 unchanged lines hidden (view full) ---

866 * No space in current array. Expand?
867 */
868 if (fdp->fd_nfiles >= lim)
869 return (EMFILE);
870 if (fdp->fd_nfiles < NDEXTENT)
871 nfiles = NDEXTENT;
872 else
873 nfiles = 2 * fdp->fd_nfiles;
900 /*
901 * Search for a free descriptor starting at the higher
902 * of want or fd_freefile. If that fails, consider
903 * expanding the ofile array.
904 */
905 lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
906 for (;;) {
907 last = min(fdp->fd_nfiles, lim);

--- 15 unchanged lines hidden (view full) ---

923 * No space in current array. Expand?
924 */
925 if (fdp->fd_nfiles >= lim)
926 return (EMFILE);
927 if (fdp->fd_nfiles < NDEXTENT)
928 nfiles = NDEXTENT;
929 else
930 nfiles = 2 * fdp->fd_nfiles;
931 FILEDESC_UNLOCK(fdp);
874 MALLOC(newofile, struct file **, nfiles * OFILESIZE,
875 M_FILEDESC, M_WAITOK);
932 MALLOC(newofile, struct file **, nfiles * OFILESIZE,
933 M_FILEDESC, M_WAITOK);
934 FILEDESC_LOCK(fdp);
876
877 /*
878 * deal with file-table extend race that might have occured
879 * when malloc was blocked.
880 */
881 if (fdp->fd_nfiles >= nfiles) {
935
936 /*
937 * deal with file-table extend race that might have occured
938 * when malloc was blocked.
939 */
940 if (fdp->fd_nfiles >= nfiles) {
941 FILEDESC_UNLOCK(fdp);
882 FREE(newofile, M_FILEDESC);
942 FREE(newofile, M_FILEDESC);
943 FILEDESC_LOCK(fdp);
883 continue;
884 }
885 newofileflags = (char *) &newofile[nfiles];
886 /*
887 * Copy the existing ofile and ofileflags arrays
888 * and zero the new portion of each array.
889 */
890 bcopy(fdp->fd_ofiles, newofile,
891 (i = sizeof(struct file *) * fdp->fd_nfiles));
892 bzero((char *)newofile + i, nfiles * sizeof(struct file *) - i);
893 bcopy(fdp->fd_ofileflags, newofileflags,
894 (i = sizeof(char) * fdp->fd_nfiles));
895 bzero(newofileflags + i, nfiles * sizeof(char) - i);
896 if (fdp->fd_nfiles > NDFILE)
944 continue;
945 }
946 newofileflags = (char *) &newofile[nfiles];
947 /*
948 * Copy the existing ofile and ofileflags arrays
949 * and zero the new portion of each array.
950 */
951 bcopy(fdp->fd_ofiles, newofile,
952 (i = sizeof(struct file *) * fdp->fd_nfiles));
953 bzero((char *)newofile + i, nfiles * sizeof(struct file *) - i);
954 bcopy(fdp->fd_ofileflags, newofileflags,
955 (i = sizeof(char) * fdp->fd_nfiles));
956 bzero(newofileflags + i, nfiles * sizeof(char) - i);
957 if (fdp->fd_nfiles > NDFILE)
897 FREE(fdp->fd_ofiles, M_FILEDESC);
958 oldofile = fdp->fd_ofiles;
959 else
960 oldofile = NULL;
898 fdp->fd_ofiles = newofile;
899 fdp->fd_ofileflags = newofileflags;
900 fdp->fd_nfiles = nfiles;
901 fdexpand++;
961 fdp->fd_ofiles = newofile;
962 fdp->fd_ofileflags = newofileflags;
963 fdp->fd_nfiles = nfiles;
964 fdexpand++;
965 if (oldofile != NULL)
966 FREE(oldofile, M_FILEDESC);
902 }
903 return (0);
904}
905
906/*
907 * Check to see whether n user file descriptors
908 * are available to the process p.
909 */
910int
911fdavail(td, n)
912 struct thread *td;
913 register int n;
914{
915 struct proc *p = td->td_proc;
916 register struct filedesc *fdp = td->td_proc->p_fd;
917 register struct file **fpp;
918 register int i, lim, last;
919
967 }
968 return (0);
969}
970
971/*
972 * Check to see whether n user file descriptors
973 * are available to the process p.
974 */
975int
976fdavail(td, n)
977 struct thread *td;
978 register int n;
979{
980 struct proc *p = td->td_proc;
981 register struct filedesc *fdp = td->td_proc->p_fd;
982 register struct file **fpp;
983 register int i, lim, last;
984
985 FILEDESC_LOCK_ASSERT(fdp, MA_OWNED);
986
920 lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
921 if ((i = lim - fdp->fd_nfiles) > 0 && (n -= i) <= 0)
922 return (1);
923
924 last = min(fdp->fd_nfiles, lim);
925 fpp = &fdp->fd_ofiles[fdp->fd_freefile];
926 for (i = last - fdp->fd_freefile; --i >= 0; fpp++) {
927 if (*fpp == NULL && --n <= 0)

--- 11 unchanged lines hidden (view full) ---

939 register struct thread *td;
940 struct file **resultfp;
941 int *resultfd;
942{
943 struct proc *p = td->td_proc;
944 register struct file *fp, *fq;
945 int error, i;
946
987 lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
988 if ((i = lim - fdp->fd_nfiles) > 0 && (n -= i) <= 0)
989 return (1);
990
991 last = min(fdp->fd_nfiles, lim);
992 fpp = &fdp->fd_ofiles[fdp->fd_freefile];
993 for (i = last - fdp->fd_freefile; --i >= 0; fpp++) {
994 if (*fpp == NULL && --n <= 0)

--- 11 unchanged lines hidden (view full) ---

1006 register struct thread *td;
1007 struct file **resultfp;
1008 int *resultfd;
1009{
1010 struct proc *p = td->td_proc;
1011 register struct file *fp, *fq;
1012 int error, i;
1013
1014 sx_xlock(&filelist_lock);
947 if (nfiles >= maxfiles) {
1015 if (nfiles >= maxfiles) {
1016 sx_xunlock(&filelist_lock);
948 tablefull("file");
949 return (ENFILE);
950 }
1017 tablefull("file");
1018 return (ENFILE);
1019 }
1020 nfiles++;
1021 sx_xunlock(&filelist_lock);
951 /*
952 * Allocate a new file descriptor.
953 * If the process has file descriptor zero open, add to the list
954 * of open files at that point, otherwise put it at the front of
955 * the list of open files.
956 */
1022 /*
1023 * Allocate a new file descriptor.
1024 * If the process has file descriptor zero open, add to the list
1025 * of open files at that point, otherwise put it at the front of
1026 * the list of open files.
1027 */
957 nfiles++;
958 MALLOC(fp, struct file *, sizeof(struct file), M_FILE, M_WAITOK | M_ZERO);
959
960 /*
961 * wait until after malloc (which may have blocked) returns before
962 * allocating the slot, else a race might have shrunk it if we had
963 * allocated it before the malloc.
964 */
1028 MALLOC(fp, struct file *, sizeof(struct file), M_FILE, M_WAITOK | M_ZERO);
1029
1030 /*
1031 * wait until after malloc (which may have blocked) returns before
1032 * allocating the slot, else a race might have shrunk it if we had
1033 * allocated it before the malloc.
1034 */
1035 FILEDESC_LOCK(p->p_fd);
965 if ((error = fdalloc(td, 0, &i))) {
1036 if ((error = fdalloc(td, 0, &i))) {
1037 FILEDESC_UNLOCK(p->p_fd);
1038 sx_xlock(&filelist_lock);
966 nfiles--;
1039 nfiles--;
1040 sx_xunlock(&filelist_lock);
967 FREE(fp, M_FILE);
968 return (error);
969 }
1041 FREE(fp, M_FILE);
1042 return (error);
1043 }
1044 mtx_init(&fp->f_mtx, "file structure", MTX_DEF);
1045 fp->f_gcflag = 0;
970 fp->f_count = 1;
971 fp->f_cred = crhold(p->p_ucred);
972 fp->f_ops = &badfileops;
973 fp->f_seqcount = 1;
1046 fp->f_count = 1;
1047 fp->f_cred = crhold(p->p_ucred);
1048 fp->f_ops = &badfileops;
1049 fp->f_seqcount = 1;
1050 FILEDESC_UNLOCK(p->p_fd);
1051 sx_xlock(&filelist_lock);
1052 FILEDESC_LOCK(p->p_fd);
974 if ((fq = p->p_fd->fd_ofiles[0])) {
975 LIST_INSERT_AFTER(fq, fp, f_list);
976 } else {
977 LIST_INSERT_HEAD(&filehead, fp, f_list);
978 }
979 p->p_fd->fd_ofiles[i] = fp;
1053 if ((fq = p->p_fd->fd_ofiles[0])) {
1054 LIST_INSERT_AFTER(fq, fp, f_list);
1055 } else {
1056 LIST_INSERT_HEAD(&filehead, fp, f_list);
1057 }
1058 p->p_fd->fd_ofiles[i] = fp;
1059 FILEDESC_UNLOCK(p->p_fd);
1060 sx_xunlock(&filelist_lock);
980 if (resultfp)
981 *resultfp = fp;
982 if (resultfd)
983 *resultfd = i;
984 return (0);
985}
986
987/*
988 * Free a file descriptor.
989 */
990void
991ffree(fp)
992 register struct file *fp;
993{
1061 if (resultfp)
1062 *resultfp = fp;
1063 if (resultfd)
1064 *resultfd = i;
1065 return (0);
1066}
1067
1068/*
1069 * Free a file descriptor.
1070 */
1071void
1072ffree(fp)
1073 register struct file *fp;
1074{
1075
994 KASSERT((fp->f_count == 0), ("ffree: fp_fcount not 0!"));
1076 KASSERT((fp->f_count == 0), ("ffree: fp_fcount not 0!"));
1077 sx_xlock(&filelist_lock);
995 LIST_REMOVE(fp, f_list);
1078 LIST_REMOVE(fp, f_list);
996 crfree(fp->f_cred);
997 nfiles--;
1079 nfiles--;
1080 sx_xunlock(&filelist_lock);
1081 crfree(fp->f_cred);
1082 mtx_destroy(&fp->f_mtx);
998 FREE(fp, M_FILE);
999}
1000
1001/*
1002 * Build a new filedesc structure.
1003 */
1004struct filedesc *
1005fdinit(td)
1006 struct thread *td;
1007{
1008 register struct filedesc0 *newfdp;
1009 register struct filedesc *fdp = td->td_proc->p_fd;
1010
1011 MALLOC(newfdp, struct filedesc0 *, sizeof(struct filedesc0),
1012 M_FILEDESC, M_WAITOK | M_ZERO);
1083 FREE(fp, M_FILE);
1084}
1085
1086/*
1087 * Build a new filedesc structure.
1088 */
1089struct filedesc *
1090fdinit(td)
1091 struct thread *td;
1092{
1093 register struct filedesc0 *newfdp;
1094 register struct filedesc *fdp = td->td_proc->p_fd;
1095
1096 MALLOC(newfdp, struct filedesc0 *, sizeof(struct filedesc0),
1097 M_FILEDESC, M_WAITOK | M_ZERO);
1098 mtx_init(&newfdp->fd_fd.fd_mtx, "filedesc structure", MTX_DEF);
1099 FILEDESC_LOCK(&newfdp->fd_fd);
1013 newfdp->fd_fd.fd_cdir = fdp->fd_cdir;
1014 if (newfdp->fd_fd.fd_cdir)
1015 VREF(newfdp->fd_fd.fd_cdir);
1016 newfdp->fd_fd.fd_rdir = fdp->fd_rdir;
1017 if (newfdp->fd_fd.fd_rdir)
1018 VREF(newfdp->fd_fd.fd_rdir);
1019 newfdp->fd_fd.fd_jdir = fdp->fd_jdir;
1020 if (newfdp->fd_fd.fd_jdir)
1021 VREF(newfdp->fd_fd.fd_jdir);
1022
1023 /* Create the file descriptor table. */
1024 newfdp->fd_fd.fd_refcnt = 1;
1025 newfdp->fd_fd.fd_cmask = cmask;
1026 newfdp->fd_fd.fd_ofiles = newfdp->fd_dfiles;
1027 newfdp->fd_fd.fd_ofileflags = newfdp->fd_dfileflags;
1028 newfdp->fd_fd.fd_nfiles = NDFILE;
1029 newfdp->fd_fd.fd_knlistsize = -1;
1100 newfdp->fd_fd.fd_cdir = fdp->fd_cdir;
1101 if (newfdp->fd_fd.fd_cdir)
1102 VREF(newfdp->fd_fd.fd_cdir);
1103 newfdp->fd_fd.fd_rdir = fdp->fd_rdir;
1104 if (newfdp->fd_fd.fd_rdir)
1105 VREF(newfdp->fd_fd.fd_rdir);
1106 newfdp->fd_fd.fd_jdir = fdp->fd_jdir;
1107 if (newfdp->fd_fd.fd_jdir)
1108 VREF(newfdp->fd_fd.fd_jdir);
1109
1110 /* Create the file descriptor table. */
1111 newfdp->fd_fd.fd_refcnt = 1;
1112 newfdp->fd_fd.fd_cmask = cmask;
1113 newfdp->fd_fd.fd_ofiles = newfdp->fd_dfiles;
1114 newfdp->fd_fd.fd_ofileflags = newfdp->fd_dfileflags;
1115 newfdp->fd_fd.fd_nfiles = NDFILE;
1116 newfdp->fd_fd.fd_knlistsize = -1;
1117 FILEDESC_UNLOCK(&newfdp->fd_fd);
1030
1031 return (&newfdp->fd_fd);
1032}
1033
1034/*
1035 * Share a filedesc structure.
1036 */
1037struct filedesc *
1038fdshare(p)
1039 struct proc *p;
1040{
1118
1119 return (&newfdp->fd_fd);
1120}
1121
1122/*
1123 * Share a filedesc structure.
1124 */
1125struct filedesc *
1126fdshare(p)
1127 struct proc *p;
1128{
1129 FILEDESC_LOCK(p->p_fd);
1041 p->p_fd->fd_refcnt++;
1130 p->p_fd->fd_refcnt++;
1131 FILEDESC_UNLOCK(p->p_fd);
1042 return (p->p_fd);
1043}
1044
1045/*
1046 * Copy a filedesc structure.
1047 */
1048struct filedesc *
1049fdcopy(td)
1050 struct thread *td;
1051{
1052 register struct filedesc *newfdp, *fdp = td->td_proc->p_fd;
1053 register struct file **fpp;
1132 return (p->p_fd);
1133}
1134
1135/*
1136 * Copy a filedesc structure.
1137 */
1138struct filedesc *
1139fdcopy(td)
1140 struct thread *td;
1141{
1142 register struct filedesc *newfdp, *fdp = td->td_proc->p_fd;
1143 register struct file **fpp;
1054 register int i;
1144 register int i, j;
1055
1056 /* Certain daemons might not have file descriptors. */
1057 if (fdp == NULL)
1058 return (NULL);
1059
1145
1146 /* Certain daemons might not have file descriptors. */
1147 if (fdp == NULL)
1148 return (NULL);
1149
1150 FILEDESC_LOCK_ASSERT(fdp, MA_OWNED);
1151
1152 FILEDESC_UNLOCK(fdp);
1060 MALLOC(newfdp, struct filedesc *, sizeof(struct filedesc0),
1061 M_FILEDESC, M_WAITOK);
1153 MALLOC(newfdp, struct filedesc *, sizeof(struct filedesc0),
1154 M_FILEDESC, M_WAITOK);
1155 FILEDESC_LOCK(fdp);
1062 bcopy(fdp, newfdp, sizeof(struct filedesc));
1156 bcopy(fdp, newfdp, sizeof(struct filedesc));
1157 FILEDESC_UNLOCK(fdp);
1158 bzero(&newfdp->fd_mtx, sizeof(newfdp->fd_mtx));
1159 mtx_init(&newfdp->fd_mtx, "filedesc structure", MTX_DEF);
1063 if (newfdp->fd_cdir)
1064 VREF(newfdp->fd_cdir);
1065 if (newfdp->fd_rdir)
1066 VREF(newfdp->fd_rdir);
1067 if (newfdp->fd_jdir)
1068 VREF(newfdp->fd_jdir);
1069 newfdp->fd_refcnt = 1;
1070
1071 /*
1072 * If the number of open files fits in the internal arrays
1073 * of the open file structure, use them, otherwise allocate
1074 * additional memory for the number of descriptors currently
1075 * in use.
1076 */
1160 if (newfdp->fd_cdir)
1161 VREF(newfdp->fd_cdir);
1162 if (newfdp->fd_rdir)
1163 VREF(newfdp->fd_rdir);
1164 if (newfdp->fd_jdir)
1165 VREF(newfdp->fd_jdir);
1166 newfdp->fd_refcnt = 1;
1167
1168 /*
1169 * If the number of open files fits in the internal arrays
1170 * of the open file structure, use them, otherwise allocate
1171 * additional memory for the number of descriptors currently
1172 * in use.
1173 */
1174 FILEDESC_LOCK(fdp);
1175 newfdp->fd_lastfile = fdp->fd_lastfile;
1176 newfdp->fd_nfiles = fdp->fd_nfiles;
1077 if (newfdp->fd_lastfile < NDFILE) {
1078 newfdp->fd_ofiles = ((struct filedesc0 *) newfdp)->fd_dfiles;
1079 newfdp->fd_ofileflags =
1080 ((struct filedesc0 *) newfdp)->fd_dfileflags;
1081 i = NDFILE;
1082 } else {
1083 /*
1084 * Compute the smallest multiple of NDEXTENT needed
1085 * for the file descriptors currently in use,
1086 * allowing the table to shrink.
1087 */
1177 if (newfdp->fd_lastfile < NDFILE) {
1178 newfdp->fd_ofiles = ((struct filedesc0 *) newfdp)->fd_dfiles;
1179 newfdp->fd_ofileflags =
1180 ((struct filedesc0 *) newfdp)->fd_dfileflags;
1181 i = NDFILE;
1182 } else {
1183 /*
1184 * Compute the smallest multiple of NDEXTENT needed
1185 * for the file descriptors currently in use,
1186 * allowing the table to shrink.
1187 */
1188retry:
1088 i = newfdp->fd_nfiles;
1089 while (i > 2 * NDEXTENT && i > newfdp->fd_lastfile * 2)
1090 i /= 2;
1189 i = newfdp->fd_nfiles;
1190 while (i > 2 * NDEXTENT && i > newfdp->fd_lastfile * 2)
1191 i /= 2;
1192 FILEDESC_UNLOCK(fdp);
1091 MALLOC(newfdp->fd_ofiles, struct file **, i * OFILESIZE,
1092 M_FILEDESC, M_WAITOK);
1193 MALLOC(newfdp->fd_ofiles, struct file **, i * OFILESIZE,
1194 M_FILEDESC, M_WAITOK);
1195 FILEDESC_LOCK(fdp);
1196 newfdp->fd_lastfile = fdp->fd_lastfile;
1197 newfdp->fd_nfiles = fdp->fd_nfiles;
1198 j = newfdp->fd_nfiles;
1199 while (j > 2 * NDEXTENT && j > newfdp->fd_lastfile * 2)
1200 j /= 2;
1201 if (i != j) {
1202 /*
1203 * The size of the original table has changed.
1204 * Go over once again.
1205 */
1206 FILEDESC_UNLOCK(fdp);
1207 FREE(newfdp->fd_ofiles, M_FILEDESC);
1208 FILEDESC_LOCK(fdp);
1209 newfdp->fd_lastfile = fdp->fd_lastfile;
1210 newfdp->fd_nfiles = fdp->fd_nfiles;
1211 goto retry;
1212 }
1093 newfdp->fd_ofileflags = (char *) &newfdp->fd_ofiles[i];
1094 }
1095 newfdp->fd_nfiles = i;
1096 bcopy(fdp->fd_ofiles, newfdp->fd_ofiles, i * sizeof(struct file **));
1097 bcopy(fdp->fd_ofileflags, newfdp->fd_ofileflags, i * sizeof(char));
1098
1099 /*
1100 * kq descriptors cannot be copied.

--- 12 unchanged lines hidden (view full) ---

1113 newfdp->fd_knlist = NULL;
1114 newfdp->fd_knlistsize = -1;
1115 newfdp->fd_knhash = NULL;
1116 newfdp->fd_knhashmask = 0;
1117 }
1118
1119 fpp = newfdp->fd_ofiles;
1120 for (i = newfdp->fd_lastfile; i-- >= 0; fpp++) {
1213 newfdp->fd_ofileflags = (char *) &newfdp->fd_ofiles[i];
1214 }
1215 newfdp->fd_nfiles = i;
1216 bcopy(fdp->fd_ofiles, newfdp->fd_ofiles, i * sizeof(struct file **));
1217 bcopy(fdp->fd_ofileflags, newfdp->fd_ofileflags, i * sizeof(char));
1218
1219 /*
1220 * kq descriptors cannot be copied.

--- 12 unchanged lines hidden (view full) ---

1233 newfdp->fd_knlist = NULL;
1234 newfdp->fd_knlistsize = -1;
1235 newfdp->fd_knhash = NULL;
1236 newfdp->fd_knhashmask = 0;
1237 }
1238
1239 fpp = newfdp->fd_ofiles;
1240 for (i = newfdp->fd_lastfile; i-- >= 0; fpp++) {
1121 if (*fpp != NULL)
1241 if (*fpp != NULL) {
1122 fhold(*fpp);
1242 fhold(*fpp);
1243 }
1123 }
1124 return (newfdp);
1125}
1126
1127/*
1128 * Release a filedesc structure.
1129 */
1130void
1131fdfree(td)
1132 struct thread *td;
1133{
1134 register struct filedesc *fdp = td->td_proc->p_fd;
1135 struct file **fpp;
1136 register int i;
1137
1138 /* Certain daemons might not have file descriptors. */
1139 if (fdp == NULL)
1140 return;
1141
1244 }
1245 return (newfdp);
1246}
1247
1248/*
1249 * Release a filedesc structure.
1250 */
1251void
1252fdfree(td)
1253 struct thread *td;
1254{
1255 register struct filedesc *fdp = td->td_proc->p_fd;
1256 struct file **fpp;
1257 register int i;
1258
1259 /* Certain daemons might not have file descriptors. */
1260 if (fdp == NULL)
1261 return;
1262
1142 if (--fdp->fd_refcnt > 0)
1263 FILEDESC_LOCK(fdp);
1264 if (--fdp->fd_refcnt > 0) {
1265 FILEDESC_UNLOCK(fdp);
1143 return;
1266 return;
1267 }
1144 /*
1145 * we are the last reference to the structure, we can
1146 * safely assume it will not change out from under us.
1147 */
1268 /*
1269 * we are the last reference to the structure, we can
1270 * safely assume it will not change out from under us.
1271 */
1272 FILEDESC_UNLOCK(fdp);
1148 fpp = fdp->fd_ofiles;
1149 for (i = fdp->fd_lastfile; i-- >= 0; fpp++) {
1150 if (*fpp)
1151 (void) closef(*fpp, td);
1152 }
1153 if (fdp->fd_nfiles > NDFILE)
1154 FREE(fdp->fd_ofiles, M_FILEDESC);
1155 if (fdp->fd_cdir)
1156 vrele(fdp->fd_cdir);
1157 if (fdp->fd_rdir)
1158 vrele(fdp->fd_rdir);
1159 if (fdp->fd_jdir)
1160 vrele(fdp->fd_jdir);
1161 if (fdp->fd_knlist)
1162 FREE(fdp->fd_knlist, M_KQUEUE);
1163 if (fdp->fd_knhash)
1164 FREE(fdp->fd_knhash, M_KQUEUE);
1273 fpp = fdp->fd_ofiles;
1274 for (i = fdp->fd_lastfile; i-- >= 0; fpp++) {
1275 if (*fpp)
1276 (void) closef(*fpp, td);
1277 }
1278 if (fdp->fd_nfiles > NDFILE)
1279 FREE(fdp->fd_ofiles, M_FILEDESC);
1280 if (fdp->fd_cdir)
1281 vrele(fdp->fd_cdir);
1282 if (fdp->fd_rdir)
1283 vrele(fdp->fd_rdir);
1284 if (fdp->fd_jdir)
1285 vrele(fdp->fd_jdir);
1286 if (fdp->fd_knlist)
1287 FREE(fdp->fd_knlist, M_KQUEUE);
1288 if (fdp->fd_knhash)
1289 FREE(fdp->fd_knhash, M_KQUEUE);
1290 mtx_destroy(&fdp->fd_mtx);
1165 FREE(fdp, M_FILEDESC);
1166}
1167
1168/*
1169 * For setugid programs, we don't want to people to use that setugidness
1170 * to generate error messages which write to a file which otherwise would
1171 * otherwise be off-limits to the process.
1172 *

--- 26 unchanged lines hidden (view full) ---

1199 /* Certain daemons might not have file descriptors. */
1200 if (fdp == NULL)
1201 return;
1202
1203 /*
1204 * note: fdp->fd_ofiles may be reallocated out from under us while
1205 * we are blocked in a close. Be careful!
1206 */
1291 FREE(fdp, M_FILEDESC);
1292}
1293
1294/*
1295 * For setugid programs, we don't want to people to use that setugidness
1296 * to generate error messages which write to a file which otherwise would
1297 * otherwise be off-limits to the process.
1298 *

--- 26 unchanged lines hidden (view full) ---

1325 /* Certain daemons might not have file descriptors. */
1326 if (fdp == NULL)
1327 return;
1328
1329 /*
1330 * note: fdp->fd_ofiles may be reallocated out from under us while
1331 * we are blocked in a close. Be careful!
1332 */
1333 FILEDESC_LOCK(fdp);
1207 for (i = 0; i <= fdp->fd_lastfile; i++) {
1208 if (i > 2)
1209 break;
1210 if (fdp->fd_ofiles[i] && is_unsafe(fdp->fd_ofiles[i])) {
1211 struct file *fp;
1212
1213#if 0
1214 if ((fdp->fd_ofileflags[i] & UF_MAPPED) != 0)
1215 (void) munmapfd(td, i);
1216#endif
1334 for (i = 0; i <= fdp->fd_lastfile; i++) {
1335 if (i > 2)
1336 break;
1337 if (fdp->fd_ofiles[i] && is_unsafe(fdp->fd_ofiles[i])) {
1338 struct file *fp;
1339
1340#if 0
1341 if ((fdp->fd_ofileflags[i] & UF_MAPPED) != 0)
1342 (void) munmapfd(td, i);
1343#endif
1217 if (i < fdp->fd_knlistsize)
1344 if (i < fdp->fd_knlistsize) {
1345 FILEDESC_UNLOCK(fdp);
1218 knote_fdclose(td, i);
1346 knote_fdclose(td, i);
1347 FILEDESC_LOCK(fdp);
1348 }
1219 /*
1220 * NULL-out descriptor prior to close to avoid
1221 * a race while close blocks.
1222 */
1223 fp = fdp->fd_ofiles[i];
1224 fdp->fd_ofiles[i] = NULL;
1225 fdp->fd_ofileflags[i] = 0;
1226 if (i < fdp->fd_freefile)
1227 fdp->fd_freefile = i;
1349 /*
1350 * NULL-out descriptor prior to close to avoid
1351 * a race while close blocks.
1352 */
1353 fp = fdp->fd_ofiles[i];
1354 fdp->fd_ofiles[i] = NULL;
1355 fdp->fd_ofileflags[i] = 0;
1356 if (i < fdp->fd_freefile)
1357 fdp->fd_freefile = i;
1358 FILEDESC_UNLOCK(fdp);
1228 (void) closef(fp, td);
1359 (void) closef(fp, td);
1360 FILEDESC_LOCK(fdp);
1229 }
1230 }
1231 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
1232 fdp->fd_lastfile--;
1361 }
1362 }
1363 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
1364 fdp->fd_lastfile--;
1365 FILEDESC_UNLOCK(fdp);
1233}
1234
1235/*
1236 * Close any files on exec?
1237 */
1238void
1239fdcloseexec(td)
1240 struct thread *td;
1241{
1242 struct filedesc *fdp = td->td_proc->p_fd;
1243 register int i;
1244
1245 /* Certain daemons might not have file descriptors. */
1246 if (fdp == NULL)
1247 return;
1248
1366}
1367
1368/*
1369 * Close any files on exec?
1370 */
1371void
1372fdcloseexec(td)
1373 struct thread *td;
1374{
1375 struct filedesc *fdp = td->td_proc->p_fd;
1376 register int i;
1377
1378 /* Certain daemons might not have file descriptors. */
1379 if (fdp == NULL)
1380 return;
1381
1382 FILEDESC_LOCK(fdp);
1383
1249 /*
1250 * We cannot cache fd_ofiles or fd_ofileflags since operations
1251 * may block and rip them out from under us.
1252 */
1253 for (i = 0; i <= fdp->fd_lastfile; i++) {
1254 if (fdp->fd_ofiles[i] != NULL &&
1255 (fdp->fd_ofileflags[i] & UF_EXCLOSE)) {
1256 struct file *fp;
1257
1258#if 0
1259 if (fdp->fd_ofileflags[i] & UF_MAPPED)
1260 (void) munmapfd(td, i);
1261#endif
1384 /*
1385 * We cannot cache fd_ofiles or fd_ofileflags since operations
1386 * may block and rip them out from under us.
1387 */
1388 for (i = 0; i <= fdp->fd_lastfile; i++) {
1389 if (fdp->fd_ofiles[i] != NULL &&
1390 (fdp->fd_ofileflags[i] & UF_EXCLOSE)) {
1391 struct file *fp;
1392
1393#if 0
1394 if (fdp->fd_ofileflags[i] & UF_MAPPED)
1395 (void) munmapfd(td, i);
1396#endif
1262 if (i < fdp->fd_knlistsize)
1397 if (i < fdp->fd_knlistsize) {
1398 FILEDESC_UNLOCK(fdp);
1263 knote_fdclose(td, i);
1399 knote_fdclose(td, i);
1400 FILEDESC_LOCK(fdp);
1401 }
1264 /*
1265 * NULL-out descriptor prior to close to avoid
1266 * a race while close blocks.
1267 */
1268 fp = fdp->fd_ofiles[i];
1269 fdp->fd_ofiles[i] = NULL;
1270 fdp->fd_ofileflags[i] = 0;
1271 if (i < fdp->fd_freefile)
1272 fdp->fd_freefile = i;
1402 /*
1403 * NULL-out descriptor prior to close to avoid
1404 * a race while close blocks.
1405 */
1406 fp = fdp->fd_ofiles[i];
1407 fdp->fd_ofiles[i] = NULL;
1408 fdp->fd_ofileflags[i] = 0;
1409 if (i < fdp->fd_freefile)
1410 fdp->fd_freefile = i;
1411 FILEDESC_UNLOCK(fdp);
1273 (void) closef(fp, td);
1412 (void) closef(fp, td);
1413 FILEDESC_LOCK(fdp);
1274 }
1275 }
1276 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
1277 fdp->fd_lastfile--;
1414 }
1415 }
1416 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
1417 fdp->fd_lastfile--;
1418 FILEDESC_UNLOCK(fdp);
1278}
1279
1280/*
1281 * Internal form of close.
1282 * Decrement reference count on file structure.
1283 * Note: td may be NULL when closing a file
1284 * that was being passed in a message.
1285 */

--- 24 unchanged lines hidden (view full) ---

1310 vp = (struct vnode *)fp->f_data;
1311 (void) VOP_ADVLOCK(vp, (caddr_t)td->td_proc->p_leader,
1312 F_UNLCK, &lf, F_POSIX);
1313 }
1314 return (fdrop(fp, td));
1315}
1316
1317/*
1419}
1420
1421/*
1422 * Internal form of close.
1423 * Decrement reference count on file structure.
1424 * Note: td may be NULL when closing a file
1425 * that was being passed in a message.
1426 */

--- 24 unchanged lines hidden (view full) ---

1451 vp = (struct vnode *)fp->f_data;
1452 (void) VOP_ADVLOCK(vp, (caddr_t)td->td_proc->p_leader,
1453 F_UNLCK, &lf, F_POSIX);
1454 }
1455 return (fdrop(fp, td));
1456}
1457
1458/*
1459 * Find the struct file 'fd' in process 'p' and bump it's refcount
1460 * struct file is not locked on return.
1461 */
1462struct file *
1463ffind_hold(td, fd)
1464 struct thread *td;
1465 int fd;
1466{
1467 struct filedesc *fdp;
1468 struct file *fp;
1469
1470 if (td == NULL || (fdp = td->td_proc->p_fd) == NULL)
1471 return (NULL);
1472 FILEDESC_LOCK(fdp);
1473 if (fd < 0 || fd >= fdp->fd_nfiles ||
1474 (fp = fdp->fd_ofiles[fd]) == NULL ||
1475 fp->f_ops == &badfileops)
1476 fp = NULL;
1477 else
1478 fhold(fp);
1479 FILEDESC_UNLOCK(fdp);
1480 return (fp);
1481}
1482
1483/*
1484 * Find the struct file 'fd' in process 'p' and bump it's refcount,
1485 * struct file is locked on return.
1486 */
1487struct file *
1488ffind_lock(td, fd)
1489 struct thread *td;
1490 int fd;
1491{
1492 struct filedesc *fdp;
1493 struct file *fp;
1494
1495 if (td == NULL || (fdp = td->td_proc->p_fd) == NULL)
1496 return (NULL);
1497 FILEDESC_LOCK(fdp);
1498 if (fd < 0 || fd >= fdp->fd_nfiles ||
1499 (fp = fdp->fd_ofiles[fd]) == NULL ||
1500 fp->f_ops == &badfileops) {
1501 fp = NULL;
1502 } else {
1503 FILE_LOCK(fp);
1504 fhold_locked(fp);
1505 }
1506 FILEDESC_UNLOCK(fdp);
1507 return (fp);
1508}
1509
1510int
1511fdrop(fp, td)
1512 struct file *fp;
1513 struct thread *td;
1514{
1515
1516 FILE_LOCK(fp);
1517 return (fdrop_locked(fp, td));
1518}
1519
1520/*
1318 * Extract the file pointer associated with the specified descriptor for
1319 * the current user process. If no error occured 0 is returned, *fpp
1320 * will be set to the file pointer, and the file pointer's ref count
1321 * will be bumped. Use fdrop() to drop it. If an error occured the
1322 * non-zero error is returned and *fpp is set to NULL.
1323 *
1324 * This routine requires Giant for the moment. Once enough of the
1325 * system is converted over to this and other encapsulated APIs we

--- 147 unchanged lines hidden (view full) ---

1473 */
1474void
1475fputsock(struct socket *so)
1476{
1477 sorele(so);
1478}
1479
1480int
1521 * Extract the file pointer associated with the specified descriptor for
1522 * the current user process. If no error occured 0 is returned, *fpp
1523 * will be set to the file pointer, and the file pointer's ref count
1524 * will be bumped. Use fdrop() to drop it. If an error occured the
1525 * non-zero error is returned and *fpp is set to NULL.
1526 *
1527 * This routine requires Giant for the moment. Once enough of the
1528 * system is converted over to this and other encapsulated APIs we

--- 147 unchanged lines hidden (view full) ---

1676 */
1677void
1678fputsock(struct socket *so)
1679{
1680 sorele(so);
1681}
1682
1683int
1481fdrop(fp, td)
1684fdrop_locked(fp, td)
1482 struct file *fp;
1483 struct thread *td;
1484{
1485 struct flock lf;
1486 struct vnode *vp;
1487 int error;
1488
1685 struct file *fp;
1686 struct thread *td;
1687{
1688 struct flock lf;
1689 struct vnode *vp;
1690 int error;
1691
1489 if (--fp->f_count > 0)
1692 FILE_LOCK_ASSERT(fp, MA_OWNED);
1693
1694 if (--fp->f_count > 0) {
1695 FILE_UNLOCK(fp);
1490 return (0);
1696 return (0);
1697 }
1491 if (fp->f_count < 0)
1492 panic("fdrop: count < 0");
1493 if ((fp->f_flag & FHASLOCK) && fp->f_type == DTYPE_VNODE) {
1494 lf.l_whence = SEEK_SET;
1495 lf.l_start = 0;
1496 lf.l_len = 0;
1497 lf.l_type = F_UNLCK;
1498 vp = (struct vnode *)fp->f_data;
1698 if (fp->f_count < 0)
1699 panic("fdrop: count < 0");
1700 if ((fp->f_flag & FHASLOCK) && fp->f_type == DTYPE_VNODE) {
1701 lf.l_whence = SEEK_SET;
1702 lf.l_start = 0;
1703 lf.l_len = 0;
1704 lf.l_type = F_UNLCK;
1705 vp = (struct vnode *)fp->f_data;
1706 FILE_UNLOCK(fp);
1499 (void) VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK);
1707 (void) VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK);
1500 }
1708 } else
1709 FILE_UNLOCK(fp);
1501 if (fp->f_ops != &badfileops)
1502 error = fo_close(fp, td);
1503 else
1504 error = 0;
1505 ffree(fp);
1506 return (error);
1507}
1508

--- 13 unchanged lines hidden (view full) ---

1522 * MPSAFE
1523 */
1524/* ARGSUSED */
1525int
1526flock(td, uap)
1527 struct thread *td;
1528 register struct flock_args *uap;
1529{
1710 if (fp->f_ops != &badfileops)
1711 error = fo_close(fp, td);
1712 else
1713 error = 0;
1714 ffree(fp);
1715 return (error);
1716}
1717

--- 13 unchanged lines hidden (view full) ---

1731 * MPSAFE
1732 */
1733/* ARGSUSED */
1734int
1735flock(td, uap)
1736 struct thread *td;
1737 register struct flock_args *uap;
1738{
1530 register struct filedesc *fdp = td->td_proc->p_fd;
1531 register struct file *fp;
1532 struct vnode *vp;
1533 struct flock lf;
1534 int error;
1535
1739 register struct file *fp;
1740 struct vnode *vp;
1741 struct flock lf;
1742 int error;
1743
1536 mtx_lock(&Giant);
1537
1538 if ((unsigned)uap->fd >= fdp->fd_nfiles ||
1539 (fp = fdp->fd_ofiles[uap->fd]) == NULL) {
1540 error = EBADF;
1541 goto done2;
1542 }
1744 fp = ffind_hold(td, uap->fd);
1745 if (fp == NULL)
1746 return (EBADF);
1543 if (fp->f_type != DTYPE_VNODE) {
1747 if (fp->f_type != DTYPE_VNODE) {
1544 error = EOPNOTSUPP;
1545 goto done2;
1748 fdrop(fp, td);
1749 return (EOPNOTSUPP);
1546 }
1750 }
1751
1752 mtx_lock(&Giant);
1547 vp = (struct vnode *)fp->f_data;
1548 lf.l_whence = SEEK_SET;
1549 lf.l_start = 0;
1550 lf.l_len = 0;
1551 if (uap->how & LOCK_UN) {
1552 lf.l_type = F_UNLCK;
1753 vp = (struct vnode *)fp->f_data;
1754 lf.l_whence = SEEK_SET;
1755 lf.l_start = 0;
1756 lf.l_len = 0;
1757 if (uap->how & LOCK_UN) {
1758 lf.l_type = F_UNLCK;
1759 FILE_LOCK(fp);
1553 fp->f_flag &= ~FHASLOCK;
1760 fp->f_flag &= ~FHASLOCK;
1761 FILE_UNLOCK(fp);
1554 error = VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK);
1555 goto done2;
1556 }
1557 if (uap->how & LOCK_EX)
1558 lf.l_type = F_WRLCK;
1559 else if (uap->how & LOCK_SH)
1560 lf.l_type = F_RDLCK;
1561 else {
1562 error = EBADF;
1563 goto done2;
1564 }
1762 error = VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK);
1763 goto done2;
1764 }
1765 if (uap->how & LOCK_EX)
1766 lf.l_type = F_WRLCK;
1767 else if (uap->how & LOCK_SH)
1768 lf.l_type = F_RDLCK;
1769 else {
1770 error = EBADF;
1771 goto done2;
1772 }
1773 FILE_LOCK(fp);
1565 fp->f_flag |= FHASLOCK;
1774 fp->f_flag |= FHASLOCK;
1566 if (uap->how & LOCK_NB)
1567 error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK);
1568 else
1569 error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK|F_WAIT);
1775 FILE_UNLOCK(fp);
1776 error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf,
1777 (uap->how & LOCK_NB) ? F_FLOCK : F_FLOCK | F_WAIT);
1570done2:
1778done2:
1779 fdrop(fp, td);
1571 mtx_unlock(&Giant);
1572 return (error);
1573}
1574
1575/*
1576 * File Descriptor pseudo-device driver (/dev/fd/).
1577 *
1578 * Opening minor device N dup()s the file (if any) connected to file

--- 35 unchanged lines hidden (view full) ---

1614 register struct file *wfp;
1615 struct file *fp;
1616
1617 /*
1618 * If the to-be-dup'd fd number is greater than the allowed number
1619 * of file descriptors, or the fd to be dup'd has already been
1620 * closed, then reject.
1621 */
1780 mtx_unlock(&Giant);
1781 return (error);
1782}
1783
1784/*
1785 * File Descriptor pseudo-device driver (/dev/fd/).
1786 *
1787 * Opening minor device N dup()s the file (if any) connected to file

--- 35 unchanged lines hidden (view full) ---

1823 register struct file *wfp;
1824 struct file *fp;
1825
1826 /*
1827 * If the to-be-dup'd fd number is greater than the allowed number
1828 * of file descriptors, or the fd to be dup'd has already been
1829 * closed, then reject.
1830 */
1831 FILEDESC_LOCK(fdp);
1622 if ((u_int)dfd >= fdp->fd_nfiles ||
1623 (wfp = fdp->fd_ofiles[dfd]) == NULL) {
1832 if ((u_int)dfd >= fdp->fd_nfiles ||
1833 (wfp = fdp->fd_ofiles[dfd]) == NULL) {
1834 FILEDESC_UNLOCK(fdp);
1624 return (EBADF);
1625 }
1626
1627 /*
1628 * There are two cases of interest here.
1629 *
1630 * For ENODEV simply dup (dfd) to file descriptor
1631 * (indx) and return.

--- 5 unchanged lines hidden (view full) ---

1637 * Any other error code is just returned.
1638 */
1639 switch (error) {
1640 case ENODEV:
1641 /*
1642 * Check that the mode the file is being opened for is a
1643 * subset of the mode of the existing descriptor.
1644 */
1835 return (EBADF);
1836 }
1837
1838 /*
1839 * There are two cases of interest here.
1840 *
1841 * For ENODEV simply dup (dfd) to file descriptor
1842 * (indx) and return.

--- 5 unchanged lines hidden (view full) ---

1848 * Any other error code is just returned.
1849 */
1850 switch (error) {
1851 case ENODEV:
1852 /*
1853 * Check that the mode the file is being opened for is a
1854 * subset of the mode of the existing descriptor.
1855 */
1645 if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag)
1856 FILE_LOCK(wfp);
1857 if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag) {
1858 FILE_UNLOCK(wfp);
1859 FILEDESC_UNLOCK(fdp);
1646 return (EACCES);
1860 return (EACCES);
1861 }
1647 fp = fdp->fd_ofiles[indx];
1648#if 0
1649 if (fp && fdp->fd_ofileflags[indx] & UF_MAPPED)
1650 (void) munmapfd(td, indx);
1651#endif
1652 fdp->fd_ofiles[indx] = wfp;
1653 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];
1862 fp = fdp->fd_ofiles[indx];
1863#if 0
1864 if (fp && fdp->fd_ofileflags[indx] & UF_MAPPED)
1865 (void) munmapfd(td, indx);
1866#endif
1867 fdp->fd_ofiles[indx] = wfp;
1868 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];
1654 fhold(wfp);
1869 fhold_locked(wfp);
1870 FILE_UNLOCK(wfp);
1655 if (indx > fdp->fd_lastfile)
1656 fdp->fd_lastfile = indx;
1871 if (indx > fdp->fd_lastfile)
1872 fdp->fd_lastfile = indx;
1873 if (fp != NULL)
1874 FILE_LOCK(fp);
1875 FILEDESC_UNLOCK(fdp);
1657 /*
1658 * we now own the reference to fp that the ofiles[] array
1659 * used to own. Release it.
1660 */
1876 /*
1877 * we now own the reference to fp that the ofiles[] array
1878 * used to own. Release it.
1879 */
1661 if (fp)
1662 fdrop(fp, td);
1880 if (fp != NULL)
1881 fdrop_locked(fp, td);
1663 return (0);
1664
1665 case ENXIO:
1666 /*
1667 * Steal away the file pointer from dfd, and stuff it into indx.
1668 */
1669 fp = fdp->fd_ofiles[indx];
1670#if 0
1671 if (fp && fdp->fd_ofileflags[indx] & UF_MAPPED)
1672 (void) munmapfd(td, indx);
1673#endif
1674 fdp->fd_ofiles[indx] = fdp->fd_ofiles[dfd];
1675 fdp->fd_ofiles[dfd] = NULL;
1676 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];
1677 fdp->fd_ofileflags[dfd] = 0;
1678
1679 /*
1882 return (0);
1883
1884 case ENXIO:
1885 /*
1886 * Steal away the file pointer from dfd, and stuff it into indx.
1887 */
1888 fp = fdp->fd_ofiles[indx];
1889#if 0
1890 if (fp && fdp->fd_ofileflags[indx] & UF_MAPPED)
1891 (void) munmapfd(td, indx);
1892#endif
1893 fdp->fd_ofiles[indx] = fdp->fd_ofiles[dfd];
1894 fdp->fd_ofiles[dfd] = NULL;
1895 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];
1896 fdp->fd_ofileflags[dfd] = 0;
1897
1898 /*
1680 * we now own the reference to fp that the ofiles[] array
1681 * used to own. Release it.
1682 */
1683 if (fp)
1684 fdrop(fp, td);
1685 /*
1686 * Complete the clean up of the filedesc structure by
1687 * recomputing the various hints.
1688 */
1689 if (indx > fdp->fd_lastfile) {
1690 fdp->fd_lastfile = indx;
1691 } else {
1692 while (fdp->fd_lastfile > 0 &&
1693 fdp->fd_ofiles[fdp->fd_lastfile] == NULL) {
1694 fdp->fd_lastfile--;
1695 }
1696 if (dfd < fdp->fd_freefile)
1697 fdp->fd_freefile = dfd;
1698 }
1899 * Complete the clean up of the filedesc structure by
1900 * recomputing the various hints.
1901 */
1902 if (indx > fdp->fd_lastfile) {
1903 fdp->fd_lastfile = indx;
1904 } else {
1905 while (fdp->fd_lastfile > 0 &&
1906 fdp->fd_ofiles[fdp->fd_lastfile] == NULL) {
1907 fdp->fd_lastfile--;
1908 }
1909 if (dfd < fdp->fd_freefile)
1910 fdp->fd_freefile = dfd;
1911 }
1912 if (fp != NULL)
1913 FILE_LOCK(fp);
1914 FILEDESC_UNLOCK(fdp);
1915
1916 /*
1917 * we now own the reference to fp that the ofiles[] array
1918 * used to own. Release it.
1919 */
1920 if (fp != NULL)
1921 fdrop_locked(fp, td);
1699 return (0);
1700
1701 default:
1922 return (0);
1923
1924 default:
1925 FILEDESC_UNLOCK(fdp);
1702 return (error);
1703 }
1704 /* NOTREACHED */
1705}
1706
1707/*
1708 * Get file structures.
1709 */
1710static int
1711sysctl_kern_file(SYSCTL_HANDLER_ARGS)
1712{
1713 int error;
1714 struct file *fp;
1715
1926 return (error);
1927 }
1928 /* NOTREACHED */
1929}
1930
1931/*
1932 * Get file structures.
1933 */
1934static int
1935sysctl_kern_file(SYSCTL_HANDLER_ARGS)
1936{
1937 int error;
1938 struct file *fp;
1939
1940 sx_slock(&filelist_lock);
1716 if (!req->oldptr) {
1717 /*
1718 * overestimate by 10 files
1719 */
1941 if (!req->oldptr) {
1942 /*
1943 * overestimate by 10 files
1944 */
1720 return (SYSCTL_OUT(req, 0, sizeof(filehead) +
1721 (nfiles + 10) * sizeof(struct file)));
1945 error = SYSCTL_OUT(req, 0, sizeof(filehead) +
1946 (nfiles + 10) * sizeof(struct file));
1947 sx_sunlock(&filelist_lock);
1948 return (error);
1722 }
1723
1724 error = SYSCTL_OUT(req, (caddr_t)&filehead, sizeof(filehead));
1949 }
1950
1951 error = SYSCTL_OUT(req, (caddr_t)&filehead, sizeof(filehead));
1725 if (error)
1952 if (error) {
1953 sx_sunlock(&filelist_lock);
1726 return (error);
1954 return (error);
1955 }
1727
1728 /*
1729 * followed by an array of file structures
1730 */
1731 LIST_FOREACH(fp, &filehead, f_list) {
1732 error = SYSCTL_OUT(req, (caddr_t)fp, sizeof (struct file));
1956
1957 /*
1958 * followed by an array of file structures
1959 */
1960 LIST_FOREACH(fp, &filehead, f_list) {
1961 error = SYSCTL_OUT(req, (caddr_t)fp, sizeof (struct file));
1733 if (error)
1962 if (error) {
1963 sx_sunlock(&filelist_lock);
1734 return (error);
1964 return (error);
1965 }
1735 }
1966 }
1967 sx_sunlock(&filelist_lock);
1736 return (0);
1737}
1738
1739SYSCTL_PROC(_kern, KERN_FILE, file, CTLTYPE_OPAQUE|CTLFLAG_RD,
1740 0, 0, sysctl_kern_file, "S,file", "Entire file table");
1741
1742SYSCTL_INT(_kern, KERN_MAXFILESPERPROC, maxfilesperproc, CTLFLAG_RW,
1743 &maxfilesperproc, 0, "Maximum files allowed open per process");

--- 93 unchanged lines hidden (view full) ---

1837 struct thread *td;
1838{
1839
1840 return (EBADF);
1841}
1842
1843SYSINIT(fildescdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,
1844 fildesc_drvinit,NULL)
1968 return (0);
1969}
1970
1971SYSCTL_PROC(_kern, KERN_FILE, file, CTLTYPE_OPAQUE|CTLFLAG_RD,
1972 0, 0, sysctl_kern_file, "S,file", "Entire file table");
1973
1974SYSCTL_INT(_kern, KERN_MAXFILESPERPROC, maxfilesperproc, CTLFLAG_RW,
1975 &maxfilesperproc, 0, "Maximum files allowed open per process");

--- 93 unchanged lines hidden (view full) ---

2069 struct thread *td;
2070{
2071
2072 return (EBADF);
2073}
2074
2075SYSINIT(fildescdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,
2076 fildesc_drvinit,NULL)
2077
2078static void filelistinit __P((void *));
2079SYSINIT(select, SI_SUB_LOCK, SI_ORDER_FIRST, filelistinit, NULL)
2080
2081/* ARGSUSED*/
2082static void
2083filelistinit(dummy)
2084 void *dummy;
2085{
2086 sx_init(&filelist_lock, "filelist lock");
2087}