1 /** $MirOS: src/sys/compat/common/uipc_syscalls_43.c,v 1.2 2005/03/06 21:27:29 tg Exp $ */
2 /* $OpenBSD: uipc_syscalls_43.c,v 1.7 2003/06/02 23:27:59 millert Exp $ */
3 /* $NetBSD: uipc_syscalls_43.c,v 1.5 1996/03/14 19:31:50 christos Exp $ */
4
5 /*
6 * Fix "undefined" MSG_COMPAT errors in /sys/sys/socket.h too!
7 */
8
9 /*
10 * Copyright (c) 1982, 1986, 1989, 1990, 1993
11 * The Regents of the University of California. All rights reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94
38 */
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/filedesc.h>
43 #include <sys/kernel.h>
44 #include <sys/proc.h>
45 #include <sys/file.h>
46 #include <sys/socket.h>
47 #include <sys/socketvar.h>
48 #include <sys/stat.h>
49 #include <sys/ioctl.h>
50 #include <sys/fcntl.h>
51 #include <sys/malloc.h>
52 #include <sys/syslog.h>
53 #include <sys/unistd.h>
54 #include <sys/resourcevar.h>
55
56 #include <sys/mount.h>
57 #include <sys/syscallargs.h>
58
59 #if defined(COMPAT_OPENBSD) || defined(COMPAT_LINUX)
60 int
compat_43_sys_accept(p,v,retval)61 compat_43_sys_accept(p, v, retval)
62 struct proc *p;
63 void *v;
64 register_t *retval;
65 {
66 struct sys_accept_args /* {
67 syscallarg(int) s;
68 syscallarg(caddr_t) name;
69 syscallarg(int *) anamelen;
70 } */ *uap = v;
71 int error;
72
73 if ((error = sys_accept(p, uap, retval)) != 0)
74 return error;
75
76 if (SCARG(uap, name)) {
77 struct sockaddr sa;
78
79 if ((error = copyin(SCARG(uap, name), &sa, sizeof(sa))) != 0)
80 return error;
81
82 ((struct osockaddr*) &sa)->sa_family = sa.sa_family;
83
84 if ((error = copyout(&sa, SCARG(uap, name), sizeof(sa))) != 0)
85 return error;
86 }
87 return 0;
88 }
89 #endif
90
91 #if defined(COMPAT_OPENBSD)
92 int
compat_43_sys_getpeername(p,v,retval)93 compat_43_sys_getpeername(p, v, retval)
94 struct proc *p;
95 void *v;
96 register_t *retval;
97 {
98 struct sys_getpeername_args /* {
99 syscallarg(int) fdes;
100 syscallarg(caddr_t) asa;
101 syscallarg(int *) alen;
102 } */ *uap = v;
103 struct sockaddr sa;
104
105 int error;
106
107 if ((error = sys_getpeername(p, uap, retval)) != 0)
108 return error;
109
110 if ((error = copyin(SCARG(uap, asa), &sa, sizeof(sa))) != 0)
111 return error;
112
113 ((struct osockaddr*) &sa)->sa_family = sa.sa_family;
114
115 if ((error = copyout(&sa, SCARG(uap, asa), sizeof(sa))) != 0)
116 return error;
117
118 return 0;
119 }
120
121
122 int
compat_43_sys_getsockname(p,v,retval)123 compat_43_sys_getsockname(p, v, retval)
124 struct proc *p;
125 void *v;
126 register_t *retval;
127 {
128 struct sys_getsockname_args /* {
129 syscallarg(int) fdes;
130 syscallarg(caddr_t) asa;
131 syscallarg(int *) alen;
132 } */ *uap = v;
133 struct sockaddr sa;
134 int error;
135
136 if ((error = sys_getsockname(p, uap, retval)) != 0)
137 return error;
138
139 if ((error = copyin(SCARG(uap, asa), &sa, sizeof(sa))) != 0)
140 return error;
141
142 ((struct osockaddr*) &sa)->sa_family = sa.sa_family;
143
144 if ((error = copyout(&sa, SCARG(uap, asa), sizeof(sa))) != 0)
145 return error;
146
147 return 0;
148 }
149 #endif
150
151 #if defined(COMPAT_OPENBSD) || defined(COMPAT_LINUX)
152 int
compat_43_sys_recv(p,v,retval)153 compat_43_sys_recv(p, v, retval)
154 struct proc *p;
155 void *v;
156 register_t *retval;
157 {
158 register struct compat_43_sys_recv_args /* {
159 syscallarg(int) s;
160 syscallarg(caddr_t) buf;
161 syscallarg(int) len;
162 syscallarg(int) flags;
163 } */ *uap = v;
164 struct msghdr msg;
165 struct iovec aiov;
166
167 msg.msg_name = 0;
168 msg.msg_namelen = 0;
169 msg.msg_iov = &aiov;
170 msg.msg_iovlen = 1;
171 aiov.iov_base = SCARG(uap, buf);
172 aiov.iov_len = SCARG(uap, len);
173 msg.msg_control = 0;
174 msg.msg_flags = SCARG(uap, flags);
175 return (recvit(p, SCARG(uap, s), &msg, (caddr_t)0, retval));
176 }
177 #endif
178
179 #if defined(COMPAT_OPENBSD)
180 int
compat_43_sys_recvfrom(p,v,retval)181 compat_43_sys_recvfrom(p, v, retval)
182 struct proc *p;
183 void *v;
184 register_t *retval;
185 {
186 struct sys_recvfrom_args /* {
187 syscallarg(int) s;
188 syscallarg(caddr_t) buf;
189 syscallarg(size_t) len;
190 syscallarg(int) flags;
191 syscallarg(caddr_t) from;
192 syscallarg(int *) fromlenaddr;
193 } */ *uap = v;
194
195 SCARG(uap, flags) |= MSG_COMPAT;
196 return (sys_recvfrom(p, uap, retval));
197 }
198
199
200 /*
201 * Old recvmsg. This code takes advantage of the fact that the old msghdr
202 * overlays the new one, missing only the flags, and with the (old) access
203 * rights where the control fields are now.
204 */
205 int
compat_43_sys_recvmsg(p,v,retval)206 compat_43_sys_recvmsg(p, v, retval)
207 struct proc *p;
208 void *v;
209 register_t *retval;
210 {
211 register struct compat_43_sys_recvmsg_args /* {
212 syscallarg(int) s;
213 syscallarg(struct omsghdr *) msg;
214 syscallarg(int) flags;
215 } */ *uap = v;
216 struct msghdr msg;
217 struct iovec aiov[UIO_SMALLIOV], *iov;
218 int error;
219
220 error = copyin((caddr_t)SCARG(uap, msg), (caddr_t)&msg,
221 sizeof (struct omsghdr));
222 if (error)
223 return (error);
224 if (msg.msg_iovlen <= 0 || msg.msg_iovlen > IOV_MAX)
225 return (EMSGSIZE);
226 if (msg.msg_iovlen > UIO_SMALLIOV)
227 MALLOC(iov, struct iovec *,
228 sizeof(struct iovec) * msg.msg_iovlen, M_IOV, M_WAITOK);
229 else
230 iov = aiov;
231 msg.msg_flags = SCARG(uap, flags) | MSG_COMPAT;
232 error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,
233 (unsigned)(msg.msg_iovlen * sizeof (struct iovec)));
234 if (error)
235 goto done;
236 msg.msg_iov = iov;
237 error = recvit(p, SCARG(uap, s), &msg,
238 (caddr_t)&SCARG(uap, msg)->msg_namelen, retval);
239
240 if (msg.msg_controllen && error == 0)
241 error = copyout((caddr_t)&msg.msg_controllen,
242 (caddr_t)&SCARG(uap, msg)->msg_accrightslen, sizeof (int));
243 done:
244 if (iov != aiov)
245 FREE(iov, M_IOV);
246 return (error);
247 }
248 #endif
249
250 #if defined(COMPAT_OPENBSD) || defined(COMPAT_LINUX)
251 int
compat_43_sys_send(p,v,retval)252 compat_43_sys_send(p, v, retval)
253 struct proc *p;
254 void *v;
255 register_t *retval;
256 {
257 register struct compat_43_sys_send_args /* {
258 syscallarg(int) s;
259 syscallarg(caddr_t) buf;
260 syscallarg(int) len;
261 syscallarg(int) flags;
262 } */ *uap = v;
263 struct msghdr msg;
264 struct iovec aiov;
265
266 msg.msg_name = 0;
267 msg.msg_namelen = 0;
268 msg.msg_iov = &aiov;
269 msg.msg_iovlen = 1;
270 aiov.iov_base = SCARG(uap, buf);
271 aiov.iov_len = SCARG(uap, len);
272 msg.msg_control = 0;
273 msg.msg_flags = 0;
274 return (sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval));
275 }
276 #endif
277
278 #if defined(COMPAT_OPENBSD)
279 int
compat_43_sys_sendmsg(p,v,retval)280 compat_43_sys_sendmsg(p, v, retval)
281 struct proc *p;
282 void *v;
283 register_t *retval;
284 {
285 register struct compat_43_sys_sendmsg_args /* {
286 syscallarg(int) s;
287 syscallarg(caddr_t) msg;
288 syscallarg(int) flags;
289 } */ *uap = v;
290 struct msghdr msg;
291 struct iovec aiov[UIO_SMALLIOV], *iov;
292 int error;
293
294 error = copyin(SCARG(uap, msg), (caddr_t)&msg,
295 sizeof (struct omsghdr));
296 if (error)
297 return (error);
298 if (msg.msg_iovlen <= 0 || msg.msg_iovlen > IOV_MAX)
299 return (EMSGSIZE);
300 if (msg.msg_iovlen > UIO_SMALLIOV)
301 MALLOC(iov, struct iovec *,
302 sizeof(struct iovec) * msg.msg_iovlen, M_IOV, M_WAITOK);
303 else
304 iov = aiov;
305 error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,
306 (unsigned)(msg.msg_iovlen * sizeof (struct iovec)));
307 if (error)
308 goto done;
309 msg.msg_flags = MSG_COMPAT;
310 msg.msg_iov = iov;
311 error = sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval);
312 done:
313 if (iov != aiov)
314 FREE(iov, M_IOV);
315 return (error);
316 }
317 #endif
318