Skip to content
Snippets Groups Projects
Commit 236e8efe authored by Henrik (Grubba) Grubbström's avatar Henrik (Grubba) Grubbström
Browse files

Runtime: Added check and fallback for accept4(2).

accept4(2) is a system call available on current Linux and many BSDs,
that allows for setting the close-on-exec and non-blocking flags
on the resulting fd.
parent 52cdd83b
No related branches found
No related tags found
No related merge requests found
...@@ -4510,6 +4510,7 @@ fi ...@@ -4510,6 +4510,7 @@ fi
AC_CHECK_FUNCS( \ AC_CHECK_FUNCS( \
_crypt \ _crypt \
poll \ poll \
accept4 \
closefrom \ closefrom \
crypt \ crypt \
fdwalk \ fdwalk \
......
...@@ -224,6 +224,22 @@ PMOD_EXPORT int set_close_on_exec(int fd, int which) ...@@ -224,6 +224,22 @@ PMOD_EXPORT int set_close_on_exec(int fd, int which)
#endif /* !HAVE_BROKEN_F_SETFD */ #endif /* !HAVE_BROKEN_F_SETFD */
} }
#ifndef HAVE_ACCEPT4
int accept4(int fd, struct sockaddr *addr, ACCEPT_SIZE_T *addrlen, int flags)
{
int fd = fd_accept(fd, addr, addrlen);
if (!flags || (fd < 0)) return fd;
if (((flags & SOCK_NONBLOCK) && (set_nonblocking(fd, 1) < 0)) ||
((flags & SOCK_CLOEXEC) && (set_close_on_exec(fd, 1) < 0))) {
int e = errno;
fd_close(fd);
errno = e;
return -1;
}
return fd;
}
#endif /* !HAVE_ACCEPT4 */
#endif /* !TESTING */ #endif /* !TESTING */
#ifdef TESTING #ifdef TESTING
......
...@@ -7,6 +7,33 @@ ...@@ -7,6 +7,33 @@
#ifndef FD_CONTROL_H #ifndef FD_CONTROL_H
#define FD_CONTROL_H #define FD_CONTROL_H
#ifndef HAVE_ACCEPT4
/* NB: The default values are compatible with Linux,
* but should work on other OSs as well, since
* accept4(2) is emulated by us anyway.
*/
enum pike_sock_flags {
#ifndef SOCK_CLOEXEC
#if !defined(SOCK_NONBLOCK) || (SOCK_NONBLOCK != 0x80000)
SOCK_CLOEXEC = 0x80000,
#else
/* Unlikely, but... */
SOCK_CLOEXEC = 0x40000,
#endif /* !SOCK_NONBLOCK || SOCK_NONBLOCK != 0x80000 */
#define SOCK_CLOEXEC SOCK_CLOEXEC
#endif
#ifndef SOCK_NONBLOCK
#if (SOCK_CLOEXEC != 0x00800)
SOCK_NONBLOCK = 0x00800,
#else
/* Unlikely, but... */
SOCK_NONBLOCK = 0x00400,
#endif
#define SOCK_NONBLOCK SOCK_NONBLOCK
#endif
};
#endif /* !HAVE_ACCEPT4 */
/* Prototypes begin here */ /* Prototypes begin here */
PMOD_EXPORT int set_nonblocking(int fd,int which); PMOD_EXPORT int set_nonblocking(int fd,int which);
PMOD_EXPORT int query_nonblocking(int fd); PMOD_EXPORT int query_nonblocking(int fd);
...@@ -16,6 +43,9 @@ PMOD_EXPORT int set_close_on_exec(int fd, int which); ...@@ -16,6 +43,9 @@ PMOD_EXPORT int set_close_on_exec(int fd, int which);
void do_close_on_exec(void); void do_close_on_exec(void);
void cleanup_close_on_exec(void); void cleanup_close_on_exec(void);
#endif /* HAVE_BROKEN_F_SETFD */ #endif /* HAVE_BROKEN_F_SETFD */
#ifndef HAVE_ACCEPT4
int accept4(int fd, struct sockaddr *addr, ACCEPT_SIZE_T *addrlen, int flags)
#endif /* !HAVE_ACCEPT4 */
/* Prototypes end here */ /* Prototypes end here */
#endif #endif
...@@ -90,6 +90,7 @@ typedef off_t PIKE_OFF_T; ...@@ -90,6 +90,7 @@ typedef off_t PIKE_OFF_T;
#define fd_socket(X,Y,Z) dmalloc_register_fd(debug_fd_socket((X),(Y),(Z))) #define fd_socket(X,Y,Z) dmalloc_register_fd(debug_fd_socket((X),(Y),(Z)))
#define fd_pipe(X) debug_fd_pipe( (X) DMALLOC_POS ) #define fd_pipe(X) debug_fd_pipe( (X) DMALLOC_POS )
#define fd_accept(X,Y,Z) dmalloc_register_fd(debug_fd_accept((X),(Y),(Z))) #define fd_accept(X,Y,Z) dmalloc_register_fd(debug_fd_accept((X),(Y),(Z)))
#define fd_accept4(X,Y,Z,F) dmalloc_register_fd(accept4((X),(Y),(Z),(F)))
#define fd_bind(fd,X,Y) debug_fd_bind(dmalloc_touch_fd(fd), (X), (Y)) #define fd_bind(fd,X,Y) debug_fd_bind(dmalloc_touch_fd(fd), (X), (Y))
#define fd_getsockopt(fd,X,Y,Z,Q) debug_fd_getsockopt(dmalloc_touch_fd(fd), (X),(Y),(Z),(Q)) #define fd_getsockopt(fd,X,Y,Z,Q) debug_fd_getsockopt(dmalloc_touch_fd(fd), (X),(Y),(Z),(Q))
...@@ -340,6 +341,7 @@ typedef off_t PIKE_OFF_T; ...@@ -340,6 +341,7 @@ typedef off_t PIKE_OFF_T;
#define fd_socket(X,Y,Z) dmalloc_register_fd(socket((X),(Y),(Z))) #define fd_socket(X,Y,Z) dmalloc_register_fd(socket((X),(Y),(Z)))
#define fd_pipe pipe /* FIXME */ #define fd_pipe pipe /* FIXME */
#define fd_accept(X,Y,Z) dmalloc_register_fd(accept((X),(Y),(Z))) #define fd_accept(X,Y,Z) dmalloc_register_fd(accept((X),(Y),(Z)))
#define fd_accept4(X,Y,Z,F) dmalloc_register_fd(accept4((X),(Y),(Z),(F)))
#define fd_bind(fd,X,Y) bind(dmalloc_touch_fd(fd), (X), (Y)) #define fd_bind(fd,X,Y) bind(dmalloc_touch_fd(fd), (X), (Y))
#define fd_getsockopt(fd,X,Y,Z,Q) getsockopt(dmalloc_touch_fd(fd), (X),(Y),(Z),(Q)) #define fd_getsockopt(fd,X,Y,Z,Q) getsockopt(dmalloc_touch_fd(fd), (X),(Y),(Z),(Q))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment