Commit 3532fa7402cda16f7b95261b0339c58630051f0b
1 parent
480c1cdb
mips socket calls (initial patch by Raphael Rigo)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2006 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
409 additions
and
81 deletions
linux-user/socket.h
0 → 100644
| 1 | + | |
| 2 | +#if defined(TARGET_MIPS) | |
| 3 | + // MIPS special values for constants | |
| 4 | + | |
| 5 | + /* | |
| 6 | + * For setsockopt(2) | |
| 7 | + * | |
| 8 | + * This defines are ABI conformant as far as Linux supports these ... | |
| 9 | + */ | |
| 10 | + #define TARGET_SOL_SOCKET 0xffff | |
| 11 | + | |
| 12 | + #define TARGET_SO_DEBUG 0x0001 /* Record debugging information. */ | |
| 13 | + #define TARGET_SO_REUSEADDR 0x0004 /* Allow reuse of local addresses. */ | |
| 14 | + #define TARGET_SO_KEEPALIVE 0x0008 /* Keep connections alive and send | |
| 15 | + SIGPIPE when they die. */ | |
| 16 | + #define TARGET_SO_DONTROUTE 0x0010 /* Don't do local routing. */ | |
| 17 | + #define TARGET_SO_BROADCAST 0x0020 /* Allow transmission of | |
| 18 | + broadcast messages. */ | |
| 19 | + #define TARGET_SO_LINGER 0x0080 /* Block on close of a reliable | |
| 20 | + socket to transmit pending data. */ | |
| 21 | + #define TARGET_SO_OOBINLINE 0x0100 /* Receive out-of-band data in-band. */ | |
| 22 | + #if 0 | |
| 23 | + To add: #define TARGET_SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */ | |
| 24 | + #endif | |
| 25 | + | |
| 26 | + #define TARGET_SO_TYPE 0x1008 /* Compatible name for SO_STYLE. */ | |
| 27 | + #define TARGET_SO_STYLE SO_TYPE /* Synonym */ | |
| 28 | + #define TARGET_SO_ERROR 0x1007 /* get error status and clear */ | |
| 29 | + #define TARGET_SO_SNDBUF 0x1001 /* Send buffer size. */ | |
| 30 | + #define TARGET_SO_RCVBUF 0x1002 /* Receive buffer. */ | |
| 31 | + #define TARGET_SO_SNDLOWAT 0x1003 /* send low-water mark */ | |
| 32 | + #define TARGET_SO_RCVLOWAT 0x1004 /* receive low-water mark */ | |
| 33 | + #define TARGET_SO_SNDTIMEO 0x1005 /* send timeout */ | |
| 34 | + #define TARGET_SO_RCVTIMEO 0x1006 /* receive timeout */ | |
| 35 | + #define TARGET_SO_ACCEPTCONN 0x1009 | |
| 36 | + | |
| 37 | + /* linux-specific, might as well be the same as on i386 */ | |
| 38 | + #define TARGET_SO_NO_CHECK 11 | |
| 39 | + #define TARGET_SO_PRIORITY 12 | |
| 40 | + #define TARGET_SO_BSDCOMPAT 14 | |
| 41 | + | |
| 42 | + #define TARGET_SO_PASSCRED 17 | |
| 43 | + #define TARGET_SO_PEERCRED 18 | |
| 44 | + | |
| 45 | + /* Security levels - as per NRL IPv6 - don't actually do anything */ | |
| 46 | + #define TARGET_SO_SECURITY_AUTHENTICATION 22 | |
| 47 | + #define TARGET_SO_SECURITY_ENCRYPTION_TRANSPORT 23 | |
| 48 | + #define TARGET_SO_SECURITY_ENCRYPTION_NETWORK 24 | |
| 49 | + | |
| 50 | + #define TARGET_SO_BINDTODEVICE 25 | |
| 51 | + | |
| 52 | + /* Socket filtering */ | |
| 53 | + #define TARGET_SO_ATTACH_FILTER 26 | |
| 54 | + #define TARGET_SO_DETACH_FILTER 27 | |
| 55 | + | |
| 56 | + #define TARGET_SO_PEERNAME 28 | |
| 57 | + #define TARGET_SO_TIMESTAMP 29 | |
| 58 | + #define SCM_TIMESTAMP SO_TIMESTAMP | |
| 59 | + | |
| 60 | + #define TARGET_SO_PEERSEC 30 | |
| 61 | + #define TARGET_SO_SNDBUFFORCE 31 | |
| 62 | + #define TARGET_SO_RCVBUFFORCE 33 | |
| 63 | + | |
| 64 | + /** sock_type - Socket types | |
| 65 | + * | |
| 66 | + * Please notice that for binary compat reasons MIPS has to | |
| 67 | + * override the enum sock_type in include/linux/net.h, so | |
| 68 | + * we define ARCH_HAS_SOCKET_TYPES here. | |
| 69 | + * | |
| 70 | + * @SOCK_DGRAM - datagram (conn.less) socket | |
| 71 | + * @SOCK_STREAM - stream (connection) socket | |
| 72 | + * @SOCK_RAW - raw socket | |
| 73 | + * @SOCK_RDM - reliably-delivered message | |
| 74 | + * @SOCK_SEQPACKET - sequential packet socket | |
| 75 | + * @SOCK_PACKET - linux specific way of getting packets at the dev level. | |
| 76 | + * For writing rarp and other similar things on the user level. | |
| 77 | + */ | |
| 78 | + enum sock_type { | |
| 79 | + TARGET_SOCK_DGRAM = 1, | |
| 80 | + TARGET_SOCK_STREAM = 2, | |
| 81 | + TARGET_SOCK_RAW = 3, | |
| 82 | + TARGET_SOCK_RDM = 4, | |
| 83 | + TARGET_SOCK_SEQPACKET = 5, | |
| 84 | + TARGET_SOCK_DCCP = 6, | |
| 85 | + TARGET_SOCK_PACKET = 10, | |
| 86 | + }; | |
| 87 | + | |
| 88 | + #define TARGET_SOCK_MAX (SOCK_PACKET + 1) | |
| 89 | + | |
| 90 | +#else | |
| 91 | + | |
| 92 | + /* For setsockopt(2) */ | |
| 93 | + #define TARGET_SOL_SOCKET 1 | |
| 94 | + | |
| 95 | + #define TARGET_SO_DEBUG 1 | |
| 96 | + #define TARGET_SO_REUSEADDR 2 | |
| 97 | + #define TARGET_SO_TYPE 3 | |
| 98 | + #define TARGET_SO_ERROR 4 | |
| 99 | + #define TARGET_SO_DONTROUTE 5 | |
| 100 | + #define TARGET_SO_BROADCAST 6 | |
| 101 | + #define TARGET_SO_SNDBUF 7 | |
| 102 | + #define TARGET_SO_RCVBUF 8 | |
| 103 | + #define TARGET_SO_SNDBUFFORCE 32 | |
| 104 | + #define TARGET_SO_RCVBUFFORCE 33 | |
| 105 | + #define TARGET_SO_KEEPALIVE 9 | |
| 106 | + #define TARGET_SO_OOBINLINE 10 | |
| 107 | + #define TARGET_SO_NO_CHECK 11 | |
| 108 | + #define TARGET_SO_PRIORITY 12 | |
| 109 | + #define TARGET_SO_LINGER 13 | |
| 110 | + #define TARGET_SO_BSDCOMPAT 14 | |
| 111 | + /* To add :#define TARGET_SO_REUSEPORT 15 */ | |
| 112 | + #define TARGET_SO_PASSCRED 16 | |
| 113 | + #define TARGET_SO_PEERCRED 17 | |
| 114 | + #define TARGET_SO_RCVLOWAT 18 | |
| 115 | + #define TARGET_SO_SNDLOWAT 19 | |
| 116 | + #define TARGET_SO_RCVTIMEO 20 | |
| 117 | + #define TARGET_SO_SNDTIMEO 21 | |
| 118 | + | |
| 119 | + /* Security levels - as per NRL IPv6 - don't actually do anything */ | |
| 120 | + #define TARGET_SO_SECURITY_AUTHENTICATION 22 | |
| 121 | + #define TARGET_SO_SECURITY_ENCRYPTION_TRANSPORT 23 | |
| 122 | + #define TARGET_SO_SECURITY_ENCRYPTION_NETWORK 24 | |
| 123 | + | |
| 124 | + #define TARGET_SO_BINDTODEVICE 25 | |
| 125 | + | |
| 126 | + /* Socket filtering */ | |
| 127 | + #define TARGET_SO_ATTACH_FILTER 26 | |
| 128 | + #define TARGET_SO_DETACH_FILTER 27 | |
| 129 | + | |
| 130 | + #define TARGET_SO_PEERNAME 28 | |
| 131 | + #define TARGET_SO_TIMESTAMP 29 | |
| 132 | + #define TARGET_SCM_TIMESTAMP TARGET_SO_TIMESTAMP | |
| 133 | + | |
| 134 | + #define TARGET_SO_ACCEPTCONN 30 | |
| 135 | + | |
| 136 | + #define TARGET_SO_PEERSEC 31 | |
| 137 | + | |
| 138 | +#endif | ... | ... |
linux-user/syscall.c
| ... | ... | @@ -446,7 +446,7 @@ static inline void target_to_host_cmsg(struct msghdr *msgh, |
| 446 | 446 | cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type); |
| 447 | 447 | cmsg->cmsg_len = CMSG_LEN(len); |
| 448 | 448 | |
| 449 | - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) { | |
| 449 | + if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) { | |
| 450 | 450 | gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type); |
| 451 | 451 | memcpy(data, target_data, len); |
| 452 | 452 | } else { |
| ... | ... | @@ -490,7 +490,7 @@ static inline void host_to_target_cmsg(struct target_msghdr *target_msgh, |
| 490 | 490 | target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type); |
| 491 | 491 | target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len)); |
| 492 | 492 | |
| 493 | - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) { | |
| 493 | + if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) { | |
| 494 | 494 | gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type); |
| 495 | 495 | memcpy(target_data, data, len); |
| 496 | 496 | } else { |
| ... | ... | @@ -552,38 +552,74 @@ static long do_setsockopt(int sockfd, int level, int optname, |
| 552 | 552 | goto unimplemented; |
| 553 | 553 | } |
| 554 | 554 | break; |
| 555 | - case SOL_SOCKET: | |
| 555 | + case TARGET_SOL_SOCKET: | |
| 556 | 556 | switch (optname) { |
| 557 | 557 | /* Options with 'int' argument. */ |
| 558 | - case SO_DEBUG: | |
| 559 | - case SO_REUSEADDR: | |
| 560 | - case SO_TYPE: | |
| 561 | - case SO_ERROR: | |
| 562 | - case SO_DONTROUTE: | |
| 563 | - case SO_BROADCAST: | |
| 564 | - case SO_SNDBUF: | |
| 565 | - case SO_RCVBUF: | |
| 566 | - case SO_KEEPALIVE: | |
| 567 | - case SO_OOBINLINE: | |
| 568 | - case SO_NO_CHECK: | |
| 569 | - case SO_PRIORITY: | |
| 558 | + case TARGET_SO_DEBUG: | |
| 559 | + optname = SO_DEBUG; | |
| 560 | + break; | |
| 561 | + case TARGET_SO_REUSEADDR: | |
| 562 | + optname = SO_REUSEADDR; | |
| 563 | + break; | |
| 564 | + case TARGET_SO_TYPE: | |
| 565 | + optname = SO_TYPE; | |
| 566 | + break; | |
| 567 | + case TARGET_SO_ERROR: | |
| 568 | + optname = SO_ERROR; | |
| 569 | + break; | |
| 570 | + case TARGET_SO_DONTROUTE: | |
| 571 | + optname = SO_DONTROUTE; | |
| 572 | + break; | |
| 573 | + case TARGET_SO_BROADCAST: | |
| 574 | + optname = SO_BROADCAST; | |
| 575 | + break; | |
| 576 | + case TARGET_SO_SNDBUF: | |
| 577 | + optname = SO_SNDBUF; | |
| 578 | + break; | |
| 579 | + case TARGET_SO_RCVBUF: | |
| 580 | + optname = SO_RCVBUF; | |
| 581 | + break; | |
| 582 | + case TARGET_SO_KEEPALIVE: | |
| 583 | + optname = SO_KEEPALIVE; | |
| 584 | + break; | |
| 585 | + case TARGET_SO_OOBINLINE: | |
| 586 | + optname = SO_OOBINLINE; | |
| 587 | + break; | |
| 588 | + case TARGET_SO_NO_CHECK: | |
| 589 | + optname = SO_NO_CHECK; | |
| 590 | + break; | |
| 591 | + case TARGET_SO_PRIORITY: | |
| 592 | + optname = SO_PRIORITY; | |
| 593 | + break; | |
| 570 | 594 | #ifdef SO_BSDCOMPAT |
| 571 | - case SO_BSDCOMPAT: | |
| 572 | -#endif | |
| 573 | - case SO_PASSCRED: | |
| 574 | - case SO_TIMESTAMP: | |
| 575 | - case SO_RCVLOWAT: | |
| 576 | - case SO_RCVTIMEO: | |
| 577 | - case SO_SNDTIMEO: | |
| 578 | - if (optlen < sizeof(uint32_t)) | |
| 579 | - return -EINVAL; | |
| 580 | - | |
| 581 | - val = tget32(optval); | |
| 582 | - ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); | |
| 595 | + case TARGET_SO_BSDCOMPAT: | |
| 596 | + optname = SO_BSDCOMPAT; | |
| 597 | + break; | |
| 598 | +#endif | |
| 599 | + case TARGET_SO_PASSCRED: | |
| 600 | + optname = SO_PASSCRED; | |
| 601 | + break; | |
| 602 | + case TARGET_SO_TIMESTAMP: | |
| 603 | + optname = SO_TIMESTAMP; | |
| 604 | + break; | |
| 605 | + case TARGET_SO_RCVLOWAT: | |
| 606 | + optname = SO_RCVLOWAT; | |
| 607 | + break; | |
| 608 | + case TARGET_SO_RCVTIMEO: | |
| 609 | + optname = SO_RCVTIMEO; | |
| 610 | + break; | |
| 611 | + case TARGET_SO_SNDTIMEO: | |
| 612 | + optname = SO_SNDTIMEO; | |
| 613 | + break; | |
| 583 | 614 | break; |
| 584 | 615 | default: |
| 585 | 616 | goto unimplemented; |
| 586 | 617 | } |
| 618 | + if (optlen < sizeof(uint32_t)) | |
| 619 | + return -EINVAL; | |
| 620 | + | |
| 621 | + val = tget32(optval); | |
| 622 | + ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val))); | |
| 587 | 623 | break; |
| 588 | 624 | default: |
| 589 | 625 | unimplemented: |
| ... | ... | @@ -599,13 +635,14 @@ static long do_getsockopt(int sockfd, int level, int optname, |
| 599 | 635 | int len, lv, val, ret; |
| 600 | 636 | |
| 601 | 637 | switch(level) { |
| 602 | - case SOL_SOCKET: | |
| 638 | + case TARGET_SOL_SOCKET: | |
| 639 | + level = SOL_SOCKET; | |
| 603 | 640 | switch (optname) { |
| 604 | - case SO_LINGER: | |
| 605 | - case SO_RCVTIMEO: | |
| 606 | - case SO_SNDTIMEO: | |
| 607 | - case SO_PEERCRED: | |
| 608 | - case SO_PEERNAME: | |
| 641 | + case TARGET_SO_LINGER: | |
| 642 | + case TARGET_SO_RCVTIMEO: | |
| 643 | + case TARGET_SO_SNDTIMEO: | |
| 644 | + case TARGET_SO_PEERCRED: | |
| 645 | + case TARGET_SO_PEERNAME: | |
| 609 | 646 | /* These don't just return a single integer */ |
| 610 | 647 | goto unimplemented; |
| 611 | 648 | default: |
| ... | ... | @@ -711,6 +748,94 @@ static void unlock_iovec(struct iovec *vec, target_ulong target_addr, |
| 711 | 748 | unlock_user (target_vec, target_addr, 0); |
| 712 | 749 | } |
| 713 | 750 | |
| 751 | +static long do_socket(int domain, int type, int protocol) | |
| 752 | +{ | |
| 753 | +#if defined(TARGET_MIPS) | |
| 754 | + switch(type) { | |
| 755 | + case TARGET_SOCK_DGRAM: | |
| 756 | + type = SOCK_DGRAM; | |
| 757 | + break; | |
| 758 | + case TARGET_SOCK_STREAM: | |
| 759 | + type = SOCK_STREAM; | |
| 760 | + break; | |
| 761 | + case TARGET_SOCK_RAW: | |
| 762 | + type = SOCK_RAW; | |
| 763 | + break; | |
| 764 | + case TARGET_SOCK_RDM: | |
| 765 | + type = SOCK_RDM; | |
| 766 | + break; | |
| 767 | + case TARGET_SOCK_SEQPACKET: | |
| 768 | + type = SOCK_SEQPACKET; | |
| 769 | + break; | |
| 770 | + case TARGET_SOCK_PACKET: | |
| 771 | + type = SOCK_PACKET; | |
| 772 | + break; | |
| 773 | + } | |
| 774 | +#endif | |
| 775 | + return get_errno(socket(domain, type, protocol)); | |
| 776 | +} | |
| 777 | + | |
| 778 | +static long do_bind(int sockfd, target_ulong target_addr, | |
| 779 | + socklen_t addrlen) | |
| 780 | +{ | |
| 781 | + void *addr = alloca(addrlen); | |
| 782 | + | |
| 783 | + target_to_host_sockaddr(addr, target_addr, addrlen); | |
| 784 | + return get_errno(bind(sockfd, addr, addrlen)); | |
| 785 | +} | |
| 786 | + | |
| 787 | +static long do_connect(int sockfd, target_ulong target_addr, | |
| 788 | + socklen_t addrlen) | |
| 789 | +{ | |
| 790 | + void *addr = alloca(addrlen); | |
| 791 | + | |
| 792 | + target_to_host_sockaddr(addr, target_addr, addrlen); | |
| 793 | + return get_errno(connect(sockfd, addr, addrlen)); | |
| 794 | +} | |
| 795 | + | |
| 796 | +static long do_sendrecvmsg(int fd, target_ulong target_msg, | |
| 797 | + int flags, int send) | |
| 798 | +{ | |
| 799 | + long ret; | |
| 800 | + struct target_msghdr *msgp; | |
| 801 | + struct msghdr msg; | |
| 802 | + int count; | |
| 803 | + struct iovec *vec; | |
| 804 | + target_ulong target_vec; | |
| 805 | + | |
| 806 | + lock_user_struct(msgp, target_msg, 1); | |
| 807 | + if (msgp->msg_name) { | |
| 808 | + msg.msg_namelen = tswap32(msgp->msg_namelen); | |
| 809 | + msg.msg_name = alloca(msg.msg_namelen); | |
| 810 | + target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name), | |
| 811 | + msg.msg_namelen); | |
| 812 | + } else { | |
| 813 | + msg.msg_name = NULL; | |
| 814 | + msg.msg_namelen = 0; | |
| 815 | + } | |
| 816 | + msg.msg_controllen = 2 * tswapl(msgp->msg_controllen); | |
| 817 | + msg.msg_control = alloca(msg.msg_controllen); | |
| 818 | + msg.msg_flags = tswap32(msgp->msg_flags); | |
| 819 | + | |
| 820 | + count = tswapl(msgp->msg_iovlen); | |
| 821 | + vec = alloca(count * sizeof(struct iovec)); | |
| 822 | + target_vec = tswapl(msgp->msg_iov); | |
| 823 | + lock_iovec(vec, target_vec, count, send); | |
| 824 | + msg.msg_iovlen = count; | |
| 825 | + msg.msg_iov = vec; | |
| 826 | + | |
| 827 | + if (send) { | |
| 828 | + target_to_host_cmsg(&msg, msgp); | |
| 829 | + ret = get_errno(sendmsg(fd, &msg, flags)); | |
| 830 | + } else { | |
| 831 | + ret = get_errno(recvmsg(fd, &msg, flags)); | |
| 832 | + if (!is_error(ret)) | |
| 833 | + host_to_target_cmsg(msgp, &msg); | |
| 834 | + } | |
| 835 | + unlock_iovec(vec, target_vec, count, !send); | |
| 836 | + return ret; | |
| 837 | +} | |
| 838 | + | |
| 714 | 839 | static long do_socketcall(int num, target_ulong vptr) |
| 715 | 840 | { |
| 716 | 841 | long ret; |
| ... | ... | @@ -722,8 +847,7 @@ static long do_socketcall(int num, target_ulong vptr) |
| 722 | 847 | int domain = tgetl(vptr); |
| 723 | 848 | int type = tgetl(vptr + n); |
| 724 | 849 | int protocol = tgetl(vptr + 2 * n); |
| 725 | - | |
| 726 | - ret = get_errno(socket(domain, type, protocol)); | |
| 850 | + ret = do_socket(domain, type, protocol); | |
| 727 | 851 | } |
| 728 | 852 | break; |
| 729 | 853 | case SOCKOP_bind: |
| ... | ... | @@ -731,10 +855,7 @@ static long do_socketcall(int num, target_ulong vptr) |
| 731 | 855 | int sockfd = tgetl(vptr); |
| 732 | 856 | target_ulong target_addr = tgetl(vptr + n); |
| 733 | 857 | socklen_t addrlen = tgetl(vptr + 2 * n); |
| 734 | - void *addr = alloca(addrlen); | |
| 735 | - | |
| 736 | - target_to_host_sockaddr(addr, target_addr, addrlen); | |
| 737 | - ret = get_errno(bind(sockfd, addr, addrlen)); | |
| 858 | + ret = do_bind(sockfd, target_addr, addrlen); | |
| 738 | 859 | } |
| 739 | 860 | break; |
| 740 | 861 | case SOCKOP_connect: |
| ... | ... | @@ -742,17 +863,13 @@ static long do_socketcall(int num, target_ulong vptr) |
| 742 | 863 | int sockfd = tgetl(vptr); |
| 743 | 864 | target_ulong target_addr = tgetl(vptr + n); |
| 744 | 865 | socklen_t addrlen = tgetl(vptr + 2 * n); |
| 745 | - void *addr = alloca(addrlen); | |
| 746 | - | |
| 747 | - target_to_host_sockaddr(addr, target_addr, addrlen); | |
| 748 | - ret = get_errno(connect(sockfd, addr, addrlen)); | |
| 866 | + ret = do_connect(sockfd, target_addr, addrlen); | |
| 749 | 867 | } |
| 750 | 868 | break; |
| 751 | 869 | case SOCKOP_listen: |
| 752 | 870 | { |
| 753 | 871 | int sockfd = tgetl(vptr); |
| 754 | 872 | int backlog = tgetl(vptr + n); |
| 755 | - | |
| 756 | 873 | ret = get_errno(listen(sockfd, backlog)); |
| 757 | 874 | } |
| 758 | 875 | break; |
| ... | ... | @@ -895,46 +1012,14 @@ static long do_socketcall(int num, target_ulong vptr) |
| 895 | 1012 | { |
| 896 | 1013 | int fd; |
| 897 | 1014 | target_ulong target_msg; |
| 898 | - struct target_msghdr *msgp; | |
| 899 | - struct msghdr msg; | |
| 900 | - int flags, count; | |
| 901 | - struct iovec *vec; | |
| 902 | - target_ulong target_vec; | |
| 903 | - int send = (num == SOCKOP_sendmsg); | |
| 904 | - | |
| 905 | - target_msg = tgetl(vptr + n); | |
| 906 | - lock_user_struct(msgp, target_msg, 1); | |
| 907 | - if (msgp->msg_name) { | |
| 908 | - msg.msg_namelen = tswap32(msgp->msg_namelen); | |
| 909 | - msg.msg_name = alloca(msg.msg_namelen); | |
| 910 | - target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name), | |
| 911 | - msg.msg_namelen); | |
| 912 | - } else { | |
| 913 | - msg.msg_name = NULL; | |
| 914 | - msg.msg_namelen = 0; | |
| 915 | - } | |
| 916 | - msg.msg_controllen = 2 * tswapl(msgp->msg_controllen); | |
| 917 | - msg.msg_control = alloca(msg.msg_controllen); | |
| 918 | - msg.msg_flags = tswap32(msgp->msg_flags); | |
| 919 | - | |
| 920 | - count = tswapl(msgp->msg_iovlen); | |
| 921 | - vec = alloca(count * sizeof(struct iovec)); | |
| 922 | - target_vec = tswapl(msgp->msg_iov); | |
| 923 | - lock_iovec(vec, target_vec, count, send); | |
| 924 | - msg.msg_iovlen = count; | |
| 925 | - msg.msg_iov = vec; | |
| 1015 | + int flags; | |
| 926 | 1016 | |
| 927 | 1017 | fd = tgetl(vptr); |
| 1018 | + target_msg = tgetl(vptr + n); | |
| 928 | 1019 | flags = tgetl(vptr + 2 * n); |
| 929 | - if (send) { | |
| 930 | - target_to_host_cmsg(&msg, msgp); | |
| 931 | - ret = get_errno(sendmsg(fd, &msg, flags)); | |
| 932 | - } else { | |
| 933 | - ret = get_errno(recvmsg(fd, &msg, flags)); | |
| 934 | - if (!is_error(ret)) | |
| 935 | - host_to_target_cmsg(msgp, &msg); | |
| 936 | - } | |
| 937 | - unlock_iovec(vec, target_vec, count, !send); | |
| 1020 | + | |
| 1021 | + ret = do_sendrecvmsg(fd, target_msg, flags, | |
| 1022 | + (num == SOCKOP_sendmsg)); | |
| 938 | 1023 | } |
| 939 | 1024 | break; |
| 940 | 1025 | case SOCKOP_setsockopt: |
| ... | ... | @@ -967,6 +1052,22 @@ static long do_socketcall(int num, target_ulong vptr) |
| 967 | 1052 | return ret; |
| 968 | 1053 | } |
| 969 | 1054 | |
| 1055 | +/* XXX: suppress this function and call directly the related socket | |
| 1056 | + functions */ | |
| 1057 | +static long do_socketcallwrapper(int num, long arg1, long arg2, long arg3, | |
| 1058 | + long arg4, long arg5, long arg6) | |
| 1059 | +{ | |
| 1060 | + target_long args[6]; | |
| 1061 | + | |
| 1062 | + tputl(args, arg1); | |
| 1063 | + tputl(args+1, arg2); | |
| 1064 | + tputl(args+2, arg3); | |
| 1065 | + tputl(args+3, arg4); | |
| 1066 | + tputl(args+4, arg5); | |
| 1067 | + tputl(args+5, arg6); | |
| 1068 | + | |
| 1069 | + return do_socketcall(num, (target_ulong) args); | |
| 1070 | +} | |
| 970 | 1071 | |
| 971 | 1072 | #define N_SHM_REGIONS 32 |
| 972 | 1073 | |
| ... | ... | @@ -2616,6 +2717,93 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, |
| 2616 | 2717 | case TARGET_NR_socketcall: |
| 2617 | 2718 | ret = do_socketcall(arg1, arg2); |
| 2618 | 2719 | break; |
| 2720 | + | |
| 2721 | +#ifdef TARGET_NR_accept | |
| 2722 | + case TARGET_NR_accept: | |
| 2723 | + ret = do_socketcallwrapper(SOCKOP_accept, arg1, arg2, arg3, arg4, arg5, arg6); | |
| 2724 | + break; | |
| 2725 | +#endif | |
| 2726 | +#ifdef TARGET_NR_bind | |
| 2727 | + case TARGET_NR_bind: | |
| 2728 | + ret = do_bind(arg1, arg2, arg3); | |
| 2729 | + break; | |
| 2730 | +#endif | |
| 2731 | +#ifdef TARGET_NR_connect | |
| 2732 | + case TARGET_NR_connect: | |
| 2733 | + ret = do_connect(arg1, arg2, arg3); | |
| 2734 | + break; | |
| 2735 | +#endif | |
| 2736 | +#ifdef TARGET_NR_getpeername | |
| 2737 | + case TARGET_NR_getpeername: | |
| 2738 | + ret = do_socketcallwrapper(SOCKOP_getpeername, arg1, arg2, arg3, arg4, arg5, arg6); | |
| 2739 | + break; | |
| 2740 | +#endif | |
| 2741 | +#ifdef TARGET_NR_getsockname | |
| 2742 | + case TARGET_NR_getsockname: | |
| 2743 | + ret = do_socketcallwrapper(SOCKOP_getsockname, arg1, arg2, arg3, arg4, arg5, arg6); | |
| 2744 | + break; | |
| 2745 | +#endif | |
| 2746 | +#ifdef TARGET_NR_getsockopt | |
| 2747 | + case TARGET_NR_getsockopt: | |
| 2748 | + ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5); | |
| 2749 | + break; | |
| 2750 | +#endif | |
| 2751 | +#ifdef TARGET_NR_listen | |
| 2752 | + case TARGET_NR_listen: | |
| 2753 | + ret = do_socketcallwrapper(SOCKOP_listen, arg1, arg2, arg3, arg4, arg5, arg6); | |
| 2754 | + break; | |
| 2755 | +#endif | |
| 2756 | +#ifdef TARGET_NR_recv | |
| 2757 | + case TARGET_NR_recv: | |
| 2758 | + ret = do_socketcallwrapper(SOCKOP_recv, arg1, arg2, arg3, arg4, arg5, arg6); | |
| 2759 | + break; | |
| 2760 | +#endif | |
| 2761 | +#ifdef TARGET_NR_recvfrom | |
| 2762 | + case TARGET_NR_recvfrom: | |
| 2763 | + ret = do_socketcallwrapper(SOCKOP_recvfrom, arg1, arg2, arg3, arg4, arg5, arg6); | |
| 2764 | + break; | |
| 2765 | +#endif | |
| 2766 | +#ifdef TARGET_NR_recvmsg | |
| 2767 | + case TARGET_NR_recvmsg: | |
| 2768 | + ret = do_sendrecvmsg(arg1, arg2, arg3, 0); | |
| 2769 | + break; | |
| 2770 | +#endif | |
| 2771 | +#ifdef TARGET_NR_send | |
| 2772 | + case TARGET_NR_send: | |
| 2773 | + ret = do_socketcallwrapper(SOCKOP_send, arg1, arg2, arg3, arg4, arg5, arg6); | |
| 2774 | + break; | |
| 2775 | +#endif | |
| 2776 | +#ifdef TARGET_NR_sendmsg | |
| 2777 | + case TARGET_NR_sendmsg: | |
| 2778 | + ret = do_sendrecvmsg(arg1, arg2, arg3, 1); | |
| 2779 | + break; | |
| 2780 | +#endif | |
| 2781 | +#ifdef TARGET_NR_sendto | |
| 2782 | + case TARGET_NR_sendto: | |
| 2783 | + ret = do_socketcallwrapper(SOCKOP_sendto, arg1, arg2, arg3, arg4, arg5, arg6); | |
| 2784 | + break; | |
| 2785 | +#endif | |
| 2786 | +#ifdef TARGET_NR_shutdown | |
| 2787 | + case TARGET_NR_shutdown: | |
| 2788 | + ret = do_socketcallwrapper(SOCKOP_shutdown, arg1, arg2, arg3, arg4, arg5, arg6); | |
| 2789 | + break; | |
| 2790 | +#endif | |
| 2791 | +#ifdef TARGET_NR_socket | |
| 2792 | + case TARGET_NR_socket: | |
| 2793 | + ret = do_socket(arg1, arg2, arg3); | |
| 2794 | + break; | |
| 2795 | +#endif | |
| 2796 | +#ifdef TARGET_NR_socketpair | |
| 2797 | + case TARGET_NR_socketpair: | |
| 2798 | + ret = do_socketcallwrapper(SOCKOP_socketpair, arg1, arg2, arg3, arg4, arg5, arg6); | |
| 2799 | + break; | |
| 2800 | +#endif | |
| 2801 | +#ifdef TARGET_NR_setsockopt | |
| 2802 | + case TARGET_NR_setsockopt: | |
| 2803 | + ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5); | |
| 2804 | + break; | |
| 2805 | +#endif | |
| 2806 | + | |
| 2619 | 2807 | case TARGET_NR_syslog: |
| 2620 | 2808 | goto unimplemented; |
| 2621 | 2809 | case TARGET_NR_setitimer: | ... | ... |
linux-user/syscall_defs.h