Skip to content

Commit 999d65e

Browse files
committed
foo_cloexec() under PERL_GLOBAL_STRUCT_PRIVATE
Fix the various Perl_PerlSock_dup2_cloexec() type functions so that t/porting/liberl.a passes under -DPERL_GLOBAL_STRUCT_PRIVATE builds. In these builds it is forbidden to have any static variables, but each of these functions (via convoluted macros) has a static var called 'strategy' which records, for each function, whether a run-time probe has been done to determine the best way of achieving close-exec functionality, and the result. Replace them all with 'global' vars: PL_strategy_dup2 etc. NB these vars aren't thread-safe but it doesn't really matter, as the worst that can happen is for a redundant probe or two to be done before a suitable "don't probe any more" value is written to the var and seen by all the threads.
1 parent 4ef8bdf commit 999d65e

File tree

5 files changed

+90
-10
lines changed

5 files changed

+90
-10
lines changed

doio.c

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,10 @@ Perl_setfd_cloexec_or_inhexec_by_sysfdness(pTHX_ int fd)
112112
} while(0)
113113
#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC) && \
114114
defined(F_GETFD)
115-
enum { CLOEXEC_EXPERIMENT, CLOEXEC_AT_OPEN, CLOEXEC_AFTER_OPEN };
116-
# define DO_GENOPEN_EXPERIMENTING_CLOEXEC(TESTFD, GENOPEN_CLOEXEC, \
115+
enum { CLOEXEC_EXPERIMENT = 0, CLOEXEC_AT_OPEN, CLOEXEC_AFTER_OPEN };
116+
# define DO_GENOPEN_EXPERIMENTING_CLOEXEC(strategy, TESTFD, GENOPEN_CLOEXEC, \
117117
GENOPEN_NORMAL, GENSETFD_CLOEXEC) \
118118
do { \
119-
static int strategy = CLOEXEC_EXPERIMENT; \
120119
switch (strategy) { \
121120
case CLOEXEC_EXPERIMENT: default: { \
122121
int res = (GENOPEN_CLOEXEC), eno; \
@@ -149,7 +148,7 @@ enum { CLOEXEC_EXPERIMENT, CLOEXEC_AT_OPEN, CLOEXEC_AFTER_OPEN };
149148
} \
150149
} while(0)
151150
#else
152-
# define DO_GENOPEN_EXPERIMENTING_CLOEXEC(TESTFD, GENOPEN_CLOEXEC, \
151+
# define DO_GENOPEN_EXPERIMENTING_CLOEXEC(strategy, TESTFD, GENOPEN_CLOEXEC, \
153152
GENOPEN_NORMAL, GENSETFD_CLOEXEC) \
154153
DO_GENOPEN_THEN_CLOEXEC(GENOPEN_NORMAL, GENSETFD_CLOEXEC)
155154
#endif
@@ -160,10 +159,13 @@ enum { CLOEXEC_EXPERIMENT, CLOEXEC_AT_OPEN, CLOEXEC_AFTER_OPEN };
160159
DO_GENOPEN_THEN_CLOEXEC(fd = (ONEOPEN_NORMAL), \
161160
setfd_cloexec(fd)); \
162161
} while(0)
163-
#define DO_ONEOPEN_EXPERIMENTING_CLOEXEC(ONEOPEN_CLOEXEC, ONEOPEN_NORMAL) \
162+
#define DO_ONEOPEN_EXPERIMENTING_CLOEXEC(strategy, \
163+
ONEOPEN_CLOEXEC, ONEOPEN_NORMAL) \
164164
do { \
165165
int fd; \
166-
DO_GENOPEN_EXPERIMENTING_CLOEXEC(fd, fd = (ONEOPEN_CLOEXEC), \
166+
DO_GENOPEN_EXPERIMENTING_CLOEXEC(strategy, \
167+
fd, \
168+
fd = (ONEOPEN_CLOEXEC), \
167169
fd = (ONEOPEN_NORMAL), setfd_cloexec(fd)); \
168170
} while(0)
169171

@@ -174,9 +176,10 @@ enum { CLOEXEC_EXPERIMENT, CLOEXEC_AT_OPEN, CLOEXEC_AFTER_OPEN };
174176
} while(0)
175177
#define DO_PIPEOPEN_THEN_CLOEXEC(PIPEFD, PIPEOPEN_NORMAL) \
176178
DO_GENOPEN_THEN_CLOEXEC(PIPEOPEN_NORMAL, DO_PIPESETFD_CLOEXEC(PIPEFD))
177-
#define DO_PIPEOPEN_EXPERIMENTING_CLOEXEC(PIPEFD, PIPEOPEN_CLOEXEC, \
179+
#define DO_PIPEOPEN_EXPERIMENTING_CLOEXEC(strategy, PIPEFD, PIPEOPEN_CLOEXEC, \
178180
PIPEOPEN_NORMAL) \
179-
DO_GENOPEN_EXPERIMENTING_CLOEXEC((PIPEFD)[0], PIPEOPEN_CLOEXEC, \
181+
DO_GENOPEN_EXPERIMENTING_CLOEXEC(strategy, \
182+
(PIPEFD)[0], PIPEOPEN_CLOEXEC, \
180183
PIPEOPEN_NORMAL, DO_PIPESETFD_CLOEXEC(PIPEFD))
181184

182185
int
@@ -188,7 +191,9 @@ Perl_PerlLIO_dup_cloexec(pTHX_ int oldfd)
188191
* to extend it, so for the time being this just isn't available on
189192
* PERL_IMPLICIT_SYS builds.
190193
*/
194+
dVAR;
191195
DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
196+
PL_strategy_dup,
192197
fcntl(oldfd, F_DUPFD_CLOEXEC, 0),
193198
PerlLIO_dup(oldfd));
194199
#else
@@ -205,7 +210,9 @@ Perl_PerlLIO_dup2_cloexec(pTHX_ int oldfd, int newfd)
205210
* to extend it, so for the time being this just isn't available on
206211
* PERL_IMPLICIT_SYS builds.
207212
*/
213+
dVAR;
208214
DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
215+
PL_strategy_dup2,
209216
dup3(oldfd, newfd, O_CLOEXEC),
210217
PerlLIO_dup2(oldfd, newfd));
211218
#else
@@ -216,9 +223,11 @@ Perl_PerlLIO_dup2_cloexec(pTHX_ int oldfd, int newfd)
216223
int
217224
Perl_PerlLIO_open_cloexec(pTHX_ const char *file, int flag)
218225
{
226+
dVAR;
219227
PERL_ARGS_ASSERT_PERLLIO_OPEN_CLOEXEC;
220228
#if defined(O_CLOEXEC)
221229
DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
230+
PL_strategy_open,
222231
PerlLIO_open(file, flag | O_CLOEXEC),
223232
PerlLIO_open(file, flag));
224233
#else
@@ -229,9 +238,11 @@ Perl_PerlLIO_open_cloexec(pTHX_ const char *file, int flag)
229238
int
230239
Perl_PerlLIO_open3_cloexec(pTHX_ const char *file, int flag, int perm)
231240
{
241+
dVAR;
232242
PERL_ARGS_ASSERT_PERLLIO_OPEN3_CLOEXEC;
233243
#if defined(O_CLOEXEC)
234244
DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
245+
PL_strategy_open3,
235246
PerlLIO_open3(file, flag | O_CLOEXEC, perm),
236247
PerlLIO_open3(file, flag, perm));
237248
#else
@@ -242,9 +253,11 @@ Perl_PerlLIO_open3_cloexec(pTHX_ const char *file, int flag, int perm)
242253
int
243254
Perl_my_mkstemp_cloexec(char *templte)
244255
{
256+
dVAR;
245257
PERL_ARGS_ASSERT_MY_MKSTEMP_CLOEXEC;
246258
#if defined(O_CLOEXEC)
247259
DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
260+
PL_strategy_mkstemp,
248261
Perl_my_mkostemp(templte, O_CLOEXEC),
249262
Perl_my_mkstemp(templte));
250263
#else
@@ -256,14 +269,15 @@ Perl_my_mkstemp_cloexec(char *templte)
256269
int
257270
Perl_PerlProc_pipe_cloexec(pTHX_ int *pipefd)
258271
{
272+
dVAR;
259273
PERL_ARGS_ASSERT_PERLPROC_PIPE_CLOEXEC;
260274
/*
261275
* struct IPerlProc doesn't cover pipe2(), and there's no clear way
262276
* to extend it, so for the time being this just isn't available on
263277
* PERL_IMPLICIT_SYS builds.
264278
*/
265279
# if !defined(PERL_IMPLICIT_SYS) && defined(HAS_PIPE2) && defined(O_CLOEXEC)
266-
DO_PIPEOPEN_EXPERIMENTING_CLOEXEC(pipefd,
280+
DO_PIPEOPEN_EXPERIMENTING_CLOEXEC(PL_strategy_pipe, pipefd,
267281
pipe2(pipefd, O_CLOEXEC),
268282
PerlProc_pipe(pipefd));
269283
# else
@@ -278,7 +292,9 @@ int
278292
Perl_PerlSock_socket_cloexec(pTHX_ int domain, int type, int protocol)
279293
{
280294
# if defined(SOCK_CLOEXEC)
295+
dVAR;
281296
DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
297+
PL_strategy_socket,
282298
PerlSock_socket(domain, type | SOCK_CLOEXEC, protocol),
283299
PerlSock_socket(domain, type, protocol));
284300
# else
@@ -297,7 +313,9 @@ Perl_PerlSock_accept_cloexec(pTHX_ int listenfd, struct sockaddr *addr,
297313
* way to extend it, so for the time being this just isn't available
298314
* on PERL_IMPLICIT_SYS builds.
299315
*/
316+
dVAR;
300317
DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
318+
PL_strategy_accept,
301319
accept4(listenfd, addr, addrlen, SOCK_CLOEXEC),
302320
PerlSock_accept(listenfd, addr, addrlen));
303321
# else
@@ -314,9 +332,10 @@ int
314332
Perl_PerlSock_socketpair_cloexec(pTHX_ int domain, int type, int protocol,
315333
int *pairfd)
316334
{
335+
dVAR;
317336
PERL_ARGS_ASSERT_PERLSOCK_SOCKETPAIR_CLOEXEC;
318337
# ifdef SOCK_CLOEXEC
319-
DO_PIPEOPEN_EXPERIMENTING_CLOEXEC(pairfd,
338+
DO_PIPEOPEN_EXPERIMENTING_CLOEXEC(PL_strategy_socketpair, pairfd,
320339
PerlSock_socketpair(domain, type | SOCK_CLOEXEC, protocol, pairfd),
321340
PerlSock_socketpair(domain, type, protocol, pairfd));
322341
# else

embedvar.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,24 @@
460460
#define PL_Gsig_trapped (my_vars->Gsig_trapped)
461461
#define PL_sigfpe_saved (my_vars->Gsigfpe_saved)
462462
#define PL_Gsigfpe_saved (my_vars->Gsigfpe_saved)
463+
#define PL_strategy_accept (my_vars->Gstrategy_accept)
464+
#define PL_Gstrategy_accept (my_vars->Gstrategy_accept)
465+
#define PL_strategy_dup (my_vars->Gstrategy_dup)
466+
#define PL_Gstrategy_dup (my_vars->Gstrategy_dup)
467+
#define PL_strategy_dup2 (my_vars->Gstrategy_dup2)
468+
#define PL_Gstrategy_dup2 (my_vars->Gstrategy_dup2)
469+
#define PL_strategy_mkstemp (my_vars->Gstrategy_mkstemp)
470+
#define PL_Gstrategy_mkstemp (my_vars->Gstrategy_mkstemp)
471+
#define PL_strategy_open (my_vars->Gstrategy_open)
472+
#define PL_Gstrategy_open (my_vars->Gstrategy_open)
473+
#define PL_strategy_open3 (my_vars->Gstrategy_open3)
474+
#define PL_Gstrategy_open3 (my_vars->Gstrategy_open3)
475+
#define PL_strategy_pipe (my_vars->Gstrategy_pipe)
476+
#define PL_Gstrategy_pipe (my_vars->Gstrategy_pipe)
477+
#define PL_strategy_socket (my_vars->Gstrategy_socket)
478+
#define PL_Gstrategy_socket (my_vars->Gstrategy_socket)
479+
#define PL_strategy_socketpair (my_vars->Gstrategy_socketpair)
480+
#define PL_Gstrategy_socketpair (my_vars->Gstrategy_socketpair)
463481
#define PL_sv_placeholder (my_vars->Gsv_placeholder)
464482
#define PL_Gsv_placeholder (my_vars->Gsv_placeholder)
465483
#define PL_thr_key (my_vars->Gthr_key)

globvar.sym

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,15 @@ PL_sig_name
6666
PL_sig_num
6767
PL_simple
6868
PL_simple_bitmask
69+
PL_strategy_dup
70+
PL_strategy_dup2
71+
PL_strategy_open
72+
PL_strategy_open3
73+
PL_strategy_mkstemp
74+
PL_strategy_socket
75+
PL_strategy_accept
76+
PL_strategy_pipe
77+
PL_strategy_socketpair
6978
PL_strict_utf8_dfa_tab
7079
PL_subversion
7180
PL_utf8skip

perlapi.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,24 @@ END_EXTERN_C
207207
#define PL_sig_trapped (*Perl_Gsig_trapped_ptr(NULL))
208208
#undef PL_sigfpe_saved
209209
#define PL_sigfpe_saved (*Perl_Gsigfpe_saved_ptr(NULL))
210+
#undef PL_strategy_accept
211+
#define PL_strategy_accept (*Perl_Gstrategy_accept_ptr(NULL))
212+
#undef PL_strategy_dup
213+
#define PL_strategy_dup (*Perl_Gstrategy_dup_ptr(NULL))
214+
#undef PL_strategy_dup2
215+
#define PL_strategy_dup2 (*Perl_Gstrategy_dup2_ptr(NULL))
216+
#undef PL_strategy_mkstemp
217+
#define PL_strategy_mkstemp (*Perl_Gstrategy_mkstemp_ptr(NULL))
218+
#undef PL_strategy_open
219+
#define PL_strategy_open (*Perl_Gstrategy_open_ptr(NULL))
220+
#undef PL_strategy_open3
221+
#define PL_strategy_open3 (*Perl_Gstrategy_open3_ptr(NULL))
222+
#undef PL_strategy_pipe
223+
#define PL_strategy_pipe (*Perl_Gstrategy_pipe_ptr(NULL))
224+
#undef PL_strategy_socket
225+
#define PL_strategy_socket (*Perl_Gstrategy_socket_ptr(NULL))
226+
#undef PL_strategy_socketpair
227+
#define PL_strategy_socketpair (*Perl_Gstrategy_socketpair_ptr(NULL))
210228
#undef PL_sv_placeholder
211229
#define PL_sv_placeholder (*Perl_Gsv_placeholder_ptr(NULL))
212230
#undef PL_thr_key

perlvars.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,3 +321,19 @@ PERLVAR(G, user_prop_mutex, perl_mutex) /* Mutex for manipulating
321321
/* Everything that folds to a given character, for case insensitivity regex
322322
* matching */
323323
PERLVAR(G, utf8_foldclosures, SV *)
324+
325+
/* these record the best way to to perform certain IO operations while
326+
* atomically setting FD_CLOEXEC. On the first call, a probe is done
327+
* and the result recorded for use by subsequent calls.
328+
* In theory these variables aren't thread-safe, but the worst that can
329+
* happen is that two treads will both do an initial probe
330+
*/
331+
PERLVARI(G, strategy_dup, int, 0) /* doio.c */
332+
PERLVARI(G, strategy_dup2, int, 0) /* doio.c */
333+
PERLVARI(G, strategy_open, int, 0) /* doio.c */
334+
PERLVARI(G, strategy_open3, int, 0) /* doio.c */
335+
PERLVARI(G, strategy_mkstemp, int, 0) /* doio.c */
336+
PERLVARI(G, strategy_socket, int, 0) /* doio.c */
337+
PERLVARI(G, strategy_accept, int, 0) /* doio.c */
338+
PERLVARI(G, strategy_pipe, int, 0) /* doio.c */
339+
PERLVARI(G, strategy_socketpair, int, 0) /* doio.c */

0 commit comments

Comments
 (0)