custom message type for VM_QUERY_EXIT
[minix3.git] / lib / libc / sys-minix / connect.c
blobdd5b7b7f5ac21c1128f0df15eef3b9384315edb9
1 #include <sys/cdefs.h>
2 #include "namespace.h"
3 #include <minix/config.h>
5 #include <errno.h>
6 #include <fcntl.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <string.h>
11 #include <sys/ioctl.h>
12 #include <sys/socket.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <netinet/in.h>
17 #include <net/gen/in.h>
18 #include <net/gen/tcp.h>
19 #include <net/gen/tcp_io.h>
20 #include <net/gen/udp.h>
21 #include <net/gen/udp_io.h>
23 #include <minix/const.h>
25 #define DEBUG 0
27 static int _tcp_connect(int sock, const struct sockaddr *address,
28 socklen_t address_len, nwio_tcpconf_t *tcpconfp);
29 static int _udp_connect(int sock, const struct sockaddr *address,
30 socklen_t address_len, nwio_udpopt_t *udpoptp);
31 static int _uds_connect(int sock, const struct sockaddr *address,
32 socklen_t address_len);
34 int connect(int sock, const struct sockaddr *address,
35 socklen_t address_len)
37 int r;
38 nwio_tcpconf_t tcpconf;
39 nwio_udpopt_t udpopt;
41 r= ioctl(sock, NWIOGTCPCONF, &tcpconf);
42 if (r != -1 || errno != ENOTTY)
44 if (r == -1)
46 /* Bad file descriptor */
47 return -1;
49 return _tcp_connect(sock, address, address_len, &tcpconf);
52 r= ioctl(sock, NWIOGUDPOPT, &udpopt);
53 if (r != -1 || errno != ENOTTY)
55 if (r == -1)
57 /* Bad file descriptor */
58 return -1;
60 return _udp_connect(sock, address, address_len, &udpopt);
63 r= _uds_connect(sock, address, address_len);
64 if (r != -1 || (errno != ENOTTY && errno != EAFNOSUPPORT))
66 if (r == -1)
68 /* Bad file descriptor */
69 return -1;
72 return r;
75 #if DEBUG
76 fprintf(stderr, "connect: not implemented for fd %d\n", sock);
77 #endif
78 errno= ENOSYS;
79 return -1;
82 static int _tcp_connect(int sock, const struct sockaddr *address,
83 socklen_t address_len, nwio_tcpconf_t *tcpconfp)
85 int r;
86 struct sockaddr_in *sinp;
87 nwio_tcpconf_t tcpconf;
88 nwio_tcpcl_t tcpcl;
90 if (address_len != sizeof(*sinp))
92 errno= EINVAL;
93 return -1;
95 sinp= (struct sockaddr_in *) __UNCONST(address);
96 if (sinp->sin_family != AF_INET)
98 errno= EINVAL;
99 return -1;
101 tcpconf.nwtc_flags= NWTC_SET_RA | NWTC_SET_RP;
102 if ((tcpconfp->nwtc_flags & NWTC_LOCPORT_MASK) == NWTC_LP_UNSET)
103 tcpconf.nwtc_flags |= NWTC_LP_SEL;
104 tcpconf.nwtc_remaddr= sinp->sin_addr.s_addr;
105 tcpconf.nwtc_remport= sinp->sin_port;
107 if (ioctl(sock, NWIOSTCPCONF, &tcpconf) == -1)
109 /* Ignore EISCONN error. The NWIOTCPCONN ioctl will get the
110 * right error.
112 if (errno != EISCONN)
113 return -1;
116 tcpcl.nwtcl_flags= TCF_DEFAULT;
118 r= fcntl(sock, F_GETFL);
119 if (r == 1)
120 return -1;
121 if (r & O_NONBLOCK)
122 tcpcl.nwtcl_flags |= TCF_ASYNCH;
124 r= ioctl(sock, NWIOTCPCONN, &tcpcl);
125 return r;
128 static int _udp_connect(int sock, const struct sockaddr *address,
129 socklen_t address_len, nwio_udpopt_t *udpoptp)
131 int r;
132 struct sockaddr_in *sinp;
133 nwio_udpopt_t udpopt;
135 if (address == NULL)
137 /* Unset remote address */
138 udpopt.nwuo_flags= NWUO_RP_ANY | NWUO_RA_ANY | NWUO_RWDATALL;
140 r= ioctl(sock, NWIOSUDPOPT, &udpopt);
141 return r;
144 if (address_len != sizeof(*sinp))
146 errno= EINVAL;
147 return -1;
149 sinp= (struct sockaddr_in *) __UNCONST(address);
150 if (sinp->sin_family != AF_INET)
152 errno= EINVAL;
153 return -1;
155 udpopt.nwuo_flags= NWUO_RP_SET | NWUO_RA_SET | NWUO_RWDATONLY;
156 if ((udpoptp->nwuo_flags & NWUO_LOCPORT_MASK) == NWUO_LP_ANY)
157 udpopt.nwuo_flags |= NWUO_LP_SEL;
158 udpopt.nwuo_remaddr= sinp->sin_addr.s_addr;
159 udpopt.nwuo_remport= sinp->sin_port;
161 r= ioctl(sock, NWIOSUDPOPT, &udpopt);
162 return r;
165 static int _uds_connect(int sock, const struct sockaddr *address,
166 socklen_t address_len)
169 if (address == NULL) {
170 errno = EFAULT;
171 return -1;
174 /* perform the connect */
175 return ioctl(sock, NWIOSUDSCONN, (void *) __UNCONST(address));