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