Skip to content

Commit 3907e94

Browse files
committed
Check if O_CLOEXEC is defined before using it in open()
Previously we checked if SOCK_CLOEXEC was defined before using SOCK_CLOEXEC, but we continued to check for SOCK_CLOEXEC after we switched to using O_CLOEXEC. Also use fcntl(F_GETFD) before fcntl(F_SETFD) to comport with the Standard.
1 parent e98a004 commit 3907e94

File tree

1 file changed

+19
-11
lines changed

1 file changed

+19
-11
lines changed

ext/mysql2/client.c

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -170,23 +170,31 @@ static void *nogvl_connect(void *ptr) {
170170
*/
171171
static VALUE invalidate_fd(int clientfd)
172172
{
173-
#ifdef SOCK_CLOEXEC
173+
#ifdef O_CLOEXEC
174174
/* Atomically set CLOEXEC on the new FD in case another thread forks */
175175
int sockfd = open("/dev/null", O_RDWR | O_CLOEXEC);
176-
if (sockfd < 0) {
177-
/* Maybe SOCK_CLOEXEC is defined but not available on this kernel */
178-
int sockfd = open("/dev/null", O_RDWR);
179-
fcntl(sockfd, F_SETFD, FD_CLOEXEC);
180-
}
181176
#else
182-
/* Well we don't have SOCK_CLOEXEC, so just set FD_CLOEXEC quickly */
183-
int sockfd = open("/dev/null", O_RDWR);
184-
fcntl(sockfd, F_SETFD, FD_CLOEXEC);
177+
/* Well we don't have O_CLOEXEC, trigger the fallback code below */
178+
int sockfd = -1;
185179
#endif
186180

187181
if (sockfd < 0) {
188-
/*
189-
* Cannot raise here, because one or both of the following may be true:
182+
/* Either O_CLOEXEC wasn't defined at compile time, or it was defined at
183+
* compile time, but isn't available at run-time. So we'll just be quick
184+
* about setting FD_CLOEXEC now.
185+
*/
186+
int flags;
187+
sockfd = open("/dev/null", O_RDWR);
188+
flags = fcntl(sockfd, F_GETFD);
189+
/* Do the flags dance in case there are more defined flags in the future */
190+
if (flags != -1) {
191+
flags |= FD_CLOEXEC;
192+
fcntl(sockfd, F_SETFD, flags);
193+
}
194+
}
195+
196+
if (sockfd < 0) {
197+
/* Cannot raise here, because one or both of the following may be true:
190198
* a) we have no GVL (in C Ruby)
191199
* b) are running as a GC finalizer
192200
*/

0 commit comments

Comments
 (0)