I recall someone (maybe oga and/or djm?) being interested in having
O_CLOEXEC support. While here, I noticed POSIX defines O_DIRECTORY,
which is pretty trivial to implement as well.
Tested that these both work as expected on directory and non-directory
files.
ok?
Index: sys/fcntl.h
===================================================================
RCS file: /home/mdempsky/anoncvs/cvs/src/sys/sys/fcntl.h,v
retrieving revision 1.14
diff -u -p -r1.14 fcntl.h
--- sys/fcntl.h 8 Jul 2011 04:23:24 -0000 1.14
+++ sys/fcntl.h 8 Jul 2011 10:24:09 -0000
@@ -108,6 +108,9 @@
/* defined by POSIX 1003.1; BSD default, this bit is not required */
#define O_NOCTTY 0x8000 /* don't assign controlling
terminal */
+#define O_CLOEXEC 0x10000 /* atomically set FD_CLOEXEC */
+#define O_DIRECTORY 0x20000 /* fail if not a directory */
+
#ifdef _KERNEL
/*
* convert from open() flags to/from fflags; convert O_RD/WR to FREAD/FWRITE.
Index: kern/vfs_vnops.c
===================================================================
RCS file: /home/mdempsky/anoncvs/cvs/src/sys/kern/vfs_vnops.c,v
retrieving revision 1.67
diff -u -p -r1.67 vfs_vnops.c
--- kern/vfs_vnops.c 6 Jul 2011 09:14:26 -0000 1.67
+++ kern/vfs_vnops.c 8 Jul 2011 10:33:47 -0000
@@ -135,6 +135,10 @@ vn_open(struct nameidata *ndp, int fmode
error = ELOOP;
goto bad;
}
+ if ((fmode & O_DIRECTORY) && vp->v_type != VDIR) {
+ error = ENOTDIR;
+ goto bad;
+ }
if ((fmode & O_CREAT) == 0) {
if (fmode & FREAD) {
if ((error = VOP_ACCESS(vp, VREAD, cred, p)) != 0)
Index: kern/vfs_syscalls.c
===================================================================
RCS file: /home/mdempsky/anoncvs/cvs/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.170
diff -u -p -r1.170 vfs_syscalls.c
--- kern/vfs_syscalls.c 8 Jul 2011 04:23:24 -0000 1.170
+++ kern/vfs_syscalls.c 8 Jul 2011 10:22:02 -0000
@@ -927,6 +927,8 @@ doopenat(struct proc *p, int fd, const c
}
}
VOP_UNLOCK(vp, 0, p);
+ if (flags & O_CLOEXEC)
+ fdp->fd_ofileflags[indx] |= UF_EXCLOSE;
*retval = indx;
FILE_SET_MATURE(fp);
out: