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