libutil: add O_NOCTTY back to old pty open code
[minix.git] / lib / libc / sys-minix / sendto.c
blobc3c039d1d348b4288bd63b7ad4228123b5059f48
1 #include <sys/cdefs.h>
2 #include "namespace.h"
4 #undef NDEBUG
6 #include <assert.h>
7 #include <errno.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <unistd.h>
12 #include <sys/ioctl.h>
13 #include <sys/socket.h>
14 #include <netinet/in.h>
16 #include <net/gen/in.h>
17 #include <net/gen/tcp.h>
18 #include <net/gen/tcp_io.h>
19 #include <net/gen/udp.h>
20 #include <net/gen/udp_hdr.h>
21 #include <net/gen/udp_io.h>
23 #define DEBUG 0
25 static ssize_t _tcp_sendto(int sock, const void *message, size_t length,
26 int flags, const struct sockaddr *dest_addr, socklen_t dest_len);
27 static ssize_t _udp_sendto(int sock, const void *message, size_t length,
28 int flags, const struct sockaddr *dest_addr, socklen_t dest_len,
29 nwio_udpopt_t *udpoptp);
30 static ssize_t _uds_sendto_conn(int sock, const void *message, size_t length,
31 int flags, const struct sockaddr *dest_addr, socklen_t dest_len);
32 static ssize_t _uds_sendto_dgram(int sock, const void *message, size_t length,
33 int flags, const struct sockaddr *dest_addr, socklen_t dest_len);
35 ssize_t sendto(int sock, const void *message, size_t length, int flags,
36 const struct sockaddr *dest_addr, socklen_t dest_len)
38 int r;
39 nwio_tcpopt_t tcpopt;
40 nwio_udpopt_t udpopt;
41 int uds_sotype = -1;
43 r= ioctl(sock, NWIOGTCPOPT, &tcpopt);
44 if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
46 if (r == -1)
47 return r;
48 return _tcp_sendto(sock, message, length, flags,
49 dest_addr, dest_len);
52 r= ioctl(sock, NWIOGUDPOPT, &udpopt);
53 if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
55 if (r == -1)
56 return r;
57 return _udp_sendto(sock, message, length, flags,
58 dest_addr, dest_len, &udpopt);
61 r= ioctl(sock, NWIOGUDSSOTYPE, &uds_sotype);
62 if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
64 if (r == -1) {
65 return r;
68 if (uds_sotype == SOCK_DGRAM) {
70 return _uds_sendto_dgram(sock, message,
71 length, flags,dest_addr, dest_len);
72 } else {
74 return _uds_sendto_conn(sock, message,
75 length, flags, dest_addr, dest_len);
79 #if DEBUG
80 fprintf(stderr, "sendto: not implemented for fd %d\n", sock);
81 #endif
82 errno= ENOSYS;
83 return -1;
86 static ssize_t _tcp_sendto(int sock, const void *message, size_t length,
87 int flags, const struct sockaddr *dest_addr, socklen_t dest_len)
90 if (flags != 0) {
91 #if DEBUG
92 fprintf(stderr, "sendto(tcp): flags not implemented\n");
93 #endif
94 errno= ENOSYS;
95 return -1;
98 /* Silently ignore destination, if given. */
100 return write(sock, message, length);
103 static ssize_t _udp_sendto(int sock, const void *message, size_t length,
104 int flags, const struct sockaddr *dest_addr, socklen_t dest_len,
105 nwio_udpopt_t *udpoptp)
107 int r, t_errno;
108 size_t buflen;
109 void *buf;
110 struct sockaddr_in *sinp;
111 udp_io_hdr_t *io_hdrp;
113 if (flags)
115 #if DEBUG
116 fprintf(stderr, "sendto(udp): flags not implemented\n");
117 #endif
118 errno= ENOSYS;
119 return -1;
122 if (udpoptp->nwuo_flags & NWUO_RWDATONLY)
123 return write(sock, message, length);
125 if ((udpoptp->nwuo_flags & NWUO_RP_ANY) ||
126 (udpoptp->nwuo_flags & NWUO_RA_ANY))
128 if (!dest_addr)
130 errno= ENOTCONN;
131 return -1;
134 /* Check destination address */
135 if (dest_len < sizeof(*sinp))
137 errno= EINVAL;
138 return -1;
140 sinp= (struct sockaddr_in *) __UNCONST(dest_addr);
141 if (sinp->sin_family != AF_INET)
143 errno= EAFNOSUPPORT;
144 return -1;
148 buflen= sizeof(*io_hdrp) + length;
149 if (buflen < length)
151 /* Overflow */
152 errno= EMSGSIZE;
153 return -1;
155 buf= malloc(buflen);
156 if (buf == NULL)
157 return -1;
159 io_hdrp= buf;
160 io_hdrp->uih_src_addr= 0; /* Unused */
161 io_hdrp->uih_src_port= 0; /* Will cause error if NWUO_LP_ANY */
162 if (udpoptp->nwuo_flags & NWUO_RA_ANY)
163 io_hdrp->uih_dst_addr= sinp->sin_addr.s_addr;
164 else
165 io_hdrp->uih_dst_addr= 0;
166 if (udpoptp->nwuo_flags & NWUO_RP_ANY)
167 io_hdrp->uih_dst_port= sinp->sin_port;
168 else
169 io_hdrp->uih_dst_port= 0;
170 io_hdrp->uih_ip_opt_len= 0;
171 io_hdrp->uih_data_len= 0;
173 memcpy(&io_hdrp[1], message, length);
174 r= write(sock, buf, buflen);
175 if (r == -1)
177 t_errno= errno;
178 free(buf);
179 errno= t_errno;
180 return -1;
182 assert(r == buflen);
183 free(buf);
184 return length;
187 static ssize_t _uds_sendto_conn(int sock, const void *message, size_t length,
188 int flags, const struct sockaddr *dest_addr, socklen_t dest_len)
191 /* for connection oriented unix domain sockets (SOCK_STREAM /
192 * SOCK_SEQPACKET)
195 if (flags != 0) {
196 #if DEBUG
197 fprintf(stderr, "sendto(uds): flags not implemented\n");
198 #endif
199 errno= ENOSYS;
200 return -1;
203 /* Silently ignore destination, if given. */
205 return write(sock, message, length);
208 static ssize_t _uds_sendto_dgram(int sock, const void *message, size_t length,
209 int flags, const struct sockaddr *dest_addr, socklen_t dest_len)
211 int r;
213 /* for connectionless unix domain sockets (SOCK_DGRAM) */
215 if (flags != 0) {
216 #if DEBUG
217 fprintf(stderr, "sendto(uds): flags not implemented\n");
218 #endif
219 errno= ENOSYS;
220 return -1;
223 if (dest_addr == NULL) {
224 errno = EFAULT;
225 return -1;
228 /* set the target address */
229 r= ioctl(sock, NWIOSUDSTADDR, (void *) __UNCONST(dest_addr));
230 if (r == -1) {
231 return r;
234 /* do the send */
235 return write(sock, message, length);