contrib: gpg-error: Provide a lock obj for NACL
[vlc.git] / compat / sendmsg.c
blob0f42e782f824ba1b6125357150322f6e4c65e5cc
1 /*****************************************************************************
2 * sendmsg.c: POSIX sendmsg() replacement
3 *****************************************************************************
4 * Copyright © 2017 VLC authors and VideoLAN
5 * Copyright © 2016 Rémi Denis-Courmont
7 * Authors: Rémi Denis-Courmont
8 * Dennis Hamester <dhamester@jusst.de>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 #ifdef HAVE_CONFIG_H
26 # include <config.h>
27 #endif
29 #ifdef _WIN32
30 # include <errno.h>
31 # include <stdlib.h>
32 # include <winsock2.h>
34 ssize_t sendmsg(int fd, const struct msghdr *msg, int flags)
36 if (msg->msg_controllen != 0)
38 errno = ENOSYS;
39 return -1;
42 if (msg->msg_iovlen > IOV_MAX)
44 errno = EINVAL;
45 return -1;
48 WSABUF *buf = malloc(msg->msg_iovlen * sizeof (*buf));
49 if (buf == NULL)
50 return -1;
52 for (unsigned i = 0; i < msg->msg_iovlen; i++)
54 buf[i].len = msg->msg_iov[i].iov_len;
55 buf[i].buf = (void *)msg->msg_iov[i].iov_base;
58 DWORD sent;
60 int ret = WSASendTo(fd, buf, msg->msg_iovlen, &sent, flags,
61 msg->msg_name, msg->msg_namelen, NULL, NULL);
62 free(buf);
64 if (ret == 0)
65 return sent;
67 switch (WSAGetLastError())
69 case WSAEWOULDBLOCK:
70 errno = EAGAIN;
71 break;
73 return -1;
76 #elif defined __native_client__
77 #include <errno.h>
78 #include <limits.h>
79 #include <stdlib.h>
80 #include <string.h>
81 #include <sys/socket.h>
82 #include <sys/uio.h>
84 ssize_t sendmsg(int fd, const struct msghdr *msg, int flags)
86 if (msg->msg_controllen != 0)
88 errno = ENOSYS;
89 return -1;
92 if ((msg->msg_iovlen <= 0) || (msg->msg_iovlen > IOV_MAX))
94 errno = EMSGSIZE;
95 return -1;
98 size_t full_size = 0;
99 for (int i = 0; i < msg->msg_iovlen; ++i)
100 full_size += msg->msg_iov[i].iov_len;
102 if (full_size > SSIZE_MAX) {
103 errno = EINVAL;
104 return -1;
108 * We always allocate here, because whether send/sento allow NULL message or
109 * not is unspecified.
111 char *data = malloc(full_size ? full_size : 1);
112 if (!data) {
113 errno = ENOMEM;
114 return -1;
117 size_t tmp = 0;
118 for (int i = 0; i < msg->msg_iovlen; ++i) {
119 memcpy(data + tmp, msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len);
120 tmp += msg->msg_iov[i].iov_len;
123 ssize_t res;
124 if (msg->msg_name)
125 res = sendto(fd, data, full_size, flags, msg->msg_name, msg->msg_namelen);
126 else
127 res = send(fd, data, full_size, flags);
129 free(data);
130 return res;
133 #else
134 #error sendmsg not implemented on your platform!
135 #endif