1139825Simp/*-
21541Srgrimes * Copyright (c) 1990, 1993
31541Srgrimes *	The Regents of the University of California.  All rights reserved.
41541Srgrimes *
51541Srgrimes * Redistribution and use in source and binary forms, with or without
61541Srgrimes * modification, are permitted provided that the following conditions
71541Srgrimes * are met:
81541Srgrimes * 1. Redistributions of source code must retain the above copyright
91541Srgrimes *    notice, this list of conditions and the following disclaimer.
101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111541Srgrimes *    notice, this list of conditions and the following disclaimer in the
121541Srgrimes *    documentation and/or other materials provided with the distribution.
131541Srgrimes * 4. Neither the name of the University nor the names of its contributors
141541Srgrimes *    may be used to endorse or promote products derived from this software
151541Srgrimes *    without specific prior written permission.
161541Srgrimes *
171541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
181541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201541Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
211541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271541Srgrimes * SUCH DAMAGE.
281541Srgrimes *
291541Srgrimes *	@(#)filedesc.h	8.1 (Berkeley) 6/2/93
3050477Speter * $FreeBSD$
311541Srgrimes */
321541Srgrimes
332165Spaul#ifndef _SYS_FILEDESC_H_
3459774Sbde#define	_SYS_FILEDESC_H_
352165Spaul
36255219Spjd#include <sys/caprights.h>
37126590Sbde#include <sys/queue.h>
38133741Sjmg#include <sys/event.h>
39168355Srwatson#include <sys/lock.h>
40137804Sphk#include <sys/priority.h>
41273137Smjg#include <sys/seq.h>
42168355Srwatson#include <sys/sx.h>
4341086Struckman
44126593Sbde#include <machine/_limits.h>
45126593Sbde
46247602Spjdstruct filecaps {
47247602Spjd	cap_rights_t	 fc_rights;	/* per-descriptor capability rights */
48247602Spjd	u_long		*fc_ioctls;	/* per-descriptor allowed ioctls */
49247602Spjd	int16_t		 fc_nioctls;	/* fc_ioctls array size */
50254479Spjd	uint32_t	 fc_fcntls;	/* per-descriptor allowed fcntls */
51247602Spjd};
52247602Spjd
53247602Spjdstruct filedescent {
54273137Smjg	struct file	*fde_file;	/* file structure for open file */
55273137Smjg	struct filecaps	 fde_caps;	/* per-descriptor rights */
56273137Smjg	uint8_t		 fde_flags;	/* per-process open file flags */
57273137Smjg	seq_t		 fde_seq;	/* keep file and caps in sync */
58247602Spjd};
59247602Spjd#define	fde_rights	fde_caps.fc_rights
60247602Spjd#define	fde_fcntls	fde_caps.fc_fcntls
61247602Spjd#define	fde_ioctls	fde_caps.fc_ioctls
62247602Spjd#define	fde_nioctls	fde_caps.fc_nioctls
63273137Smjg#define	fde_change_size	(offsetof(struct filedescent, fde_seq))
64247602Spjd
651541Srgrimes/*
661541Srgrimes * This structure is used for the management of descriptors.  It may be
671541Srgrimes * shared by multiple processes.
681541Srgrimes */
69126591Sbde#define NDSLOTTYPE	u_long
701541Srgrimes
711541Srgrimesstruct filedesc {
72247602Spjd	struct	filedescent *fd_ofiles;	/* open files */
731541Srgrimes	struct	vnode *fd_cdir;		/* current directory */
741541Srgrimes	struct	vnode *fd_rdir;		/* root directory */
7551649Sphk	struct	vnode *fd_jdir;		/* jail root directory */
761541Srgrimes	int	fd_nfiles;		/* number of open files allocated */
77126591Sbde	NDSLOTTYPE *fd_map;		/* bitmap of free fds */
7889306Salfred	int	fd_lastfile;		/* high-water mark of fd_ofiles */
7989306Salfred	int	fd_freefile;		/* approx. next free file */
801541Srgrimes	u_short	fd_cmask;		/* mask for file creation */
81138838Sphk	u_short	fd_refcnt;		/* thread reference count */
82138838Sphk	u_short	fd_holdcnt;		/* hold count on structure + mutex */
83168355Srwatson	struct	sx fd_sx;		/* protects members of this struct */
84133741Sjmg	struct	kqlist fd_kqlist;	/* list of kqueues on this filedesc */
85115702Stegge	int	fd_holdleaderscount;	/* block fdfree() for shared close() */
86115702Stegge	int	fd_holdleaderswakeup;	/* fdfree() needs wakeup */
871541Srgrimes};
88273137Smjg#define	fd_seq(fdp, fd)	(&(fdp)->fd_ofiles[(fd)].fde_seq)
891541Srgrimes
901541Srgrimes/*
91115702Stegge * Structure to keep track of (process leader, struct fildedesc) tuples.
92115702Stegge * Each process has a pointer to such a structure when detailed tracking
93126591Sbde * is needed, e.g., when rfork(RFPROC | RFMEM) causes a file descriptor
94115702Stegge * table to be shared by processes having different "p_leader" pointers
95115702Stegge * and thus distinct POSIX style locks.
96115702Stegge *
97115702Stegge * fdl_refcount and fdl_holdcount are protected by struct filedesc mtx.
98115702Stegge */
99115702Steggestruct filedesc_to_leader {
100115702Stegge	int		fdl_refcount;	/* references from struct proc */
101115702Stegge	int		fdl_holdcount;	/* temporary hold during closef */
102115702Stegge	int		fdl_wakeup;	/* fdfree() waits on closef() */
103115702Stegge	struct proc	*fdl_leader;	/* owner of POSIX locks */
104126591Sbde	/* Circular list: */
105115702Stegge	struct filedesc_to_leader *fdl_prev;
106115702Stegge	struct filedesc_to_leader *fdl_next;
107115702Stegge};
108115702Stegge
109115702Stegge/*
1101541Srgrimes * Per-process open flags.
1111541Srgrimes */
112246912Spjd#define	UF_EXCLOSE	0x01		/* auto-close on exec */
1131541Srgrimes
11455205Speter#ifdef _KERNEL
11589306Salfred
116247602Spjd/* Flags for do_dup() */
117247602Spjd#define	DUP_FIXED	0x1	/* Force fixed allocation. */
118247602Spjd#define	DUP_FCNTL	0x2	/* fcntl()-style errors. */
119247602Spjd#define	DUP_CLOEXEC	0x4	/* Atomically set FD_CLOEXEC. */
120247602Spjd
12189306Salfred/* Lock a file descriptor table. */
122168355Srwatson#define	FILEDESC_LOCK_INIT(fdp)	sx_init(&(fdp)->fd_sx, "filedesc structure")
123168355Srwatson#define	FILEDESC_LOCK_DESTROY(fdp)	sx_destroy(&(fdp)->fd_sx)
124168355Srwatson#define	FILEDESC_LOCK(fdp)	(&(fdp)->fd_sx)
125168355Srwatson#define	FILEDESC_XLOCK(fdp)	sx_xlock(&(fdp)->fd_sx)
126168355Srwatson#define	FILEDESC_XUNLOCK(fdp)	sx_xunlock(&(fdp)->fd_sx)
127168355Srwatson#define	FILEDESC_SLOCK(fdp)	sx_slock(&(fdp)->fd_sx)
128168355Srwatson#define	FILEDESC_SUNLOCK(fdp)	sx_sunlock(&(fdp)->fd_sx)
129137804Sphk
130168355Srwatson#define	FILEDESC_LOCK_ASSERT(fdp)	sx_assert(&(fdp)->fd_sx, SX_LOCKED | \
131168355Srwatson					    SX_NOTRECURSED)
132168355Srwatson#define	FILEDESC_XLOCK_ASSERT(fdp)	sx_assert(&(fdp)->fd_sx, SX_XLOCKED | \
133168355Srwatson					    SX_NOTRECURSED)
134237072Spjd#define	FILEDESC_UNLOCK_ASSERT(fdp)	sx_assert(&(fdp)->fd_sx, SX_UNLOCKED)
135137804Sphk
136122514Sjhbstruct thread;
137122514Sjhb
138247602Spjdvoid	filecaps_init(struct filecaps *fcaps);
139247602Spjdvoid	filecaps_copy(const struct filecaps *src, struct filecaps *dst);
140247736Spjdvoid	filecaps_move(struct filecaps *src, struct filecaps *dst);
141247602Spjdvoid	filecaps_free(struct filecaps *fcaps);
142247602Spjd
143126591Sbdeint	closef(struct file *fp, struct thread *td);
144247602Spjdint	do_dup(struct thread *td, int flags, int old, int new,
145247602Spjd	    register_t *retval);
146237033Spjdint	dupfdopen(struct thread *td, struct filedesc *fdp, int dfd, int mode,
147237033Spjd	    int openerror, int *indxp);
148220245Skibint	falloc(struct thread *td, struct file **resultfp, int *resultfd,
149219999Skib	    int flags);
150223694Sjonathanint	falloc_noinstall(struct thread *td, struct file **resultfp);
151247602Spjdint	finstall(struct thread *td, struct file *fp, int *resultfp, int flags,
152247602Spjd	    struct filecaps *fcaps);
153126591Sbdeint	fdalloc(struct thread *td, int minfd, int *result);
154249480Smjgint	fdallocn(struct thread *td, int minfd, int *fds, int n);
15592719Salfredint	fdavail(struct thread *td, int n);
156126590Sbdeint	fdcheckstd(struct thread *td);
157137355Sphkvoid	fdclose(struct filedesc *fdp, struct file *fp, int idx, struct thread *td);
15892719Salfredvoid	fdcloseexec(struct thread *td);
159108522Salfredstruct	filedesc *fdcopy(struct filedesc *fdp);
160268345Smjgvoid	fdunshare(struct thread *td);
161247602Spjdvoid	fdescfree(struct thread *td);
162108520Salfredstruct	filedesc *fdinit(struct filedesc *fdp);
163108520Salfredstruct	filedesc *fdshare(struct filedesc *fdp);
164115702Steggestruct filedesc_to_leader *
165126591Sbde	filedesc_to_leader_alloc(struct filedesc_to_leader *old,
166126591Sbde	    struct filedesc *fdp, struct proc *leader);
167255219Spjdint	getvnode(struct filedesc *fdp, int fd, cap_rights_t *rightsp,
168224778Srwatson	    struct file **fpp);
169138835Sphkvoid	mountcheckdirs(struct vnode *olddp, struct vnode *newdp);
170126590Sbdevoid	setugidsafety(struct thread *td);
171115702Stegge
172192080Sjeff/* Return a referenced file from an unlocked descriptor. */
173255219Spjdint	fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
174247602Spjd	    int needfcntl, struct file **fpp, cap_rights_t *haverightsp);
175192080Sjeff
176192080Sjeff/* Requires a FILEDESC_{S,X}LOCK held and returns without a ref. */
17789969Salfredstatic __inline struct file *
178100072Smarkmfget_locked(struct filedesc *fdp, int fd)
17989969Salfred{
18089969Salfred
181237081Spjd	FILEDESC_LOCK_ASSERT(fdp);
182237081Spjd
183268338Smjg	if (fd < 0 || fd > fdp->fd_lastfile)
184237081Spjd		return (NULL);
185237081Spjd
186247602Spjd	return (fdp->fd_ofiles[fd].fde_file);
18789969Salfred}
18889969Salfred
18959774Sbde#endif /* _KERNEL */
1902165Spaul
19159774Sbde#endif /* !_SYS_FILEDESC_H_ */
192