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