To simplify the filedesc fd_ofileflags handling, how about if we make
falloc() take optional flags to OR into the new fd's ofileflags? That
eliminates a quarter of the references to fd_ofileflags.
While here, make falloc() assert that its return arguments are non-NULL,
as it doesn't make sense to allocate a larval file but no get a reference
back with which to mature it, or to allocate an fd but not get back which.
ok?
Philip Guenther
Index: share/man/man9/file.9
===
RCS file: /data/src/openbsd/src/share/man/man9/file.9,v
retrieving revision 1.16
diff -u -p -r1.16 file.9
--- share/man/man9/file.9 23 Nov 2015 17:53:57 - 1.16
+++ share/man/man9/file.9 11 Feb 2017 08:32:51 -
@@ -38,7 +38,7 @@
.In sys/file.h
.In sys/filedesc.h
.Ft int
-.Fn falloc "struct proc *p" "struct file **resultfp" "int *resultfd"
+.Fn falloc "struct proc *p" "int flags" "struct file **resultfp" "int
*resultfd"
.Ft int
.Fn fdrelease "struct proc *p" "int fd"
.Ft void
@@ -66,17 +66,32 @@ kqueues (see
.Xr kqueue 2 ) ,
and various special purpose communication endpoints.
.Pp
-A new file descriptor is allocated with the function
+A new file and a file descriptor for it are allocated with the function
+.Fn falloc .
+The
+.Fa flags
+argument can be used to set the
+.Dv UF_EXCLOSE
+flag on the new descriptor.
+The larval file and fd are returned via
+.Fa resultfp
+and
+.Fa resultfd ,
+which must not be
+.Dv NULL .
.Fn falloc
-and freed with
+initializes the new file to have a reference count of two:
+one for the reference from the file descriptor table and one
+for the caller to release with
+.Fn FRELE
+when it done initializing it.
+.Pp
+A file descriptor is freed with
.Fn fdrelease .
-.Fn falloc
-and
-.Fn fdrelease
-deal with allocating and freeing slots in the file descriptor table,
-expanding the table when necessary and initializing the descriptor.
-It's possible to do those things in smaller steps, but it's not
-recommended to make complicated kernel APIs that require it.
+This releases the reference that it holds to the underlying file;
+if that's the last reference then the file will be freed.
+.\" with
+.\" .Xr closef 9 .
.Pp
The files are extracted from the file descriptor table using the
functions
Index: sys/sys/filedesc.h
===
RCS file: /data/src/openbsd/src/sys/sys/filedesc.h,v
retrieving revision 1.33
diff -u -p -r1.33 filedesc.h
--- sys/sys/filedesc.h 25 Jan 2017 06:15:50 - 1.33
+++ sys/sys/filedesc.h 11 Feb 2017 09:13:34 -
@@ -125,7 +125,7 @@ voidfiledesc_init(void);
intdupfdopen(struct proc *, int, int);
intfdalloc(struct proc *p, int want, int *result);
void fdexpand(struct proc *);
-intfalloc(struct proc *p, struct file **resultfp, int *resultfd);
+intfalloc(struct proc *_p, int _flags, struct file **_rfp, int *_rfd);
struct filedesc *fdinit(void);
struct filedesc *fdshare(struct process *);
struct filedesc *fdcopy(struct process *);
Index: sys/kern/exec_script.c
===
RCS file: /data/src/openbsd/src/sys/kern/exec_script.c,v
retrieving revision 1.39
diff -u -p -r1.39 exec_script.c
--- sys/kern/exec_script.c 25 Apr 2016 20:00:33 - 1.39
+++ sys/kern/exec_script.c 11 Feb 2017 09:12:08 -
@@ -169,7 +169,7 @@ check_shell:
#endif
fdplock(p->p_fd);
- error = falloc(p, , >ep_fd);
+ error = falloc(p, 0, , >ep_fd);
fdpunlock(p->p_fd);
if (error)
goto fail;
Index: sys/kern/kern_descrip.c
===
RCS file: /data/src/openbsd/src/sys/kern/kern_descrip.c,v
retrieving revision 1.139
diff -u -p -r1.139 kern_descrip.c
--- sys/kern/kern_descrip.c 24 Jan 2017 04:09:59 - 1.139
+++ sys/kern/kern_descrip.c 11 Feb 2017 09:08:23 -
@@ -895,11 +895,14 @@ fdexpand(struct proc *p)
* a file descriptor for the process that refers to it.
*/
int
-falloc(struct proc *p, struct file **resultfp, int *resultfd)
+falloc(struct proc *p, int flags, struct file **resultfp, int *resultfd)
{
struct file *fp, *fq;
int error, i;
+ KASSERT(resultfp != NULL);
+ KASSERT(resultfd != NULL);
+
fdpassertlocked(p->p_fd);
restart:
if ((error = fdalloc(p, 0, )) != 0) {
@@ -929,13 +932,12 @@ restart:
LIST_INSERT_HEAD(, fp, f_list);
}
p->p_fd->fd_ofiles[i] = fp;
+ p->p_fd->fd_ofileflags[i] |= (flags & UF_EXCLOSE);
fp->f_count = 1;
fp->f_cred = p->p_ucred;
crhold(fp->f_cred);
- if (resultfp)
- *resultfp = fp;
- if (resultfd)
- *resultfd = i;
+ *resultfp = fp;
+ *resultfd = i;
FREF(fp);
return (0);
}
Index: