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