summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changes4
-rw-r--r--otherlibs/unix/open.c38
-rw-r--r--otherlibs/unix/unix.ml1
-rw-r--r--otherlibs/unix/unix.mli3
-rw-r--r--otherlibs/unix/unixLabels.mli2
-rw-r--r--otherlibs/win32unix/open.c21
-rw-r--r--otherlibs/win32unix/unix.ml1
7 files changed, 56 insertions, 14 deletions
diff --git a/Changes b/Changes
index e673d5e71..771120afb 100644
--- a/Changes
+++ b/Changes
@@ -66,6 +66,10 @@ Standard library:
- Add optimized composition operators |> and @@ in Pervasives
+Other libraries:
+- PR#5568: add O_CLOEXEC flag to Unix.openfile, so that the returned
+ file descriptor is created in close-on-exec mode
+
Runtime system:
* PR#6019: more efficient implementation of caml_modify() and caml_initialize().
The new implementations are less lenient than the old ones: now,
diff --git a/otherlibs/unix/open.c b/otherlibs/unix/open.c
index 097a0455b..ecee01389 100644
--- a/otherlibs/unix/open.c
+++ b/otherlibs/unix/open.c
@@ -17,6 +17,9 @@
#include <signals.h>
#include "unixsupport.h"
#include <string.h>
+#ifdef HAS_UNISTD
+#include <unistd.h>
+#endif
#include <fcntl.h>
#ifndef O_NONBLOCK
@@ -31,16 +34,31 @@
#ifndef O_RSYNC
#define O_RSYNC 0
#endif
+#ifndef O_CLOEXEC
+#define NEED_CLOEXEC_EMULATION
+#define O_CLOEXEC 0
+#endif
-static int open_flag_table[] = {
+static int open_flag_table[14] = {
O_RDONLY, O_WRONLY, O_RDWR, O_NONBLOCK, O_APPEND, O_CREAT, O_TRUNC, O_EXCL,
- O_NOCTTY, O_DSYNC, O_SYNC, O_RSYNC, 0
+ O_NOCTTY, O_DSYNC, O_SYNC, O_RSYNC,
+ 0, /* O_SHARE_DELETE, Windows-only */
+ O_CLOEXEC
+};
+
+#ifdef NEED_CLOEXEC_EMULATION
+static int open_cloexec_table[14] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0,
+ 1
};
+#endif
CAMLprim value unix_open(value path, value flags, value perm)
{
CAMLparam3(path, flags, perm);
- int ret, cv_flags;
+ int fd, cv_flags;
char * p;
cv_flags = convert_flag_list(flags, open_flag_table);
@@ -48,9 +66,17 @@ CAMLprim value unix_open(value path, value flags, value perm)
strcpy(p, String_val(path));
/* open on a named FIFO can block (PR#1533) */
enter_blocking_section();
- ret = open(p, cv_flags, Int_val(perm));
+ fd = open(p, cv_flags, Int_val(perm));
leave_blocking_section();
stat_free(p);
- if (ret == -1) uerror("open", path);
- CAMLreturn (Val_int(ret));
+ if (fd == -1) uerror("open", path);
+#if defined(NEED_CLOEXEC_EMULATION) && defined(FD_CLOEXEC)
+ if (convert_flag_list(flags, open_cloexec_table) != 0) {
+ int flags = fcntl(fd, F_GETFD, 0);
+ if (flags == -1 ||
+ fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
+ uerror("open", path);
+ }
+#endif
+ CAMLreturn (Val_int(fd));
}
diff --git a/otherlibs/unix/unix.ml b/otherlibs/unix/unix.ml
index 8a69ca7b4..a89783146 100644
--- a/otherlibs/unix/unix.ml
+++ b/otherlibs/unix/unix.ml
@@ -227,6 +227,7 @@ type open_flag =
| O_SYNC
| O_RSYNC
| O_SHARE_DELETE
+ | O_CLOEXEC
type file_perm = int
diff --git a/otherlibs/unix/unix.mli b/otherlibs/unix/unix.mli
index a9b551041..6c4202246 100644
--- a/otherlibs/unix/unix.mli
+++ b/otherlibs/unix/unix.mli
@@ -242,6 +242,9 @@ type open_flag =
O_SYNC/O_DSYNC) *)
| O_SHARE_DELETE (** Windows only: allow the file to be deleted
while still open *)
+ | O_CLOEXEC (** Set the close-on-exec flag on the
+ descriptor returned by {!openfile} *)
+
(** The flags to {!Unix.openfile}. *)
diff --git a/otherlibs/unix/unixLabels.mli b/otherlibs/unix/unixLabels.mli
index 91636c6a8..7494d4f7b 100644
--- a/otherlibs/unix/unixLabels.mli
+++ b/otherlibs/unix/unixLabels.mli
@@ -239,6 +239,8 @@ type open_flag = Unix.open_flag =
| O_SYNC (** Writes complete as `Synchronised I/O file integrity completion' *)
| O_RSYNC (** Reads complete as writes (depending on O_SYNC/O_DSYNC) *)
| O_SHARE_DELETE (** Windows only: allow the file to be deleted while still open *)
+ | O_CLOEXEC (** Set the close-on-exec flag on the
+ descriptor returned by {!openfile} *)
(** The flags to {!UnixLabels.openfile}. *)
diff --git a/otherlibs/win32unix/open.c b/otherlibs/win32unix/open.c
index 40ea34b63..a2ffa4e1e 100644
--- a/otherlibs/win32unix/open.c
+++ b/otherlibs/win32unix/open.c
@@ -16,22 +16,26 @@
#include "unixsupport.h"
#include <fcntl.h>
-static int open_access_flags[13] = {
+static int open_access_flags[14] = {
GENERIC_READ, GENERIC_WRITE, GENERIC_READ|GENERIC_WRITE,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
-static int open_create_flags[13] = {
- 0, 0, 0, 0, 0, O_CREAT, O_TRUNC, O_EXCL, 0, 0, 0, 0, 0
+static int open_create_flags[14] = {
+ 0, 0, 0, 0, 0, O_CREAT, O_TRUNC, O_EXCL, 0, 0, 0, 0, 0, 0
};
-static int open_share_flags[13] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FILE_SHARE_DELETE
+static int open_share_flags[14] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FILE_SHARE_DELETE, 0
+};
+
+static int open_cloexec_flags[14] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
};
CAMLprim value unix_open(value path, value flags, value perm)
{
- int fileaccess, createflags, fileattrib, filecreate, sharemode;
+ int fileaccess, createflags, fileattrib, filecreate, sharemode, cloexec;
SECURITY_ATTRIBUTES attr;
HANDLE h;
@@ -55,9 +59,10 @@ CAMLprim value unix_open(value path, value flags, value perm)
else
fileattrib = FILE_ATTRIBUTE_NORMAL;
+ cloexec = convert_flag_list(flags, open_cloexec_flags);
attr.nLength = sizeof(attr);
attr.lpSecurityDescriptor = NULL;
- attr.bInheritHandle = TRUE;
+ attr.bInheritHandle = cloexec ? FALSE : TRUE;
h = CreateFile(String_val(path), fileaccess,
sharemode, &attr,
diff --git a/otherlibs/win32unix/unix.ml b/otherlibs/win32unix/unix.ml
index a8a3dcc2a..cff003994 100644
--- a/otherlibs/win32unix/unix.ml
+++ b/otherlibs/win32unix/unix.ml
@@ -169,6 +169,7 @@ type open_flag =
| O_SYNC
| O_RSYNC
| O_SHARE_DELETE
+ | O_CLOEXEC
type file_perm = int