xref: /minix/minix/lib/libc/sys/sendmsg.c (revision e3b78ef1)
1 #include <sys/cdefs.h>
2 #include "namespace.h"
3 
4 #include <errno.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <sys/ioctl.h>
8 #include <sys/ioc_net.h>
9 #include <sys/socket.h>
10 #include <sys/types.h>
11 #include <sys/un.h>
12 
13 #define DEBUG 0
14 
15 static ssize_t _uds_sendmsg_conn(int sock, const struct msghdr *msg,
16 	int flags);
17 static ssize_t _uds_sendmsg_dgram(int sock, const struct msghdr *msg,
18 	int flags);
19 
20 ssize_t sendmsg(int sock, const struct msghdr *msg, int flags)
21 {
22 	int r;
23 	int uds_sotype;
24 
25 	if (msg == NULL) {
26 		errno= EFAULT;
27 		return -1;
28 	}
29 
30 	r= ioctl(sock, NWIOGUDSSOTYPE, &uds_sotype);
31 	if (r != -1 || errno != ENOTTY) {
32 		if (r == -1) {
33 			return r;
34 		}
35 
36 		if (uds_sotype == SOCK_DGRAM) {
37 			return _uds_sendmsg_dgram(sock, msg, flags);
38 		} else {
39 			return _uds_sendmsg_conn(sock, msg, flags);
40 		}
41 
42 	}
43 
44 #if DEBUG
45 	fprintf(stderr, "sendmsg: not implemented for fd %d\n", sock);
46 #endif
47 
48 	errno= ENOSYS;
49 	return -1;
50 }
51 
52 static ssize_t _uds_sendmsg_conn(int sock, const struct msghdr *msg,
53 	int flags)
54 {
55 	struct msg_control msg_ctrl;
56 	int r;
57 
58 	if (flags != 0) {
59 #if DEBUG
60 		fprintf(stderr, "sendmsg(uds): flags not implemented\n");
61 #endif
62 		errno= ENOSYS;
63 		return -1;
64 
65 	}
66 
67 	/* grab the control data */
68 	memset(&msg_ctrl, '\0', sizeof(struct msg_control));
69 	if (msg->msg_controllen > MSG_CONTROL_MAX) {
70 		errno = ENOMEM;
71 		return -1;
72 	} else if (msg->msg_controllen > 0) {
73 		memcpy(&msg_ctrl.msg_control, msg->msg_control,
74 							msg->msg_controllen);
75 	}
76 	msg_ctrl.msg_controllen = msg->msg_controllen;
77 
78 	/* send the control data to PFS */
79 	r= ioctl(sock, NWIOSUDSCTRL, (void *) &msg_ctrl);
80 	if (r == -1) {
81 		return r;
82 	}
83 
84 	/* Silently ignore destination, if given. */
85 
86 	return writev(sock, msg->msg_iov, msg->msg_iovlen);
87 }
88 
89 static ssize_t _uds_sendmsg_dgram(int sock, const struct msghdr *msg,
90 	int flags)
91 {
92 	struct msg_control msg_ctrl;
93 	struct sockaddr_un *dest_addr;
94 	int r;
95 
96 	if (flags != 0) {
97 #if DEBUG
98 		fprintf(stderr, "sendmsg(uds): flags not implemented\n");
99 #endif
100 		errno= ENOSYS;
101 		return -1;
102 
103 	}
104 
105 	dest_addr = msg->msg_name;
106 	if (dest_addr == NULL) {
107 		errno= EFAULT;
108 		return -1;
109 	}
110 
111 	/* set the target address */
112 	r= ioctl(sock, NWIOSUDSTADDR, (void *) dest_addr);
113 	if (r == -1) {
114 		return r;
115 	}
116 
117 	/* grab the control data */
118 	memset(&msg_ctrl, '\0', sizeof(struct msg_control));
119 	if (msg->msg_controllen > MSG_CONTROL_MAX) {
120 		errno = ENOMEM;
121 		return -1;
122 	} else if (msg->msg_controllen > 0) {
123 		memcpy(&msg_ctrl.msg_control, msg->msg_control,
124 							msg->msg_controllen);
125 	}
126 	msg_ctrl.msg_controllen = msg->msg_controllen;
127 
128 	/* send the control data to PFS */
129 	r= ioctl(sock, NWIOSUDSCTRL, (void *) &msg_ctrl);
130 	if (r == -1) {
131 		return r;
132 	}
133 
134 	/* do the send */
135 	return writev(sock, msg->msg_iov, msg->msg_iovlen);
136 }
137