summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Ryan Loebs2016-03-28 23:34:34 -0700
committerGravatar Ryan Loebs2016-03-28 23:34:34 -0700
commit91dbebbcc5007c3286f0f9948c2225ff5b5c8260 (patch)
treee20ace4ec6344d7ae899e150d8504f2035b60e04 /src
parentMerge pull request #1589 from LittleWhite-tb/compil-fix (diff)
downloadyuzu-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.cpp49
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
727static 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
751static 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
727const Interface::FunctionInfo FunctionTable[] = { 770const 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"},