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