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
|
/*******************************************************************************/
/* Permission is hereby granted, free of charge, to any person or organization */
/* obtaining a copy of the software and accompanying documentation covered by */
/* this license (the "Software") to use, reproduce, display, distribute, */
/* execute, and transmit the Software, and to prepare derivative works of the */
/* Software, and to permit third-parties to whom the Software is furnished to */
/* do so, all subject to the following: */
/* */
/* The copyright notices in the Software and this entire statement, including */
/* the above license grant, this restriction and the following disclaimer, */
/* must be included in all copies of the Software, in whole or in part, and */
/* all derivative works of the Software, unless such copies or derivative */
/* works are solely in the form of machine-executable object code generated by */
/* a source language processor. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
/* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT */
/* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE */
/* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, */
/* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER */
/* DEALINGS IN THE SOFTWARE. */
/*******************************************************************************/
#include <config.h>
#include <lfp/socket.h>
#include <lfp/fcntl.h>
#include <lfp/unistd.h>
int lfp_socket(int domain, int type, int protocol, uint64_t flags)
{
#if defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK)
return socket(domain,
type | ((flags & O_CLOEXEC) ? SOCK_CLOEXEC : 0) \
| ((flags & O_NONBLOCK) ? SOCK_NONBLOCK : 0),
protocol);
#else
int fd = socket(domain, type, protocol);
if (fd < 0) { goto error_return; }
if (((flags & O_CLOEXEC) && (lfp_set_fd_cloexec(fd, true) < 0)) || \
((flags & O_NONBLOCK) && (lfp_set_fd_nonblock(fd, true) < 0))) {
goto error_close;
}
return fd;
error_close:
close(fd);
error_return:
return -1;
#endif
}
int lfp_accept(int sockfd,
struct sockaddr *addr,
socklen_t *addrlen,
uint64_t flags)
{
// FIXME: This branch requires that SOCK_CLOEXEC and SOCK_NONBLOCK be
// defined when accept4(2) is present. Should we add an Autoconf check ?
#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK)
return accept4(sockfd, addr, addrlen,
((flags & O_CLOEXEC) ? SOCK_CLOEXEC : 0) | \
((flags & O_NONBLOCK) ? SOCK_NONBLOCK : 0));
#else
int fd = accept(sockfd, addr, addrlen);
if (fd < 0) { goto error_return; }
if (((flags & O_CLOEXEC) && (lfp_set_fd_cloexec(fd, true) < 0)) || \
((flags & O_NONBLOCK) && (lfp_set_fd_nonblock(fd, true) < 0))) {
goto error_close;
}
return fd;
error_close:
close(fd);
error_return:
return -1;
#endif
}
struct cmsghdr* lfp_cmsg_firsthdr (struct msghdr* msgh)
{
return CMSG_FIRSTHDR(msgh);
}
struct cmsghdr* lfp_cmsg_nxthdr (struct msghdr* msgh, struct cmsghdr* cmsg)
{
return CMSG_NXTHDR(msgh, cmsg);
}
size_t lfp_cmsg_space (size_t length)
{
return CMSG_SPACE(length);
}
size_t lfp_cmsg_len (size_t length)
{
return CMSG_LEN(length);
}
void* lfp_cmsg_data (struct cmsghdr* cmsg)
{
return CMSG_DATA(cmsg);
}
|