| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #include <config.h> |
| |
|
| | |
| | #include <sys/socket.h> |
| |
|
| | #include <errno.h> |
| | #include <fcntl.h> |
| | #include "binary-io.h" |
| | #if GNULIB_MSVC_NOTHROW |
| | # include "msvc-nothrow.h" |
| | #else |
| | # include <io.h> |
| | #endif |
| |
|
| | #ifndef SOCK_CLOEXEC |
| | # define SOCK_CLOEXEC 0 |
| | #endif |
| | #ifndef SOCK_NONBLOCK |
| | # define SOCK_NONBLOCK 0 |
| | #endif |
| |
|
| | int |
| | accept4 (int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) |
| | { |
| | int fd; |
| |
|
| | #if HAVE_DECL_ACCEPT4 |
| | # undef accept4 |
| | |
| | |
| | { |
| | |
| | static int have_accept4_really; |
| | if (have_accept4_really >= 0) |
| | { |
| | int result = accept4 (sockfd, addr, addrlen, flags); |
| | if (!(result < 0 && errno == ENOSYS)) |
| | { |
| | have_accept4_really = 1; |
| | return result; |
| | } |
| | have_accept4_really = -1; |
| | } |
| | } |
| | #endif |
| |
|
| | |
| | if ((flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK | O_TEXT | O_BINARY)) != 0) |
| | { |
| | errno = EINVAL; |
| | return -1; |
| | } |
| |
|
| | fd = accept (sockfd, addr, addrlen); |
| | if (fd < 0) |
| | return -1; |
| |
|
| | #if SOCK_CLOEXEC |
| | # if defined _WIN32 && ! defined __CYGWIN__ |
| | |
| | if (flags & SOCK_CLOEXEC) |
| | { |
| | HANDLE curr_process = GetCurrentProcess (); |
| | HANDLE old_handle = (HANDLE) _get_osfhandle (fd); |
| | HANDLE new_handle; |
| | int nfd; |
| |
|
| | if (!DuplicateHandle (curr_process, |
| | old_handle, |
| | curr_process, |
| | (PHANDLE) &new_handle, |
| | (DWORD) 0, |
| | FALSE, |
| | DUPLICATE_SAME_ACCESS)) |
| | { |
| | close (fd); |
| | errno = EBADF; |
| | return -1; |
| | } |
| |
|
| | |
| | |
| | close (fd); |
| | nfd = _open_osfhandle ((intptr_t) new_handle, |
| | O_NOINHERIT | (flags & (O_TEXT | O_BINARY))); |
| | if (nfd < 0) |
| | { |
| | CloseHandle (new_handle); |
| | return -1; |
| | } |
| | return nfd; |
| | } |
| | # else |
| | |
| | if (flags & SOCK_CLOEXEC) |
| | { |
| | int fcntl_flags; |
| |
|
| | if ((fcntl_flags = fcntl (fd, F_GETFD, 0)) < 0 |
| | || fcntl (fd, F_SETFD, fcntl_flags | FD_CLOEXEC) == -1) |
| | { |
| | int saved_errno = errno; |
| | close (fd); |
| | errno = saved_errno; |
| | return -1; |
| | } |
| | } |
| | # endif |
| | #endif |
| |
|
| | #if SOCK_NONBLOCK |
| | if (flags & SOCK_NONBLOCK) |
| | { |
| | int fcntl_flags; |
| |
|
| | if ((fcntl_flags = fcntl (fd, F_GETFL, 0)) < 0 |
| | || fcntl (fd, F_SETFL, fcntl_flags | O_NONBLOCK) == -1) |
| | { |
| | int saved_errno = errno; |
| | close (fd); |
| | errno = saved_errno; |
| | return -1; |
| | } |
| | } |
| | #endif |
| |
|
| | #if O_BINARY |
| | if (flags & O_BINARY) |
| | set_binary_mode (fd, O_BINARY); |
| | else if (flags & O_TEXT) |
| | set_binary_mode (fd, O_TEXT); |
| | #endif |
| |
|
| | return fd; |
| | } |
| |
|