diff options
| author | 2016-03-28 23:34:34 -0700 | |
|---|---|---|
| committer | 2016-03-28 23:34:34 -0700 | |
| commit | 91dbebbcc5007c3286f0f9948c2225ff5b5c8260 (patch) | |
| tree | e20ace4ec6344d7ae899e150d8504f2035b60e04 /src | |
| parent | Merge pull request #1589 from LittleWhite-tb/compil-fix (diff) | |
| download | yuzu-91dbebbcc5007c3286f0f9948c2225ff5b5c8260.tar.gz yuzu-91dbebbcc5007c3286f0f9948c2225ff5b5c8260.tar.xz yuzu-91dbebbcc5007c3286f0f9948c2225ff5b5c8260.zip | |
SOC Updates
-Implement GetSockOpt / SetSockOpt
-Fix bug in RecvFrom where sending from localhost
does not fill in src_addr/src_addr_len on Linux
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/soc_u.cpp | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp index ff0af8f12..efda8bd4f 100644 --- a/src/core/hle/service/soc_u.cpp +++ b/src/core/hle/service/soc_u.cpp | |||
| @@ -568,7 +568,7 @@ static void RecvFrom(Service::Interface* self) { | |||
| 568 | socklen_t src_addr_len = sizeof(src_addr); | 568 | socklen_t src_addr_len = sizeof(src_addr); |
| 569 | int ret = ::recvfrom(socket_handle, (char*)output_buff, len, flags, &src_addr, &src_addr_len); | 569 | int ret = ::recvfrom(socket_handle, (char*)output_buff, len, flags, &src_addr, &src_addr_len); |
| 570 | 570 | ||
| 571 | if (buffer_parameters.output_src_address_buffer != 0) { | 571 | if (buffer_parameters.output_src_address_buffer != 0 && src_addr_len > 0) { |
| 572 | CTRSockAddr* ctr_src_addr = reinterpret_cast<CTRSockAddr*>(Memory::GetPointer(buffer_parameters.output_src_address_buffer)); | 572 | CTRSockAddr* ctr_src_addr = reinterpret_cast<CTRSockAddr*>(Memory::GetPointer(buffer_parameters.output_src_address_buffer)); |
| 573 | *ctr_src_addr = CTRSockAddr::FromPlatform(src_addr); | 573 | *ctr_src_addr = CTRSockAddr::FromPlatform(src_addr); |
| 574 | } | 574 | } |
| @@ -724,6 +724,49 @@ static void ShutdownSockets(Service::Interface* self) { | |||
| 724 | cmd_buffer[1] = 0; | 724 | cmd_buffer[1] = 0; |
| 725 | } | 725 | } |
| 726 | 726 | ||
| 727 | static void GetSockOpt(Service::Interface* self) { | ||
| 728 | u32* cmd_buffer = Kernel::GetCommandBuffer(); | ||
| 729 | u32 socket_handle = cmd_buffer[1]; | ||
| 730 | u32 level = cmd_buffer[2]; | ||
| 731 | u32 optname = cmd_buffer[3]; | ||
| 732 | u32 optlen = cmd_buffer[4]; | ||
| 733 | |||
| 734 | // 0x100 = static buffer offset (bytes) | ||
| 735 | // + 0x4 = 2nd pointer (u32) position | ||
| 736 | // >> 2 = convert to u32 offset instead of byte offset (cmd_buffer = u32*) | ||
| 737 | u8* optval = Memory::GetPointer(cmd_buffer[0x104 >> 2]); | ||
| 738 | |||
| 739 | int ret = ::getsockopt(socket_handle, level, optname, &optval, &optlen); | ||
| 740 | int err = 0; | ||
| 741 | if(ret == SOCKET_ERROR_VALUE) { | ||
| 742 | err = TranslateError(GET_ERRNO); | ||
| 743 | } | ||
| 744 | |||
| 745 | cmd_buffer[0] = IPC::MakeHeader(0x11, 4, 2); | ||
| 746 | cmd_buffer[1] = ret; | ||
| 747 | cmd_buffer[2] = err; | ||
| 748 | cmd_buffer[3] = optlen; | ||
| 749 | } | ||
| 750 | |||
| 751 | static void SetSockOpt(Service::Interface* self) { | ||
| 752 | u32* cmd_buffer = Kernel::GetCommandBuffer(); | ||
| 753 | u32 socket_handle = cmd_buffer[1]; | ||
| 754 | u32 level = cmd_buffer[2]; | ||
| 755 | u32 optname = cmd_buffer[3]; | ||
| 756 | socklen_t optlen = static_cast<socklen_t>(cmd_buffer[4]); | ||
| 757 | void *optval = Memory::GetPointer(cmd_buffer[8]); | ||
| 758 | |||
| 759 | int ret = static_cast<u32>(::setsockopt(socket_handle, level, optname, optval, optlen)); | ||
| 760 | int err = 0; | ||
| 761 | if(ret == SOCKET_ERROR_VALUE) { | ||
| 762 | err = TranslateError(GET_ERRNO); | ||
| 763 | } | ||
| 764 | |||
| 765 | cmd_buffer[0] = IPC::MakeHeader(0x12, 4, 4); | ||
| 766 | cmd_buffer[1] = ret; | ||
| 767 | cmd_buffer[2] = err; | ||
| 768 | } | ||
| 769 | |||
| 727 | const Interface::FunctionInfo FunctionTable[] = { | 770 | const Interface::FunctionInfo FunctionTable[] = { |
| 728 | {0x00010044, InitializeSockets, "InitializeSockets"}, | 771 | {0x00010044, InitializeSockets, "InitializeSockets"}, |
| 729 | {0x000200C2, Socket, "Socket"}, | 772 | {0x000200C2, Socket, "Socket"}, |
| @@ -741,8 +784,8 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 741 | {0x000E00C2, nullptr, "GetHostByAddr"}, | 784 | {0x000E00C2, nullptr, "GetHostByAddr"}, |
| 742 | {0x000F0106, nullptr, "GetAddrInfo"}, | 785 | {0x000F0106, nullptr, "GetAddrInfo"}, |
| 743 | {0x00100102, nullptr, "GetNameInfo"}, | 786 | {0x00100102, nullptr, "GetNameInfo"}, |
| 744 | {0x00110102, nullptr, "GetSockOpt"}, | 787 | {0x00110102, GetSockOpt, "GetSockOpt"}, |
| 745 | {0x00120104, nullptr, "SetSockOpt"}, | 788 | {0x00120104, SetSockOpt, "SetSockOpt"}, |
| 746 | {0x001300C2, Fcntl, "Fcntl"}, | 789 | {0x001300C2, Fcntl, "Fcntl"}, |
| 747 | {0x00140084, Poll, "Poll"}, | 790 | {0x00140084, Poll, "Poll"}, |
| 748 | {0x00150042, nullptr, "SockAtMark"}, | 791 | {0x00150042, nullptr, "SockAtMark"}, |