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