xref: /minix/minix/lib/libc/sys/recvfrom.c (revision 84ed480e)
1433d6423SLionel Sambuc #include <sys/cdefs.h>
2433d6423SLionel Sambuc #include "namespace.h"
3c38dbb97SDavid van Moolenbroek #include <lib.h>
4433d6423SLionel Sambuc 
5433d6423SLionel Sambuc #include <assert.h>
6433d6423SLionel Sambuc #include <errno.h>
7433d6423SLionel Sambuc #include <stdlib.h>
8433d6423SLionel Sambuc #include <stdio.h>
9433d6423SLionel Sambuc #include <string.h>
10433d6423SLionel Sambuc #include <unistd.h>
11433d6423SLionel Sambuc #include <sys/ioctl.h>
12433d6423SLionel Sambuc #include <sys/socket.h>
13433d6423SLionel Sambuc #include <netinet/in.h>
14433d6423SLionel Sambuc 
15433d6423SLionel Sambuc #include <net/gen/in.h>
16433d6423SLionel Sambuc #include <net/gen/tcp.h>
17433d6423SLionel Sambuc #include <net/gen/tcp_io.h>
18433d6423SLionel Sambuc #include <net/gen/udp.h>
19433d6423SLionel Sambuc #include <net/gen/udp_hdr.h>
20433d6423SLionel Sambuc #include <net/gen/udp_io.h>
21433d6423SLionel Sambuc 
227f5f010bSBen Gras #include <net/gen/ip_hdr.h>
2317580212SDavid van Moolenbroek #include <net/gen/ip_io.h>
247f5f010bSBen Gras 
25433d6423SLionel Sambuc #define DEBUG 0
26433d6423SLionel Sambuc 
27433d6423SLionel Sambuc static ssize_t _tcp_recvfrom(int sock, void *__restrict buffer, size_t length,
28433d6423SLionel Sambuc 	int flags, struct sockaddr *__restrict address,
29433d6423SLionel Sambuc 	socklen_t *__restrict address_len, nwio_tcpconf_t *tcpconfp);
30433d6423SLionel Sambuc static ssize_t _udp_recvfrom(int sock, void *__restrict buffer, size_t length,
31433d6423SLionel Sambuc 	int flags, struct sockaddr *__restrict address,
32433d6423SLionel Sambuc 	socklen_t *__restrict address_len, nwio_udpopt_t *udpoptp);
33433d6423SLionel Sambuc static ssize_t _uds_recvfrom_conn(int sock, void *__restrict buffer,
34433d6423SLionel Sambuc 	size_t length, int flags, struct sockaddr *__restrict address,
35433d6423SLionel Sambuc 	socklen_t *__restrict address_len, struct sockaddr_un *uds_addr);
36433d6423SLionel Sambuc static ssize_t _uds_recvfrom_dgram(int sock, void *__restrict buffer,
37433d6423SLionel Sambuc 	size_t length, int flags, struct sockaddr *__restrict address,
38433d6423SLionel Sambuc 	socklen_t *__restrict address_len);
39433d6423SLionel Sambuc 
40c38dbb97SDavid van Moolenbroek /*
41c38dbb97SDavid van Moolenbroek  * Receive a message from a socket.
42c38dbb97SDavid van Moolenbroek  */
43c38dbb97SDavid van Moolenbroek static ssize_t
__recvfrom(int fd,void * __restrict buffer,size_t length,int flags,struct sockaddr * __restrict address,socklen_t * __restrict address_len)44c38dbb97SDavid van Moolenbroek __recvfrom(int fd, void * __restrict buffer, size_t length, int flags,
45c38dbb97SDavid van Moolenbroek 	struct sockaddr * __restrict address,
46c38dbb97SDavid van Moolenbroek 	socklen_t * __restrict address_len)
47c38dbb97SDavid van Moolenbroek {
48c38dbb97SDavid van Moolenbroek 	message m;
49c38dbb97SDavid van Moolenbroek 	ssize_t r;
50c38dbb97SDavid van Moolenbroek 
51c38dbb97SDavid van Moolenbroek 	if (address != NULL && address_len == NULL) {
52c38dbb97SDavid van Moolenbroek 		errno = EFAULT;
53c38dbb97SDavid van Moolenbroek 		return -1;
54c38dbb97SDavid van Moolenbroek 	}
55c38dbb97SDavid van Moolenbroek 
56c38dbb97SDavid van Moolenbroek 	memset(&m, 0, sizeof(m));
57c38dbb97SDavid van Moolenbroek 	m.m_lc_vfs_sendrecv.fd = fd;
58c38dbb97SDavid van Moolenbroek 	m.m_lc_vfs_sendrecv.buf = (vir_bytes)buffer;
59c38dbb97SDavid van Moolenbroek 	m.m_lc_vfs_sendrecv.len = length;
60c38dbb97SDavid van Moolenbroek 	m.m_lc_vfs_sendrecv.flags = flags;
61c38dbb97SDavid van Moolenbroek 	m.m_lc_vfs_sendrecv.addr = (vir_bytes)address;
62c38dbb97SDavid van Moolenbroek 	m.m_lc_vfs_sendrecv.addr_len = (address != NULL) ? *address_len : 0;
63c38dbb97SDavid van Moolenbroek 
64c38dbb97SDavid van Moolenbroek 	if ((r = _syscall(VFS_PROC_NR, VFS_RECVFROM, &m)) < 0)
65c38dbb97SDavid van Moolenbroek 		return -1;
66c38dbb97SDavid van Moolenbroek 
67c38dbb97SDavid van Moolenbroek 	if (address != NULL)
68c38dbb97SDavid van Moolenbroek 		*address_len = m.m_vfs_lc_socklen.len;
69c38dbb97SDavid van Moolenbroek 	return r;
70c38dbb97SDavid van Moolenbroek }
71c38dbb97SDavid van Moolenbroek 
recvfrom(int sock,void * __restrict buffer,size_t length,int flags,struct sockaddr * __restrict address,socklen_t * __restrict address_len)72433d6423SLionel Sambuc ssize_t recvfrom(int sock, void *__restrict buffer, size_t length,
73433d6423SLionel Sambuc 	int flags, struct sockaddr *__restrict address,
74433d6423SLionel Sambuc 	socklen_t *__restrict address_len)
75433d6423SLionel Sambuc {
76433d6423SLionel Sambuc 	int r;
77433d6423SLionel Sambuc 	nwio_tcpconf_t tcpconf;
78433d6423SLionel Sambuc 	nwio_udpopt_t udpopt;
7917580212SDavid van Moolenbroek 	nwio_ipopt_t ipopt;
80433d6423SLionel Sambuc 	struct sockaddr_un uds_addr;
81433d6423SLionel Sambuc 	int uds_sotype = -1;
82433d6423SLionel Sambuc 
83c38dbb97SDavid van Moolenbroek 	r = __recvfrom(sock, buffer, length, flags, address, address_len);
84*84ed480eSDavid van Moolenbroek 	if (r != -1 || (errno != ENOTSOCK && errno != ENOSYS))
85c38dbb97SDavid van Moolenbroek 		return r;
86c38dbb97SDavid van Moolenbroek 
87433d6423SLionel Sambuc #if DEBUG
88433d6423SLionel Sambuc 	fprintf(stderr, "recvfrom: for fd %d\n", sock);
89433d6423SLionel Sambuc #endif
90433d6423SLionel Sambuc 
91433d6423SLionel Sambuc 	r= ioctl(sock, NWIOGTCPCONF, &tcpconf);
92433d6423SLionel Sambuc 	if (r != -1 || errno != ENOTTY)
93433d6423SLionel Sambuc 	{
94433d6423SLionel Sambuc 		if (r == -1)
95433d6423SLionel Sambuc 			return r;
96433d6423SLionel Sambuc 		return _tcp_recvfrom(sock, buffer, length, flags,
97433d6423SLionel Sambuc 			address, address_len, &tcpconf);
98433d6423SLionel Sambuc 	}
99433d6423SLionel Sambuc 
100433d6423SLionel Sambuc 	r= ioctl(sock, NWIOGUDPOPT, &udpopt);
101433d6423SLionel Sambuc 	if (r != -1 || errno != ENOTTY)
102433d6423SLionel Sambuc 	{
103433d6423SLionel Sambuc 		if (r == -1)
104433d6423SLionel Sambuc 			return r;
105433d6423SLionel Sambuc 		return _udp_recvfrom(sock, buffer, length, flags,
106433d6423SLionel Sambuc 			address, address_len, &udpopt);
107433d6423SLionel Sambuc 	}
108433d6423SLionel Sambuc 
109433d6423SLionel Sambuc 	r= ioctl(sock, NWIOGUDSSOTYPE, &uds_sotype);
110433d6423SLionel Sambuc 	if (r != -1 || errno != ENOTTY)
111433d6423SLionel Sambuc 	{
112433d6423SLionel Sambuc 
113433d6423SLionel Sambuc 		if (r == -1) {
114433d6423SLionel Sambuc 			return r;
115433d6423SLionel Sambuc 		}
116433d6423SLionel Sambuc 
117433d6423SLionel Sambuc 		if (uds_sotype == SOCK_DGRAM) {
118433d6423SLionel Sambuc 			return _uds_recvfrom_dgram(sock, buffer,
119433d6423SLionel Sambuc 				length, flags, address, address_len);
120433d6423SLionel Sambuc 		} else {
121433d6423SLionel Sambuc 			return _uds_recvfrom_conn(sock, buffer,
122433d6423SLionel Sambuc 				length, flags, address, address_len,
123433d6423SLionel Sambuc 				&uds_addr);
124433d6423SLionel Sambuc 		}
125433d6423SLionel Sambuc 	}
126433d6423SLionel Sambuc 
12717580212SDavid van Moolenbroek 	r= ioctl(sock, NWIOGIPOPT, &ipopt);
12817580212SDavid van Moolenbroek 	if (r != -1 || errno != ENOTTY)
1297f5f010bSBen Gras 	{
1307f5f010bSBen Gras 		ip_hdr_t *ip_hdr;
1315dd8da10SDavid van Moolenbroek 		int rd;
1327f5f010bSBen Gras 		struct sockaddr_in sin;
1337f5f010bSBen Gras 
13417580212SDavid van Moolenbroek 		if (r == -1) {
13517580212SDavid van Moolenbroek 			return r;
13617580212SDavid van Moolenbroek 		}
13717580212SDavid van Moolenbroek 
1387f5f010bSBen Gras 		rd = read(sock, buffer, length);
1397f5f010bSBen Gras 
1407f5f010bSBen Gras 		if(rd < 0) return rd;
1417f5f010bSBen Gras 
1425dd8da10SDavid van Moolenbroek 		assert((size_t)rd >= sizeof(*ip_hdr));
1437f5f010bSBen Gras 
1447f5f010bSBen Gras 		ip_hdr= buffer;
1457f5f010bSBen Gras 
1467f5f010bSBen Gras 		if (address != NULL)
1477f5f010bSBen Gras 		{
1487f5f010bSBen Gras 			int len;
1497f5f010bSBen Gras 			memset(&sin, 0, sizeof(sin));
1507f5f010bSBen Gras 			sin.sin_family= AF_INET;
1517f5f010bSBen Gras 			sin.sin_addr.s_addr= ip_hdr->ih_src;
1527f5f010bSBen Gras 			sin.sin_len= sizeof(sin);
1537f5f010bSBen Gras 			len= *address_len;
1545dd8da10SDavid van Moolenbroek 			if ((size_t)len > sizeof(sin))
1555dd8da10SDavid van Moolenbroek 				len= (int)sizeof(sin);
1567f5f010bSBen Gras 			memcpy(address, &sin, len);
1577f5f010bSBen Gras 			*address_len= sizeof(sin);
1587f5f010bSBen Gras 		}
1597f5f010bSBen Gras 
1607f5f010bSBen Gras 		return rd;
1617f5f010bSBen Gras 	}
1627f5f010bSBen Gras 
163c38dbb97SDavid van Moolenbroek 	errno = ENOTSOCK;
164c38dbb97SDavid van Moolenbroek 	return -1;
165433d6423SLionel Sambuc }
166433d6423SLionel Sambuc 
_tcp_recvfrom(int sock,void * __restrict buffer,size_t length,int flags,struct sockaddr * __restrict address,socklen_t * __restrict address_len,nwio_tcpconf_t * tcpconfp)167433d6423SLionel Sambuc static ssize_t _tcp_recvfrom(int sock, void *__restrict buffer, size_t length,
168433d6423SLionel Sambuc 	int flags, struct sockaddr *__restrict address,
169433d6423SLionel Sambuc 	socklen_t *__restrict address_len, nwio_tcpconf_t *tcpconfp)
170433d6423SLionel Sambuc {
171433d6423SLionel Sambuc 	int r;
172433d6423SLionel Sambuc 	size_t len;
173433d6423SLionel Sambuc 	struct sockaddr_in sin;
174433d6423SLionel Sambuc 
175433d6423SLionel Sambuc 	if (flags != 0)
176433d6423SLionel Sambuc 	{
177433d6423SLionel Sambuc #if DEBUG
178433d6423SLionel Sambuc 		fprintf(stderr, "recvfrom(tcp): flags not implemented\n");
179433d6423SLionel Sambuc #endif
180433d6423SLionel Sambuc 		errno= ENOSYS;
181433d6423SLionel Sambuc 		return -1;
182433d6423SLionel Sambuc 	}
183433d6423SLionel Sambuc 
184433d6423SLionel Sambuc 	r = read(sock, buffer, length);
185433d6423SLionel Sambuc 
186433d6423SLionel Sambuc 	if (r >= 0 && address != NULL)
187433d6423SLionel Sambuc 	{
188433d6423SLionel Sambuc 		sin.sin_family= AF_INET;
189433d6423SLionel Sambuc 		sin.sin_addr.s_addr= tcpconfp->nwtc_remaddr;
190433d6423SLionel Sambuc 		sin.sin_port= tcpconfp->nwtc_remport;
191433d6423SLionel Sambuc 		sin.sin_len= sizeof(sin);
192433d6423SLionel Sambuc 		len= *address_len;
193433d6423SLionel Sambuc 		if (len > sizeof(sin))
194433d6423SLionel Sambuc 			len= sizeof(sin);
195433d6423SLionel Sambuc 		memcpy(address, &sin, len);
196433d6423SLionel Sambuc 		*address_len= sizeof(sin);
197433d6423SLionel Sambuc 	}
198433d6423SLionel Sambuc 
199433d6423SLionel Sambuc 	return r;
200433d6423SLionel Sambuc }
201433d6423SLionel Sambuc 
_udp_recvfrom(int sock,void * __restrict buffer,size_t length,int flags,struct sockaddr * __restrict address,socklen_t * __restrict address_len,nwio_udpopt_t * udpoptp)202433d6423SLionel Sambuc static ssize_t _udp_recvfrom(int sock, void *__restrict buffer, size_t length,
203433d6423SLionel Sambuc 	int flags, struct sockaddr *__restrict address,
204433d6423SLionel Sambuc 	socklen_t *__restrict address_len, nwio_udpopt_t *udpoptp)
205433d6423SLionel Sambuc {
206433d6423SLionel Sambuc 	int r, t_errno;
207433d6423SLionel Sambuc 	size_t buflen, len;
208433d6423SLionel Sambuc 	void *buf;
209433d6423SLionel Sambuc 	udp_io_hdr_t *io_hdrp;
210433d6423SLionel Sambuc 	struct sockaddr_in sin;
211433d6423SLionel Sambuc 
212433d6423SLionel Sambuc 	if (flags)
213433d6423SLionel Sambuc 	{
214433d6423SLionel Sambuc #if DEBUG
215433d6423SLionel Sambuc 		fprintf(stderr, "recvfrom(udp): flags not implemented\n");
216433d6423SLionel Sambuc #endif
217433d6423SLionel Sambuc 		errno= ENOSYS;
218433d6423SLionel Sambuc 		return -1;
219433d6423SLionel Sambuc 	}
220433d6423SLionel Sambuc 
221433d6423SLionel Sambuc 	if (udpoptp->nwuo_flags & NWUO_RWDATONLY)
222433d6423SLionel Sambuc 	{
223433d6423SLionel Sambuc 		if (address != NULL &&
224433d6423SLionel Sambuc 			(udpoptp->nwuo_flags & (NWUO_RA_SET | NWUO_RP_SET)) !=
225433d6423SLionel Sambuc 			(NWUO_RA_SET | NWUO_RP_SET))
226433d6423SLionel Sambuc 		{
227433d6423SLionel Sambuc 
228433d6423SLionel Sambuc #if DEBUG
229433d6423SLionel Sambuc 			fprintf(stderr,
230433d6423SLionel Sambuc 			"recvfrom(udp): RWDATONLY on unconnected socket\n");
231433d6423SLionel Sambuc #endif
232433d6423SLionel Sambuc 			errno= ENOTCONN;
233433d6423SLionel Sambuc 			return -1;
234433d6423SLionel Sambuc 		}
235433d6423SLionel Sambuc 
236433d6423SLionel Sambuc 		r= read(sock, buffer, length);
237433d6423SLionel Sambuc 		if (r == -1)
238433d6423SLionel Sambuc 			return r;
239433d6423SLionel Sambuc 
240433d6423SLionel Sambuc 		if (address != NULL)
241433d6423SLionel Sambuc 		{
242433d6423SLionel Sambuc 			sin.sin_family= AF_INET;
243433d6423SLionel Sambuc 			sin.sin_addr.s_addr= udpoptp->nwuo_remaddr;
244433d6423SLionel Sambuc 			sin.sin_port= udpoptp->nwuo_remport;
245433d6423SLionel Sambuc 			sin.sin_len= sizeof(sin);
246433d6423SLionel Sambuc 			len= *address_len;
247433d6423SLionel Sambuc 			if (len > sizeof(sin))
248433d6423SLionel Sambuc 				len= sizeof(sin);
249433d6423SLionel Sambuc 			memcpy(address, &sin, len);
250433d6423SLionel Sambuc 			*address_len= sizeof(sin);
251433d6423SLionel Sambuc 		}
252433d6423SLionel Sambuc 
253433d6423SLionel Sambuc 		return r;
254433d6423SLionel Sambuc 	}
255433d6423SLionel Sambuc 
256433d6423SLionel Sambuc 	buflen= sizeof(*io_hdrp) + length;
257433d6423SLionel Sambuc 	if (buflen < length)
258433d6423SLionel Sambuc 	{
259433d6423SLionel Sambuc 		/* Overflow */
260433d6423SLionel Sambuc 		errno= EMSGSIZE;
261433d6423SLionel Sambuc 		return -1;
262433d6423SLionel Sambuc 	}
263433d6423SLionel Sambuc 	buf= malloc(buflen);
264433d6423SLionel Sambuc 	if (buf == NULL)
265433d6423SLionel Sambuc 		return -1;
266433d6423SLionel Sambuc 
267433d6423SLionel Sambuc 	r= read(sock, buf, buflen);
268433d6423SLionel Sambuc 	if (r == -1)
269433d6423SLionel Sambuc 	{
270433d6423SLionel Sambuc 		t_errno= errno;
271433d6423SLionel Sambuc #if DEBUG
272433d6423SLionel Sambuc 		fprintf(stderr, "recvfrom(udp): read failed: %s\n",
273433d6423SLionel Sambuc 			strerror(errno));
274433d6423SLionel Sambuc 		fprintf(stderr, "udp opt flags = 0x%x\n", udpoptp->nwuo_flags);
275433d6423SLionel Sambuc #endif
276433d6423SLionel Sambuc 		free(buf);
277433d6423SLionel Sambuc 		errno= t_errno;
278433d6423SLionel Sambuc 		return -1;
279433d6423SLionel Sambuc 	}
280433d6423SLionel Sambuc 
2815dd8da10SDavid van Moolenbroek 	assert((size_t)r >= sizeof(*io_hdrp));
282433d6423SLionel Sambuc 	length= r-sizeof(*io_hdrp);
283433d6423SLionel Sambuc 
284433d6423SLionel Sambuc 	io_hdrp= buf;
285433d6423SLionel Sambuc 	memcpy(buffer, &io_hdrp[1], length);
286433d6423SLionel Sambuc 
287433d6423SLionel Sambuc 	if (address != NULL)
288433d6423SLionel Sambuc 	{
289433d6423SLionel Sambuc 		sin.sin_family= AF_INET;
290433d6423SLionel Sambuc 		sin.sin_addr.s_addr= io_hdrp->uih_src_addr;
291433d6423SLionel Sambuc 		sin.sin_port= io_hdrp->uih_src_port;
292433d6423SLionel Sambuc 		sin.sin_len= sizeof(sin);
293433d6423SLionel Sambuc 		len= *address_len;
294433d6423SLionel Sambuc 		if (len > sizeof(sin))
295433d6423SLionel Sambuc 			len= sizeof(sin);
296433d6423SLionel Sambuc 		memcpy(address, &sin, len);
297433d6423SLionel Sambuc 		*address_len= sizeof(sin);
298433d6423SLionel Sambuc 	}
299433d6423SLionel Sambuc 	free(buf);
300433d6423SLionel Sambuc 	return length;
301433d6423SLionel Sambuc }
302433d6423SLionel Sambuc 
_uds_recvfrom_conn(int sock,void * __restrict buffer,size_t length,int flags,struct sockaddr * __restrict address,socklen_t * __restrict address_len,struct sockaddr_un * uds_addr)303433d6423SLionel Sambuc static ssize_t _uds_recvfrom_conn(int sock, void *__restrict buffer,
304433d6423SLionel Sambuc 	size_t length, int flags, struct sockaddr *__restrict address,
305433d6423SLionel Sambuc 	socklen_t *__restrict address_len, struct sockaddr_un *uds_addr)
306433d6423SLionel Sambuc {
307433d6423SLionel Sambuc 	int r;
308433d6423SLionel Sambuc 	size_t len;
309433d6423SLionel Sambuc 
310433d6423SLionel Sambuc 	/* for connection oriented unix domain sockets (SOCK_STREAM /
311433d6423SLionel Sambuc 	 * SOCK_SEQPACKET)
312433d6423SLionel Sambuc 	 */
313433d6423SLionel Sambuc 
314433d6423SLionel Sambuc 	if (flags != 0)
315433d6423SLionel Sambuc 	{
316433d6423SLionel Sambuc #if DEBUG
317433d6423SLionel Sambuc 		fprintf(stderr, "recvfrom(uds): flags not implemented\n");
318433d6423SLionel Sambuc #endif
319433d6423SLionel Sambuc 		errno= ENOSYS;
320433d6423SLionel Sambuc 		return -1;
321433d6423SLionel Sambuc 	}
322433d6423SLionel Sambuc 
323433d6423SLionel Sambuc 	r = read(sock, buffer, length);
324433d6423SLionel Sambuc 
325433d6423SLionel Sambuc 	if (r >= 0 && address != NULL)
326433d6423SLionel Sambuc 	{
327433d6423SLionel Sambuc 
328433d6423SLionel Sambuc 		len= *address_len;
329433d6423SLionel Sambuc 		if (len > sizeof(struct sockaddr_un))
330433d6423SLionel Sambuc 			len= sizeof(struct sockaddr_un);
331433d6423SLionel Sambuc 		memcpy(address, uds_addr, len);
332433d6423SLionel Sambuc 		*address_len= sizeof(struct sockaddr_un);
333433d6423SLionel Sambuc 	}
334433d6423SLionel Sambuc 
335433d6423SLionel Sambuc 	return r;
336433d6423SLionel Sambuc }
337433d6423SLionel Sambuc 
_uds_recvfrom_dgram(int sock,void * __restrict buffer,size_t length,int flags,struct sockaddr * __restrict address,socklen_t * __restrict address_len)338433d6423SLionel Sambuc static ssize_t _uds_recvfrom_dgram(int sock, void *__restrict buffer,
339433d6423SLionel Sambuc 	size_t length, int flags, struct sockaddr *__restrict address,
340433d6423SLionel Sambuc 	socklen_t *__restrict address_len)
341433d6423SLionel Sambuc {
342433d6423SLionel Sambuc 	int r;
343433d6423SLionel Sambuc 	size_t len;
344433d6423SLionel Sambuc 
345433d6423SLionel Sambuc 	/* for connectionless unix domain sockets (SOCK_DGRAM) */
346433d6423SLionel Sambuc 
347433d6423SLionel Sambuc 	if (flags != 0)
348433d6423SLionel Sambuc 	{
349433d6423SLionel Sambuc #if DEBUG
350433d6423SLionel Sambuc 		fprintf(stderr, "recvfrom(uds): flags not implemented\n");
351433d6423SLionel Sambuc #endif
352433d6423SLionel Sambuc 		errno= ENOSYS;
353433d6423SLionel Sambuc 		return -1;
354433d6423SLionel Sambuc 	}
355433d6423SLionel Sambuc 
356433d6423SLionel Sambuc 	r = read(sock, buffer, length);
357433d6423SLionel Sambuc 
358433d6423SLionel Sambuc 	if (r >= 0 && address != NULL)
359433d6423SLionel Sambuc 	{
360433d6423SLionel Sambuc 		len= *address_len;
361433d6423SLionel Sambuc 		if (len > sizeof(struct sockaddr_un))
362433d6423SLionel Sambuc 			len= sizeof(struct sockaddr_un);
363433d6423SLionel Sambuc 		ioctl(sock, NWIOGUDSFADDR, address);
364433d6423SLionel Sambuc 		*address_len= sizeof(struct sockaddr_un);
365433d6423SLionel Sambuc 	}
366433d6423SLionel Sambuc 
367433d6423SLionel Sambuc 	return r;
368433d6423SLionel Sambuc }
369433d6423SLionel Sambuc 
370