xref: /freebsd/crypto/heimdal/lib/roken/sendmsg.c (revision b9f654b163bce26de79705e77b872427c9f2afa1)
1 /*
2  * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
3  * (Royal Institute of Technology, Stockholm, Sweden).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the Institute nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #include <config.h>
35 
36 #include "roken.h"
37 
38 #ifndef _WIN32
39 
40 ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL
41 sendmsg(rk_socket_t s, const struct msghdr *msg, int flags)
42 {
43     ssize_t ret;
44     size_t tot = 0;
45     int i;
46     char *buf, *p;
47     struct iovec *iov = msg->msg_iov;
48 
49     for(i = 0; i < msg->msg_iovlen; ++i)
50 	tot += iov[i].iov_len;
51     buf = malloc(tot);
52     if (tot != 0 && buf == NULL) {
53 	errno = ENOMEM;
54 	return -1;
55     }
56     p = buf;
57     for (i = 0; i < msg->msg_iovlen; ++i) {
58 	memcpy (p, iov[i].iov_base, iov[i].iov_len);
59 	p += iov[i].iov_len;
60     }
61     ret = sendto (s, buf, tot, flags, msg->msg_name, msg->msg_namelen);
62     free (buf);
63     return ret;
64 }
65 
66 #else /* _WIN32 */
67 
68 /***********************************************************************
69  * Copyright (c) 2009, Secure Endpoints Inc.
70  * All rights reserved.
71  *
72  * Redistribution and use in source and binary forms, with or without
73  * modification, are permitted provided that the following conditions
74  * are met:
75  *
76  * - Redistributions of source code must retain the above copyright
77  *   notice, this list of conditions and the following disclaimer.
78  *
79  * - Redistributions in binary form must reproduce the above copyright
80  *   notice, this list of conditions and the following disclaimer in
81  *   the documentation and/or other materials provided with the
82  *   distribution.
83  *
84  * - Neither the name of Secure Endpoints Inc. nor the names of its
85  *   contributors may be used to endorse or promote products derived
86  *   from this software without specific prior written permission.
87  *
88  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
89  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
90  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
91  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
92  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
93  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
94  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
95  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
96  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
97  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
98  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
99  * OF THE POSSIBILITY OF SUCH DAMAGE.
100  *
101  **********************************************************************/
102 
103 /**
104  * Implementation of sendmsg() for WIN32
105  *
106  * We are using a contrived definition of msghdr which actually uses
107  * an array of ::_WSABUF structures instead of ::iovec .  This allows
108  * us to call WSASend directly using the given ::msghdr instead of
109  * having to allocate another array of ::_WSABUF and copying data for
110  * each call.
111  *
112  * Limitations:
113  *
114  * - msg->msg_name is ignored.  So is msg->control.
115  * - WSASend() only supports ::MSG_DONTROUTE, ::MSG_OOB and
116  *   ::MSG_PARTIAL.
117  *
118  * @param[in] s The socket to use.
119  * @param[in] msg The message
120  * @param[in] flags Flags.  A combination of ::MSG_DONTROUTE,
121  *  ::MSG_OOB and ::MSG_PARTIAL
122  *
123  * @return The number of bytes sent, on success.  Or -1 on error.
124  */
125 ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL
126 sendmsg_w32(rk_socket_t s, const struct msghdr * msg, int flags)
127 {
128     int srv;
129     DWORD num_bytes_sent = 0;
130 
131     /* TODO: For _WIN32_WINNT >= 0x0600 we can use WSASendMsg using
132        WSAMSG which is a much more direct analogue to sendmsg(). */
133 
134     srv = WSASend(s, msg->msg_iov, msg->msg_iovlen,
135 		  &num_bytes_sent, flags, NULL, NULL);
136 
137     if (srv == 0)
138 	return (int) num_bytes_sent;
139 
140     /* srv == SOCKET_ERROR and WSAGetLastError() == WSA_IO_PENDING
141        indicates that a non-blocking transfer has been scheduled.
142        We'll have to check for that if we ever support non-blocking
143        I/O. */
144 
145     return -1;
146 }
147 
148 #endif /* !_WIN32 */
149