commit f3d451b81c4caa8cce7f55af6463ec685e79e227 Author: Gerd Stolpmann Date: Sun Feb 26 21:04:49 2017 +0100 ocaml-4.05: support for O_KEEPEXEC diff --git a/code/src/netsys/Makefile b/code/src/netsys/Makefile index cbc1ce2..cb70a09 100644 --- a/code/src/netsys/Makefile +++ b/code/src/netsys/Makefile @@ -56,7 +56,7 @@ OCAMLC_OPTIONS_FOR_netsys_c_xdr.c = -ccopt -O OCAMLC_OPTIONS += $(STRING_OPTS) OCAMLOPT_OPTIONS += $(STRING_OPTS) -PP_OPTIONS = -pp "$(CPPO) $(DEF_O_SHARE_DELETE) $(DEF_O_CLOEXEC) $(PP_BYTES) $(PP_DEPRECATED)" +PP_OPTIONS = -pp "$(CPPO) $(DEF_O_SHARE_DELETE) $(DEF_O_CLOEXEC) $(DEF_O_KEEPEXEC) $(PP_BYTES) $(PP_DEPRECATED)" INSTALL_EXTRA += netsys_c_event.h $(OOH_OBJECT) diff --git a/code/src/netsys/configure b/code/src/netsys/configure index 1325843..f4dbc09 100755 --- a/code/src/netsys/configure +++ b/code/src/netsys/configure @@ -437,6 +437,21 @@ else echo "no" fi +###################################################################### + +printf "Checking for O_KEEPEXEC... " +mkdir -p tmp +cat <<_EOF_ >tmp/t.ml +let x = Unix.O_KEEPEXEC;; +_EOF_ + +def_o_keepexec="-D NO_O_KEEPEXEC" +if ocaml unix.cma tmp/t.ml >/dev/null 2>/dev/null; then + echo "yes" + def_o_keepexec="-D HAVE_O_KEEPEXEC" +else + echo "no" +fi ###################################################################### @@ -445,6 +460,7 @@ cat <Makefile.conf NETSYS_LINK_OPTIONS = $netsys_link_options DEF_O_SHARE_DELETE = $def_o_share_delete DEF_O_CLOEXEC = $def_o_cloexec +DEF_O_KEEPEXEC = $def_o_keepexec OOH_OBJECT = $def_ooh_object EOF diff --git a/code/src/netsys/netsys_c.c b/code/src/netsys/netsys_c.c index a8b16be..4c30873 100644 --- a/code/src/netsys/netsys_c.c +++ b/code/src/netsys/netsys_c.c @@ -448,32 +448,43 @@ static int at_flags_table[] = { #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[] = { 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_SHARE_DELETE */, O_CLOEXEC + O_NOCTTY, O_DSYNC, O_SYNC, O_RSYNC, + 0 /* O_SHARE_DELETE */, 0 /* O_CLOEXEC */, 0 /* O_KEEPEXEC */ }; -#ifdef NEED_CLOEXEC_EMULATION +enum { CLOEXEC = 1, KEEPEXEC = 2 }; + static int open_cloexec_table[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CLOEXEC, KEEPEXEC }; +#ifndef HAVE_O_KEEPEXEC +#define unix_cloexec_default 0 #endif + #endif CAMLprim value netsys_openat(value dirfd, value path, value flags, value perm) { #ifdef HAVE_AT CAMLparam4(dirfd, path, flags, perm); - int ret, cv_flags; + int ret, cv_flags, clo_flags, cloexec; char * p; /* shamelessly copied from ocaml distro */ cv_flags = convert_flag_list(flags, open_flag_table); + clo_flags = convert_flag_list(flags, open_cloexec_table); + if (clo_flags & CLOEXEC) + cloexec = 1; + else if (clo_flags & KEEPEXEC) + cloexec = 0; + else + cloexec = unix_cloexec_default; +#if defined(O_CLOEXEC) + if (cloexec) cv_flags |= O_CLOEXEC; +#endif p = stat_alloc(string_length(path) + 1); strcpy(p, String_val(path)); enter_blocking_section(); @@ -481,8 +492,8 @@ CAMLprim value netsys_openat(value dirfd, value path, value flags, value perm) leave_blocking_section(); stat_free(p); if (ret == -1) uerror("openat", path); -#if defined(NEED_CLOEXEC_EMULATION) && defined(FD_CLOEXEC) - if (convert_flag_list(flags, open_cloexec_table) != 0) { +#if !defined(O_CLOEXEC) + { int flags = fcntl(Int_val(dirfd), F_GETFD, 0); if (flags == -1 || fcntl(Int_val(dirfd), F_SETFD, flags | FD_CLOEXEC) == -1) uerror("openat", path); diff --git a/code/src/netsys/netsys_posix.ml b/code/src/netsys/netsys_posix.ml index 602ceae..3bf3e7c 100644 --- a/code/src/netsys/netsys_posix.ml +++ b/code/src/netsys/netsys_posix.ml @@ -715,6 +715,12 @@ type at_flag = AT_EACCESS | AT_SYMLINK_NOFOLLOW | AT_SYMLINK_FOLLOW | AT_REMOVEDIR (* The stubs assume these type definitions: *) +#ifdef HAVE_O_KEEPEXEC +type open_flag1 = Unix.open_flag = + O_RDONLY | O_WRONLY | O_RDWR | O_NONBLOCK | O_APPEND | O_CREAT | O_TRUNC + | O_EXCL | O_NOCTTY | O_DSYNC | O_SYNC | O_RSYNC | O_SHARE_DELETE + | O_CLOEXEC | O_KEEPEXEC +#else #ifdef HAVE_O_CLOEXEC type open_flag1 = Unix.open_flag = O_RDONLY | O_WRONLY | O_RDWR | O_NONBLOCK | O_APPEND | O_CREAT | O_TRUNC @@ -731,6 +737,7 @@ type open_flag1 = Unix.open_flag = | O_EXCL | O_NOCTTY | O_DSYNC | O_SYNC | O_RSYNC #endif #endif +#endif type access_permission1 = Unix.access_permission = R_OK | W_OK | X_OK | F_OK