summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Mustacchi <rm@fingolfin.org>2020-01-18 22:03:20 +0000
committerRobert Mustacchi <rm@fingolfin.org>2020-02-01 06:34:51 +0000
commit69c811ab73b7ce531454837ae68c4343e8724e0b (patch)
tree00076116a576bde8519acea540782c3b49a63f34
parent2fe8bc68ec8e8e8e05997b3ac2f081bfdded45ab (diff)
downloadillumos-joyent-69c811ab73b7ce531454837ae68c4343e8724e0b.tar.gz
9965 Want support for O_DIRECTORY
Reviewed by: Andy Fiddaman <andy@omniosce.org> Reviewed by: Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org> Approved by: Garrett D'Amore <garrett@damore.org>
-rw-r--r--usr/src/cmd/mandoc/config.h11
-rw-r--r--usr/src/cmd/truss/codes.c4
-rw-r--r--usr/src/man/man2/open.245
-rw-r--r--usr/src/man/man3head/fcntl.h.3head20
-rw-r--r--usr/src/pkg/manifests/system-test-ostest.mf2
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/fcntl_h.cfg1
-rw-r--r--usr/src/test/os-tests/runfiles/default.run3
-rw-r--r--usr/src/test/os-tests/tests/Makefile57
-rw-r--r--usr/src/test/os-tests/tests/odirectory.c247
-rw-r--r--usr/src/uts/common/fs/vnode.c34
-rw-r--r--usr/src/uts/common/sys/fcntl.h7
-rw-r--r--usr/src/uts/common/sys/file.h1
12 files changed, 421 insertions, 11 deletions
diff --git a/usr/src/cmd/mandoc/config.h b/usr/src/cmd/mandoc/config.h
index 3ae0245c08..e4bc9a6a3b 100644
--- a/usr/src/cmd/mandoc/config.h
+++ b/usr/src/cmd/mandoc/config.h
@@ -3,12 +3,21 @@
#include <sys/types.h>
+/*
+ * The tools build may be on a system without O_DIRECTORY. So we need to
+ * explicitly include sys/fcntl.h and check for O_DIRECTORY and if not present,
+ * use the default of it being zero.
+ */
+#include <sys/fcntl.h>
+#ifndef O_DIRECTORY
+#define O_DIRECTORY 0
+#endif
+
#define MAN_CONF_FILE "/etc/man.conf"
#define MANPATH_BASE "/usr/share/man"
#define MANPATH_DEFAULT "/usr/share/man:/usr/gnu/share/man"
#define UTF8_LOCALE "en_US.UTF-8"
#define EFTYPE EINVAL
-#define O_DIRECTORY 0
#define HAVE_CMSG_XPG42 0
#define HAVE_DIRENT_NAMLEN 0
#define HAVE_ENDIAN 1
diff --git a/usr/src/cmd/truss/codes.c b/usr/src/cmd/truss/codes.c
index de04009d59..88c67ea994 100644
--- a/usr/src/cmd/truss/codes.c
+++ b/usr/src/cmd/truss/codes.c
@@ -1962,7 +1962,7 @@ pathconfname(int code)
#define ALL_O_FLAGS \
(O_NDELAY|O_APPEND|O_SYNC|O_DSYNC|O_NONBLOCK|O_CREAT|O_TRUNC\
|O_EXCL|O_NOCTTY|O_LARGEFILE|O_RSYNC|O_XATTR|O_NOFOLLOW|O_NOLINKS\
- |O_CLOEXEC|FXATTRDIROPEN)
+ |O_CLOEXEC|O_DIRECTORY|FXATTRDIROPEN)
const char *
openarg(private_t *pri, int arg)
@@ -2022,6 +2022,8 @@ openarg(private_t *pri, int arg)
(void) strlcat(str, "|O_NOLINKS", sizeof (pri->code_buf));
if (arg & O_CLOEXEC)
(void) strlcat(str, "|O_CLOEXEC", sizeof (pri->code_buf));
+ if (arg & O_DIRECTORY)
+ (void) strlcat(str, "|O_DIRECTORY", sizeof (pri->code_buf));
if (arg & FXATTRDIROPEN)
(void) strlcat(str, "|FXATTRDIROPEN", sizeof (pri->code_buf));
diff --git a/usr/src/man/man2/open.2 b/usr/src/man/man2/open.2
index 3ad37a86c7..86e00e575a 100644
--- a/usr/src/man/man2/open.2
+++ b/usr/src/man/man2/open.2
@@ -47,7 +47,7 @@
.\" All Rights Reserved.
.\" Copyright 2015 Nexenta Systems, Inc. All rights reserved.
.\"
-.TH OPEN 2 "Feb 14, 2015"
+.TH OPEN 2 "Jan 20, 2020"
.SH NAME
open, openat \- open a file
.SH SYNOPSIS
@@ -176,6 +176,37 @@ whether the file is open for reading, writing or for both.
.sp
.ne 2
.na
+.B O_DIRECTORY
+.ad
+.sp .6
+.RS 4n
+Indicates that attempts to open
+.I path
+should fail unless
+.I path
+is a directory.
+If both
+.B O_CREAT
+and
+.B O_DIRECTORY
+are specified then the call will fail if it would result in a file being
+created.
+If a directory already exists at
+.I path
+then it will behave as if the
+.B O_DIRECTORY
+flag had not been present.
+If the
+.B O_EXCL
+and
+.B O_CREAT
+flags are specified, then the call will always fail as they imply a file
+should always be created.
+.RE
+
+.sp
+.ne 2
+.na
\fB\fBO_DSYNC\fR\fR
.ad
.sp .6
@@ -686,6 +717,14 @@ The maximum allowable number of files is currently open in the system.
The \fBO_CREAT\fR flag is not set and the named file does not exist; or the
\fBO_CREAT\fR flag is set and either the path prefix does not exist or the
\fIpath\fR argument points to an empty string.
+.sp
+The
+.B O_CREAT
+and
+.B O_DIRECTORY
+flags were both set and
+.I path
+did not point to a file.
.RE
.sp
@@ -747,6 +786,10 @@ A component of the path prefix is not a directory or a relative path was
supplied to \fBopenat()\fR, the \fBO_XATTR\fR flag was not supplied, and the
file descriptor does not refer to a directory. The \fBO_SEARCH\fR flag
was passed and \fIpath\fR does not refer to a directory.
+.sp
+The
+.B O_DIRECTORY
+flag was set and the file was not a directory.
.RE
.sp
diff --git a/usr/src/man/man3head/fcntl.h.3head b/usr/src/man/man3head/fcntl.h.3head
index fa75967763..3e272db601 100644
--- a/usr/src/man/man3head/fcntl.h.3head
+++ b/usr/src/man/man3head/fcntl.h.3head
@@ -43,7 +43,7 @@
.\" Copyright 1989 AT&T
.\" Copyright (c) 2008, Sun Microsystems, Inc. All Rights Reserved.
.\"
-.TH FCNTL.H 3HEAD "April 9, 2016"
+.TH FCNTL.H 3HEAD "January 20, 2020"
.SH NAME
fcntl.h, fcntl \- file control options
.SH SYNOPSIS
@@ -374,6 +374,15 @@ Create file if it does not exist.
.sp
.ne 2
.na
+.B O_DIRECTORY
+.ad
+.RS 12n
+Fail unless the path is a directory.
+.RE
+
+.sp
+.ne 2
+.na
\fB\fBO_EXCL\fR\fR
.ad
.RS 12n
@@ -426,6 +435,15 @@ Set append mode.
.sp
.ne 2
.na
+.B O_CLOEXEC
+.ad
+.RS 12n
+The file should be closed on any calls to \fBexec\fR(2).
+.RE
+
+.sp
+.ne 2
+.na
\fB\fBO_NDELAY\fR\fR
.ad
.RS 14n
diff --git a/usr/src/pkg/manifests/system-test-ostest.mf b/usr/src/pkg/manifests/system-test-ostest.mf
index 1c17f19792..07d6b57fc0 100644
--- a/usr/src/pkg/manifests/system-test-ostest.mf
+++ b/usr/src/pkg/manifests/system-test-ostest.mf
@@ -48,6 +48,8 @@ file path=opt/os-tests/tests/file-locking/runtests.64 mode=0555
$(i386_ONLY)file path=opt/os-tests/tests/i386/badseg mode=0555
$(i386_ONLY)file path=opt/os-tests/tests/i386/badseg_exec mode=0555
$(i386_ONLY)file path=opt/os-tests/tests/i386/ldt mode=0555
+file path=opt/os-tests/tests/odirectory.32 mode=0555
+file path=opt/os-tests/tests/odirectory.64 mode=0555
file path=opt/os-tests/tests/pf_key/acquire-compare mode=0555
file path=opt/os-tests/tests/pf_key/acquire-spray mode=0555
file path=opt/os-tests/tests/pf_key/eacq-enabler mode=0555
diff --git a/usr/src/test/libc-tests/cfg/symbols/fcntl_h.cfg b/usr/src/test/libc-tests/cfg/symbols/fcntl_h.cfg
index 92806885bc..0a359e92ce 100644
--- a/usr/src/test/libc-tests/cfg/symbols/fcntl_h.cfg
+++ b/usr/src/test/libc-tests/cfg/symbols/fcntl_h.cfg
@@ -42,6 +42,7 @@ value | O_RDWR | int | fcntl.h | POSIX+ SUS+
value | O_RSYNC | int | fcntl.h | XPG3+ POSIX-1993+
value | O_SYNC | int | fcntl.h | XPG3+ POSIX-1993+
value | O_WRONLY | int | fcntl.h | POSIX+ SUS+
+value | O_DIRECTORY | int | fcntl.h | -ALL SUSv4+
#
# Functions
diff --git a/usr/src/test/os-tests/runfiles/default.run b/usr/src/test/os-tests/runfiles/default.run
index af99f6efd1..46c8bf68dd 100644
--- a/usr/src/test/os-tests/runfiles/default.run
+++ b/usr/src/test/os-tests/runfiles/default.run
@@ -26,6 +26,9 @@ outputdir = /var/tmp/test_results
user = root
tests = ['poll_test', 'epoll_test']
+[/opt/os-tests/tests/odirectory.32]
+[/opt/os-tests/tests/odirectory.64]
+
[/opt/os-tests/tests/secflags]
user = root
tests = ['secflags_aslr',
diff --git a/usr/src/test/os-tests/tests/Makefile b/usr/src/test/os-tests/tests/Makefile
index aab4828541..53bfd1b5a1 100644
--- a/usr/src/test/os-tests/tests/Makefile
+++ b/usr/src/test/os-tests/tests/Makefile
@@ -29,4 +29,59 @@ SUBDIRS = \
stress \
$(SUBDIRS_$(MACH))
-include $(SRC)/test/Makefile.com
+PROGS = \
+ odirectory
+
+CPPFLAGS += -D_REENTRANT
+PROGS32 = $(PROGS:%=%.32)
+PROGS64 = $(PROGS:%=%.64)
+
+ROOTOPTDIR = $(ROOT)/opt/os-tests/tests
+ROOTOPTPROGS = $(PROGS32:%=$(ROOTOPTDIR)/%) \
+ $(PROGS64:%=$(ROOTOPTDIR)/%) \
+ $(SCRIPTS:%=$(ROOTOPTDIR)/%)
+
+odirectory.32 := LDLIBS += -lsocket
+odirectory.64 := LDLIBS64 += -lsocket
+
+include $(SRC)/cmd/Makefile.cmd
+
+all := TARGET = all
+install := TARGET = install
+clean := TARGET = clean
+clobber := TARGET = clobber
+
+.KEEP_STATE:
+
+install: $(SUBDIRS) $(ROOTOPTPROGS)
+
+all: $(SUBDIRS) $(PROGS32) $(PROGS64)
+
+clean: $(SUBDIRS)
+
+$(ROOTOPTPROGS): $(PROGS32) $(PROGS64) $(ROOTOPTDIR)
+
+$(ROOTOPTDIR):
+ $(INS.dir)
+
+$(ROOTOPTDIR)/%: %
+ $(INS.file)
+
+$(ROOTOPTDIR)/%: %.ksh
+ $(INS.rename)
+
+%.64: %.c
+ $(LINK64.c) -o $@ $< $(LDLIBS64)
+ $(POST_PROCESS)
+
+%.32: %.c
+ $(LINK.c) -o $@ $< $(LDLIBS)
+ $(POST_PROCESS)
+
+clobber: $(SUBDIRS)
+ $(RM) $(PROGS32) $(PROGS64)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
diff --git a/usr/src/test/os-tests/tests/odirectory.c b/usr/src/test/os-tests/tests/odirectory.c
new file mode 100644
index 0000000000..f818c6433f
--- /dev/null
+++ b/usr/src/test/os-tests/tests/odirectory.c
@@ -0,0 +1,247 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2020 Robert Mustacchi
+ */
+
+/*
+ * Test different O_DIRECTORY open cases.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <err.h>
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <door.h>
+#include <stropts.h>
+#include <sys/socket.h>
+
+static uint_t odir_failures;
+static char odir_fpath[PATH_MAX];
+static char odir_dpath[PATH_MAX];
+static char odir_doorpath[PATH_MAX];
+static char odir_enoent[PATH_MAX];
+static char odir_udspath[PATH_MAX];
+static int odir_did = -1;
+static int odir_uds = -1;
+
+static void
+odir_test_one(const char *test, const char *path, int flags, int err)
+{
+ int fd = open(path, flags | O_DIRECTORY | O_RDONLY, 0644);
+ if (fd >= 0) {
+ (void) close(fd);
+ if (err != 0) {
+ odir_failures++;
+ warnx("TEST FAILED: %s: opened %s, but expected error: "
+ "%d", test, path, err);
+ }
+ } else {
+ if (err == 0) {
+ odir_failures++;
+ warnx("TEST FAILED: %s: failed to open %s, error: %d",
+ test, path, err);
+ } else if (err != errno) {
+ odir_failures++;
+ warnx("TEST FAILED: %s: wrong error for path %s, "
+ "found %d, expected %d", test, path, errno, err);
+ }
+ }
+}
+
+static void
+odir_door_server(void *cookie, char *argp, size_t arg_size, door_desc_t *dp,
+ uint_t ndesc)
+{
+ (void) door_return(NULL, 0, NULL, 0);
+}
+
+static boolean_t
+odir_setup(void)
+{
+ int fd;
+ struct stat st;
+ struct sockaddr_un un;
+ pid_t pid = getpid();
+
+ (void) snprintf(odir_fpath, sizeof (odir_fpath),
+ "/tmp/odir.%d.file", pid);
+ if ((fd = creat(odir_fpath, 0644)) < 0) {
+ warn("failed to create temp file %s", odir_fpath);
+ odir_fpath[0] = '\0';
+ return (B_FALSE);
+ }
+ (void) close(fd);
+
+ (void) snprintf(odir_dpath, sizeof (odir_dpath),
+ "/tmp/odir.%d.dir", pid);
+ if (mkdir(odir_dpath, 0755) != 0) {
+ warn("failed to create temp directory %s", odir_dpath);
+ odir_dpath[0] = '\0';
+ return (B_FALSE);
+ }
+
+ odir_did = door_create(odir_door_server, NULL, 0);
+ if (odir_did == -1) {
+ warnx("failed to create door");
+ return (B_FALSE);
+ }
+ (void) snprintf(odir_doorpath, sizeof (odir_doorpath),
+ "/tmp/odir.%d.door", pid);
+ if ((fd = creat(odir_doorpath, 0644)) < 0) {
+ warn("failed to create %s", odir_doorpath);
+ odir_doorpath[0] = '\0';
+ return (B_FALSE);
+ }
+ (void) close(fd);
+ if (fattach(odir_did, odir_doorpath) != 0) {
+ warn("failed to attach door to %s", odir_doorpath);
+ (void) unlink(odir_doorpath);
+ odir_doorpath[0] = '\0';
+ return (B_FALSE);
+ }
+
+ (void) snprintf(odir_enoent, sizeof (odir_enoent),
+ "/tmp/odir.%d.enoent", pid);
+ if (stat(odir_enoent, &st) == 0) {
+ warnx("somehow random file %s exists!", odir_enoent);
+ }
+
+ odir_uds = socket(PF_UNIX, SOCK_STREAM, 0);
+ if (odir_uds == -1) {
+ warn("failed to create UDS");
+ return (B_FALSE);
+ }
+ (void) snprintf(odir_udspath, sizeof (odir_udspath),
+ "/tmp/odir.%d.uds", pid);
+ (void) memset(&un, '\0', sizeof (un));
+ un.sun_family = AF_UNIX;
+ if (strlcpy(un.sun_path, odir_udspath, sizeof (un.sun_path)) >=
+ sizeof (un.sun_path)) {
+ warnx("%s overflows AF_UNIX path", odir_udspath);
+ odir_udspath[0] = '\0';
+ return (B_FALSE);
+ }
+
+ if (bind(odir_uds, (struct sockaddr *)&un, SUN_LEN(&un)) != 0) {
+ warn("failed to bind %s", odir_udspath);
+ odir_udspath[0] = '\0';
+ return (B_FALSE);
+ }
+
+ if (listen(odir_uds, 1) != 0) {
+ warn("failed to listen on %s", odir_udspath);
+ return (B_FALSE);
+ }
+
+ return (B_TRUE);
+}
+
+static void
+odir_verify_enoent(void)
+{
+ struct stat st;
+
+ if (stat(odir_enoent, &st) == 0) {
+ warnx("TEST FAILED: %s was created", odir_enoent);
+ odir_failures++;
+ } else if (errno != ENOENT) {
+ warn("TEST FAILED: stat on %s failed", odir_enoent);
+ odir_failures++;
+ }
+}
+
+static void
+odir_cleanup(void)
+{
+ if (odir_udspath[0] != '\0') {
+ if (unlink(odir_udspath) != 0) {
+ warn("failed to unlink %s", odir_udspath);
+ }
+ }
+
+ if (odir_uds != -1) {
+ if (close(odir_uds) != 0) {
+ warn("failed to close UDS");
+ }
+ }
+
+ if (odir_doorpath[0] != '\0') {
+ if (fdetach(odir_doorpath) != 0) {
+ warn("failed to detach door %s", odir_doorpath);
+ }
+ }
+
+ if (odir_did != -1) {
+ if (door_revoke(odir_did) != 0) {
+ warn("failed to revoke door");
+ }
+ }
+
+ if (odir_dpath[0] != '\0') {
+ if (rmdir(odir_dpath) != 0) {
+ warn("failed to clean up %s", odir_dpath);
+ }
+ }
+
+ if (odir_fpath[0] != '\0') {
+ if (unlink(odir_fpath) != 0) {
+ warn("failed to clean up %s", odir_fpath);
+ }
+ }
+}
+
+int
+main(void)
+{
+ if (!odir_setup()) {
+ odir_cleanup();
+ return (EXIT_FAILURE);
+ }
+
+ odir_test_one("regular file", odir_fpath, 0, ENOTDIR);
+ odir_test_one("directory", odir_dpath, 0, 0);
+ odir_test_one("character device", "/dev/null", 0, ENOTDIR);
+ odir_test_one("door server", odir_doorpath, 0, ENOTDIR);
+ odir_test_one("missing file", odir_enoent, 0, ENOENT);
+ odir_test_one("UDS", odir_udspath, 0, ENOTDIR);
+
+ odir_test_one("O_CREAT | O_DIRECTORY on a regular file", odir_fpath,
+ O_CREAT, ENOTDIR);
+ odir_test_one("O_CREAT | O_DIRECTORY | O_EXCL on a regular file",
+ odir_fpath, O_CREAT | O_EXCL, EINVAL);
+
+ odir_test_one("O_CREAT | O_DIRECTORY on a directory", odir_dpath,
+ O_CREAT, 0);
+ odir_test_one("O_CREAT | O_DIRECTORY | O_EXCL on a directory",
+ odir_dpath, O_CREAT | O_EXCL, EINVAL);
+
+ odir_test_one("O_CREAT | O_DIRECTORY on a missing file", odir_enoent,
+ O_CREAT, ENOENT);
+ odir_verify_enoent();
+ odir_test_one("O_CREAT | O_DIRECTORY | O_EXCL on a missing file",
+ odir_enoent, O_CREAT | O_EXCL, EINVAL);
+ odir_verify_enoent();
+
+ odir_cleanup();
+ if (odir_failures > 0) {
+ warnx("%u tests failed", odir_failures);
+ }
+
+ return (odir_failures > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
+}
diff --git a/usr/src/uts/common/fs/vnode.c b/usr/src/uts/common/fs/vnode.c
index eeb34524d9..afdb3baf40 100644
--- a/usr/src/uts/common/fs/vnode.c
+++ b/usr/src/uts/common/fs/vnode.c
@@ -967,6 +967,7 @@ vn_openat(
int estale_retry = 0;
struct shrlock shr;
struct shr_locowner shr_own;
+ boolean_t create;
mode = 0;
accessflags = 0;
@@ -986,8 +987,31 @@ vn_openat(
if (filemode & FAPPEND)
accessflags |= V_APPEND;
+ /*
+ * We need to handle the case of FCREAT | FDIRECTORY and the case of
+ * FEXCL. If all three are specified, then we always fail because we
+ * cannot create a directory through this interface and FEXCL says we
+ * need to fail the request if we can't create it. If, however, only
+ * FCREAT | FDIRECTORY are specified, then we can treat this as the case
+ * of opening a file that already exists. If it exists, we can do
+ * something and if not, we fail. Effectively FCREAT | FDIRECTORY is
+ * treated as FDIRECTORY.
+ */
+ if ((filemode & (FCREAT | FDIRECTORY | FEXCL)) ==
+ (FCREAT | FDIRECTORY | FEXCL)) {
+ return (EINVAL);
+ }
+
+ if ((filemode & (FCREAT | FDIRECTORY)) == (FCREAT | FDIRECTORY)) {
+ create = B_FALSE;
+ } else if ((filemode & FCREAT) != 0) {
+ create = B_TRUE;
+ } else {
+ create = B_FALSE;
+ }
+
top:
- if (filemode & FCREAT) {
+ if (create) {
enum vcexcl excl;
/*
@@ -1084,11 +1108,13 @@ top:
*/
if (error = VOP_ACCESS(vp, mode, accessflags, CRED(), NULL))
goto out;
+
/*
- * Require FSEARCH to return a directory.
- * Require FEXEC to return a regular file.
+ * Require FSEARCH and FDIRECTORY to return a directory. Require
+ * FEXEC to return a regular file.
*/
- if ((filemode & FSEARCH) && vp->v_type != VDIR) {
+ if ((filemode & (FSEARCH|FDIRECTORY)) != 0 &&
+ vp->v_type != VDIR) {
error = ENOTDIR;
goto out;
}
diff --git a/usr/src/uts/common/sys/fcntl.h b/usr/src/uts/common/sys/fcntl.h
index 3167fd4a1d..cf55ebbf2a 100644
--- a/usr/src/uts/common/sys/fcntl.h
+++ b/usr/src/uts/common/sys/fcntl.h
@@ -86,6 +86,9 @@ extern "C" {
#define O_NOFOLLOW 0x20000 /* don't follow symlinks */
#define O_NOLINKS 0x40000 /* don't allow multiple hard links */
#define O_CLOEXEC 0x800000 /* set the close-on-exec flag */
+#if !defined(_STRICT_SYMBOLS) || defined(_XPG7)
+#define O_DIRECTORY 0x1000000 /* fail if not a directory */
+#endif
/*
* fcntl(2) requests
@@ -181,7 +184,7 @@ extern "C" {
#endif /* _STRICT_SYMBOLS */
#endif /* _LP64 || _FILE_OFFSET_BITS == 32 */
-#if defined(_LARGEFILE64_SOURCE)
+#if defined(_LARGEFILE64_SOURCE)
#if !defined(_LP64) || defined(_KERNEL)
/*
@@ -260,7 +263,7 @@ typedef struct flock32 {
/* transitional large file interface version */
-#if defined(_LARGEFILE64_SOURCE)
+#if defined(_LARGEFILE64_SOURCE)
typedef struct flock64 {
short l_type;
diff --git a/usr/src/uts/common/sys/file.h b/usr/src/uts/common/sys/file.h
index ec0741fe08..36e14f0c7a 100644
--- a/usr/src/uts/common/sys/file.h
+++ b/usr/src/uts/common/sys/file.h
@@ -118,6 +118,7 @@ typedef struct fpollinfo {
#define FEXEC 0x400000 /* O_EXEC = 0x400000 */
#define FCLOEXEC 0x800000 /* O_CLOEXEC = 0x800000 */
+#define FDIRECTORY 0x1000000 /* O_DIRECTORY = 0x1000000 */
#if defined(_KERNEL) || defined(_FAKE_KERNEL)