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