1 #include <sys/cdefs.h> 2 #include "namespace.h" 3 4 #include <errno.h> 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <string.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_recvmsg_conn(int sock, struct msghdr *msg, int flags); 17 static ssize_t _uds_recvmsg_dgram(int sock, struct msghdr *msg, int flags); 18 19 ssize_t recvmsg(int sock, 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_recvmsg_dgram(sock, msg, flags); 37 } else { 38 return _uds_recvmsg_conn(sock, msg, flags); 39 } 40 } 41 42 #if DEBUG 43 fprintf(stderr, "recvmsg: not implemented for fd %d\n", sock); 44 #endif 45 46 errno= ENOSYS; 47 return -1; 48 } 49 50 static ssize_t _uds_recvmsg_conn(int sock, struct msghdr *msg, int flags) 51 { 52 int r, rc; 53 54 if (flags != 0) { 55 #if DEBUG 56 fprintf(stderr, "recvmsg(uds): flags not implemented\n"); 57 #endif 58 errno= ENOSYS; 59 return -1; 60 } 61 62 r= readv(sock, msg->msg_iov, msg->msg_iovlen); 63 64 if (r >= 0 && msg->msg_name && msg->msg_namelen > 0) { 65 getpeername(sock, msg->msg_name, &msg->msg_namelen); 66 } 67 68 /* get control data */ 69 if (r >= 0 && msg->msg_control && msg->msg_controllen > 0) { 70 struct msg_control msg_ctrl; 71 72 memset(&msg_ctrl, '\0', sizeof(struct msg_control)); 73 msg_ctrl.msg_controllen = msg->msg_controllen; 74 rc = ioctl(sock, NWIOGUDSCTRL, &msg_ctrl); 75 if (rc == -1) { 76 return rc; 77 } 78 79 if (msg_ctrl.msg_controllen <= msg->msg_controllen) { 80 memcpy(msg->msg_control, msg_ctrl.msg_control, 81 msg_ctrl.msg_controllen); 82 msg->msg_controllen = msg_ctrl.msg_controllen; 83 } 84 } 85 86 msg->msg_flags = 0; 87 88 return r; 89 } 90 91 static ssize_t _uds_recvmsg_dgram(int sock, struct msghdr *msg, int flags) 92 { 93 int r, rc; 94 95 if (flags != 0) { 96 #if DEBUG 97 fprintf(stderr, "recvmsg(uds): flags not implemented\n"); 98 #endif 99 errno= ENOSYS; 100 return -1; 101 } 102 103 r= readv(sock, msg->msg_iov, msg->msg_iovlen); 104 105 if (r >= 0 && msg->msg_name && 106 msg->msg_namelen >= sizeof(struct sockaddr_un)) 107 { 108 rc= ioctl(sock, NWIOGUDSFADDR, msg->msg_name); 109 if (rc == -1) { 110 return rc; 111 } 112 msg->msg_namelen= sizeof(struct sockaddr_un); 113 } 114 115 /* get control data */ 116 if (r >= 0 && msg->msg_control && msg->msg_controllen > 0) { 117 struct msg_control msg_ctrl; 118 119 memset(&msg_ctrl, '\0', sizeof(struct msg_control)); 120 msg_ctrl.msg_controllen = msg->msg_controllen; 121 rc = ioctl(sock, NWIOGUDSCTRL, &msg_ctrl); 122 if (rc == -1) { 123 return rc; 124 } 125 126 if (msg_ctrl.msg_controllen <= msg->msg_controllen) { 127 memcpy(msg->msg_control, msg_ctrl.msg_control, 128 msg_ctrl.msg_controllen); 129 msg->msg_controllen = msg_ctrl.msg_controllen; 130 } 131 } 132 133 msg->msg_flags = 0; 134 135 return r; 136 } 137