10 #include <net/netlib.h>
11 #include <sys/ioctl.h>
12 #include <sys/ioc_net.h>
13 #include <sys/socket.h>
19 static int _uds_socketpair(int type
, int protocol
, int sv
[2]);
22 * Create a pair of connected sockets.
25 __socketpair(int domain
, int type
, int protocol
, int sv
[2])
29 memset(&m
, 0, sizeof(m
));
30 m
.m_lc_vfs_socket
.domain
= domain
;
31 m
.m_lc_vfs_socket
.type
= type
;
32 m
.m_lc_vfs_socket
.protocol
= protocol
;
34 if (_syscall(VFS_PROC_NR
, VFS_SOCKETPAIR
, &m
) < 0)
37 sv
[0] = m
.m_vfs_lc_fdpair
.fd0
;
38 sv
[1] = m
.m_vfs_lc_fdpair
.fd1
;
43 socketpair(int domain
, int type
, int protocol
, int sv
[2])
47 r
= __socketpair(domain
, type
, protocol
, sv
);
48 if (r
!= -1 || (errno
!= EAFNOSUPPORT
&& errno
!= ENOSYS
))
52 fprintf(stderr
, "socketpair: domain %d, type %d, protocol %d\n",
53 domain
, type
, protocol
);
56 if (domain
== AF_UNIX
)
57 return _uds_socketpair(type
, protocol
, sv
);
63 static int _uds_socketpair(int type
, int protocol
, int sv
[2])
69 if (type
!= SOCK_STREAM
&& type
!= SOCK_SEQPACKET
) {
77 fprintf(stderr
, "socketpair(uds): bad protocol %d\n", protocol
);
79 errno
= EPROTONOSUPPORT
;
83 /* in this 'for' loop two unconnected sockets are created */
84 for (i
= 0; i
< 2; i
++) {
85 sv
[i
]= open(UDS_DEVICE
, O_RDWR
);
87 int open_errno
= errno
;
90 /* if we failed to open() the 2nd
91 * socket, we need to close the 1st
100 /* set the type for the socket via ioctl
101 * (SOCK_STREAM, SOCK_SEQPACKET, etc)
103 r
= ioctl(sv
[i
], NWIOSUDSTYPE
, &type
);
107 /* if that failed rollback socket creation */
112 /* if we just closed the 2nd socket, we
113 * need to close the 1st
118 /* return the error thrown by the call to ioctl */
124 r
= fstat(sv
[1], &sbuf
);
128 /* if that failed rollback socket creation */
134 /* return the error thrown by the call to fstat */
141 /* connect the sockets sv[0] and sv[1] */
142 r
= ioctl(sv
[0], NWIOSUDSPAIR
, &dev
);
146 /* if that failed rollback socket creation */
152 /* return the error thrown by the call to ioctl */