__aeabi_ldivmod: fix sign logic
[minix.git] / lib / libc / sys-minix / connect.c
blob3ef50854ed0e1be76193ed328a3db49fdb9d80db
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 && errno != EBADIOCTL))
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 && errno != EBADIOCTL))
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 ||
65 (errno != ENOTTY && errno != EBADIOCTL &&
66 errno != EAFNOSUPPORT))
68 if (r == -1)
70 /* Bad file descriptor */
71 return -1;
74 return r;
77 #if DEBUG
78 fprintf(stderr, "connect: not implemented for fd %d\n", sock);
79 #endif
80 errno= ENOSYS;
81 return -1;
84 static int _tcp_connect(int sock, const struct sockaddr *address,
85 socklen_t address_len, nwio_tcpconf_t *tcpconfp)
87 int r;
88 struct sockaddr_in *sinp;
89 nwio_tcpconf_t tcpconf;
90 nwio_tcpcl_t tcpcl;
92 if (address_len != sizeof(*sinp))
94 errno= EINVAL;
95 return -1;
97 sinp= (struct sockaddr_in *) __UNCONST(address);
98 if (sinp->sin_family != AF_INET)
100 errno= EINVAL;
101 return -1;
103 tcpconf.nwtc_flags= NWTC_SET_RA | NWTC_SET_RP;
104 if ((tcpconfp->nwtc_flags & NWTC_LOCPORT_MASK) == NWTC_LP_UNSET)
105 tcpconf.nwtc_flags |= NWTC_LP_SEL;
106 tcpconf.nwtc_remaddr= sinp->sin_addr.s_addr;
107 tcpconf.nwtc_remport= sinp->sin_port;
109 if (ioctl(sock, NWIOSTCPCONF, &tcpconf) == -1)
111 /* Ignore EISCONN error. The NWIOTCPCONN ioctl will get the
112 * right error.
114 if (errno != EISCONN)
115 return -1;
118 tcpcl.nwtcl_flags= TCF_DEFAULT;
120 r= fcntl(sock, F_GETFL);
121 if (r == 1)
122 return -1;
123 if (r & O_NONBLOCK)
124 tcpcl.nwtcl_flags |= TCF_ASYNCH;
126 r= ioctl(sock, NWIOTCPCONN, &tcpcl);
127 return r;
130 static int _udp_connect(int sock, const struct sockaddr *address,
131 socklen_t address_len, nwio_udpopt_t *udpoptp)
133 int r;
134 struct sockaddr_in *sinp;
135 nwio_udpopt_t udpopt;
137 if (address == NULL)
139 /* Unset remote address */
140 udpopt.nwuo_flags= NWUO_RP_ANY | NWUO_RA_ANY | NWUO_RWDATALL;
142 r= ioctl(sock, NWIOSUDPOPT, &udpopt);
143 return r;
146 if (address_len != sizeof(*sinp))
148 errno= EINVAL;
149 return -1;
151 sinp= (struct sockaddr_in *) __UNCONST(address);
152 if (sinp->sin_family != AF_INET)
154 errno= EINVAL;
155 return -1;
157 udpopt.nwuo_flags= NWUO_RP_SET | NWUO_RA_SET | NWUO_RWDATONLY;
158 if ((udpoptp->nwuo_flags & NWUO_LOCPORT_MASK) == NWUO_LP_ANY)
159 udpopt.nwuo_flags |= NWUO_LP_SEL;
160 udpopt.nwuo_remaddr= sinp->sin_addr.s_addr;
161 udpopt.nwuo_remport= sinp->sin_port;
163 r= ioctl(sock, NWIOSUDPOPT, &udpopt);
164 return r;
167 static int _uds_connect(int sock, const struct sockaddr *address,
168 socklen_t address_len)
171 if (address == NULL) {
172 errno = EFAULT;
173 return -1;
176 /* perform the connect */
177 return ioctl(sock, NWIOSUDSCONN, (void *) __UNCONST(address));