}
#endif /* HAVE_FOPEN64 */
+static void swrap_inject_o_largefile(int *flags)
+{
+ (void)*flags; /* maybe unused */
+#if SIZE_MAX == 0xffffffffUL && defined(O_LARGEFILE)
+#ifdef O_PATH
+ if (((*flags) & O_PATH) == 0)
+#endif
+ {
+ *flags |= O_LARGEFILE;
+ }
+#endif
+}
+
static int libc_vopen(const char *pathname, int flags, va_list ap)
{
int mode = 0;
swrap_bind_symbol_all();
+ swrap_inject_o_largefile(&flags);
+
if (flags & O_CREAT) {
mode = va_arg(ap, int);
}
swrap_bind_symbol_all();
+ swrap_inject_o_largefile(&flags);
+
if (flags & O_CREAT) {
mode = va_arg(ap, int);
}
swrap_bind_symbol_all();
+ swrap_inject_o_largefile(&flags);
+
if (flags & O_CREAT) {
mode = va_arg(ap, int);
}
return 0;
}
+struct swrap_sockaddr_buf {
+ char str[128];
+};
+
+static const char *swrap_sockaddr_string(struct swrap_sockaddr_buf *buf,
+ const struct sockaddr *saddr)
+{
+ unsigned int port = 0;
+ char addr[64] = {0,};
+
+ switch (saddr->sa_family) {
+ case AF_INET: {
+ const struct sockaddr_in *in =
+ (const struct sockaddr_in *)(const void *)saddr;
+
+ port = ntohs(in->sin_port);
+
+ inet_ntop(saddr->sa_family,
+ &in->sin_addr,
+ addr, sizeof(addr));
+ break;
+ }
+#ifdef HAVE_IPV6
+ case AF_INET6: {
+ const struct sockaddr_in6 *in6 =
+ (const struct sockaddr_in6 *)(const void *)saddr;
+
+ port = ntohs(in6->sin6_port);
+
+ inet_ntop(saddr->sa_family,
+ &in6->sin6_addr,
+ addr, sizeof(addr));
+ break;
+ }
+#endif
+ default:
+ snprintf(addr, sizeof(addr),
+ "<Unknown address family %u>",
+ saddr->sa_family);
+ break;
+ }
+
+ snprintf(buf->str, sizeof(buf->str),
+ "addr[%s]/port[%u]",
+ addr, port);
+
+ return buf->str;
+}
+
static struct socket_info *swrap_get_socket_info(int si_index)
{
return (struct socket_info *)(&(sockets[si_index].info));
type = u_type;
iface = (addr & 0x000000FF);
} else {
- char str[256] = {0,};
- inet_ntop(inaddr->sa_family,
- &in->sin_addr,
- str, sizeof(str));
+ struct swrap_sockaddr_buf buf = {};
SWRAP_LOG(SWRAP_LOG_WARN,
- "str[%s] prt[%u]",
- str, (unsigned)prt);
+ "%s",
+ swrap_sockaddr_string(&buf, inaddr));
errno = ENETUNREACH;
return -1;
}
if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
iface = in->sin6_addr.s6_addr[15];
} else {
- char str[256] = {0,};
- inet_ntop(inaddr->sa_family,
- &in->sin6_addr,
- str, sizeof(str));
+ struct swrap_sockaddr_buf buf = {};
SWRAP_LOG(SWRAP_LOG_WARN,
- "str[%s] prt[%u]",
- str, (unsigned)prt);
+ "%s",
+ swrap_sockaddr_string(&buf, inaddr));
errno = ENETUNREACH;
return -1;
}
char type;
int ret;
int port;
- struct stat st;
char *swrap_dir = NULL;
swrap_mutex_lock(&autobind_start_mutex);
type,
socket_wrapper_default_iface(),
port);
- if (stat(un_addr.sa.un.sun_path, &st) == 0) continue;
ret = libc_bind(fd, &un_addr.sa.s, un_addr.sa_socklen);
if (ret == -1) {
+ if (errno == EALREADY || errno == EADDRINUSE) {
+ continue;
+ }
goto done;
}
.sa_socklen = sizeof(struct sockaddr_un),
};
struct socket_info *si = find_socket_info(s);
+ struct swrap_sockaddr_buf buf = {};
int bcast = 0;
if (!si) {
}
SWRAP_LOG(SWRAP_LOG_TRACE,
- "connect() path=%s, fd=%d",
+ "connect(%s) path=%s, fd=%d",
+ swrap_sockaddr_string(&buf, serv_addr),
un_addr.sa.un.sun_path, s);
.sa_socklen = sizeof(struct sockaddr_un),
};
struct socket_info *si = find_socket_info(s);
+ struct swrap_sockaddr_buf buf = {};
int bind_error = 0;
#if 0 /* FIXME */
bool in_use;
ret = libc_bind(s, &un_addr.sa.s, un_addr.sa_socklen);
SWRAP_LOG(SWRAP_LOG_TRACE,
- "bind() path=%s, fd=%d",
+ "bind(%s) path=%s, fd=%d",
+ swrap_sockaddr_string(&buf, myaddr),
un_addr.sa.un.sun_path, s);
if (ret == 0) {
struct cmsghdr *cmsg;
};
-static int swrap_sendmsg_unix_scm_rights(const struct cmsghdr *cmsg,
+static int swrap_sendmsg_unix_scm_rights(struct cmsghdr *cmsg,
uint8_t **cm_data,
size_t *cm_data_space,
int *scm_rights_pipe_fd)
return 0;
}
-static int swrap_sendmsg_unix_sol_socket(const struct cmsghdr *cmsg,
+static int swrap_sendmsg_unix_sol_socket(struct cmsghdr *cmsg,
uint8_t **cm_data,
size_t *cm_data_space,
int *scm_rights_pipe_fd)
return rc;
}
-static int swrap_recvmsg_unix_scm_rights(const struct cmsghdr *cmsg,
+static int swrap_recvmsg_unix_scm_rights(struct cmsghdr *cmsg,
uint8_t **cm_data,
size_t *cm_data_space)
{
return 0;
}
-static int swrap_recvmsg_unix_sol_socket(const struct cmsghdr *cmsg,
+static int swrap_recvmsg_unix_sol_socket(struct cmsghdr *cmsg,
uint8_t **cm_data,
size_t *cm_data_space)
{
for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
- memcpy(buf + ofs,
- msg->msg_iov[i].iov_base,
- this_time);
+ if (this_time > 0) {
+ memcpy(buf + ofs,
+ msg->msg_iov[i].iov_base,
+ this_time);
+ }
ofs += this_time;
remain -= this_time;
}
SAFE_FREE(sockets);
- if (swrap.libc.handle != NULL) {
+ if (swrap.libc.handle != NULL
+#ifdef RTLD_NEXT
+ && swrap.libc.handle != RTLD_NEXT
+#endif
+ ) {
dlclose(swrap.libc.handle);
}
- if (swrap.libc.socket_handle) {
+ if (swrap.libc.socket_handle
+#ifdef RTLD_NEXT
+ && swrap.libc.socket_handle != RTLD_NEXT
+#endif
+ ) {
dlclose(swrap.libc.socket_handle);
}
}
* related syscalls also with the '_' prefix.
*
* This is tested in Samba's 'make test',
- * there we noticed that providing '_read'
- * and '_open' would cause errors, which
+ * there we noticed that providing '_read',
+ * '_open' and '_close' would cause errors, which
* means we skip '_read', '_write' and
* all non socket related calls without
* further analyzing the problem.
#endif
SWRAP_SYMBOL_ALIAS(accept, _accept);
SWRAP_SYMBOL_ALIAS(bind, _bind);
-SWRAP_SYMBOL_ALIAS(close, _close);
SWRAP_SYMBOL_ALIAS(connect, _connect);
SWRAP_SYMBOL_ALIAS(dup, _dup);
SWRAP_SYMBOL_ALIAS(dup2, _dup2);