1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
commit f3d451b81c4caa8cce7f55af6463ec685e79e227
Author: Gerd Stolpmann <gerd@gerd-stolpmann.de>
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 <<EOF >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
|