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