PR#5568: add O_CLOEXEC flag to Unix.openfile, so that the returned

file descriptor is created in close-on-exec mode.
(Reflecting commit r13961 on version/4.01)


git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@13962 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
master
Xavier Leroy 2013-08-01 12:14:57 +00:00
parent 5e78d37215
commit 1c58683353
7 changed files with 56 additions and 14 deletions

View File

@ -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,

View File

@ -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));
}

View File

@ -227,6 +227,7 @@ type open_flag =
| O_SYNC
| O_RSYNC
| O_SHARE_DELETE
| O_CLOEXEC
type file_perm = int

View File

@ -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}. *)

View File

@ -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}. *)

View File

@ -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,

View File

@ -169,6 +169,7 @@ type open_flag =
| O_SYNC
| O_RSYNC
| O_SHARE_DELETE
| O_CLOEXEC
type file_perm = int