early-access version 3953
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
#include "core/hle/service/apm/apm_controller.h"
|
||||
#include "core/hle/service/apm/apm_interface.h"
|
||||
#include "core/hle/service/bcat/backend/backend.h"
|
||||
#include "core/hle/service/caps/caps_su.h"
|
||||
#include "core/hle/service/caps/caps_types.h"
|
||||
#include "core/hle/service/filesystem/filesystem.h"
|
||||
#include "core/hle/service/ipc_helpers.h"
|
||||
@@ -702,9 +703,17 @@ void ISelfController::SetAlbumImageTakenNotificationEnabled(HLERequestContext& c
|
||||
void ISelfController::SaveCurrentScreenshot(HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
const auto album_report_option = rp.PopEnum<Capture::AlbumReportOption>();
|
||||
const auto report_option = rp.PopEnum<Capture::AlbumReportOption>();
|
||||
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called. album_report_option={}", album_report_option);
|
||||
LOG_INFO(Service_AM, "called, report_option={}", report_option);
|
||||
|
||||
const auto screenshot_service =
|
||||
system.ServiceManager().GetService<Service::Capture::IScreenShotApplicationService>(
|
||||
"caps:su");
|
||||
|
||||
if (screenshot_service) {
|
||||
screenshot_service->CaptureAndSaveScreenshot(report_option);
|
||||
}
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
@@ -796,7 +805,9 @@ ILockAccessor::ILockAccessor(Core::System& system_)
|
||||
lock_event = service_context.CreateEvent("ILockAccessor::LockEvent");
|
||||
}
|
||||
|
||||
ILockAccessor::~ILockAccessor() = default;
|
||||
ILockAccessor::~ILockAccessor() {
|
||||
service_context.CloseEvent(lock_event);
|
||||
};
|
||||
|
||||
void ILockAccessor::TryLock(HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
@@ -909,7 +920,9 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_,
|
||||
msg_queue->PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground);
|
||||
}
|
||||
|
||||
ICommonStateGetter::~ICommonStateGetter() = default;
|
||||
ICommonStateGetter::~ICommonStateGetter() {
|
||||
service_context.CloseEvent(sleep_lock_event);
|
||||
};
|
||||
|
||||
void ICommonStateGetter::GetBootMode(HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
|
@@ -25,7 +25,9 @@ Cabinet::Cabinet(Core::System& system_, LibraryAppletMode applet_mode_,
|
||||
service_context.CreateEvent("CabinetApplet:AvailabilityChangeEvent");
|
||||
}
|
||||
|
||||
Cabinet::~Cabinet() = default;
|
||||
Cabinet::~Cabinet() {
|
||||
service_context.CloseEvent(availability_change_event);
|
||||
};
|
||||
|
||||
void Cabinet::Initialize() {
|
||||
Applet::Initialize();
|
||||
|
@@ -228,12 +228,14 @@ Result AlbumManager::LoadAlbumScreenShotThumbnail(
|
||||
|
||||
Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry,
|
||||
const ScreenShotAttribute& attribute,
|
||||
std::span<const u8> image_data, u64 aruid) {
|
||||
return SaveScreenShot(out_entry, attribute, {}, image_data, aruid);
|
||||
AlbumReportOption report_option, std::span<const u8> image_data,
|
||||
u64 aruid) {
|
||||
return SaveScreenShot(out_entry, attribute, report_option, {}, image_data, aruid);
|
||||
}
|
||||
|
||||
Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry,
|
||||
const ScreenShotAttribute& attribute,
|
||||
AlbumReportOption report_option,
|
||||
const ApplicationData& app_data, std::span<const u8> image_data,
|
||||
u64 aruid) {
|
||||
const u64 title_id = system.GetApplicationProcessProgramID();
|
||||
@@ -407,10 +409,14 @@ Result AlbumManager::LoadImage(std::span<u8> out_image, const std::filesystem::p
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
static void PNGToMemory(void* context, void* png, int len) {
|
||||
void AlbumManager::FlipVerticallyOnWrite(bool flip) {
|
||||
stbi_flip_vertically_on_write(flip);
|
||||
}
|
||||
|
||||
static void PNGToMemory(void* context, void* data, int len) {
|
||||
std::vector<u8>* png_image = static_cast<std::vector<u8>*>(context);
|
||||
png_image->reserve(len);
|
||||
std::memcpy(png_image->data(), png, len);
|
||||
unsigned char* png = static_cast<unsigned char*>(data);
|
||||
png_image->insert(png_image->end(), png, png + len);
|
||||
}
|
||||
|
||||
Result AlbumManager::SaveImage(ApplicationAlbumEntry& out_entry, std::span<const u8> image,
|
||||
|
@@ -59,14 +59,17 @@ public:
|
||||
const ScreenShotDecodeOption& decoder_options) const;
|
||||
|
||||
Result SaveScreenShot(ApplicationAlbumEntry& out_entry, const ScreenShotAttribute& attribute,
|
||||
std::span<const u8> image_data, u64 aruid);
|
||||
Result SaveScreenShot(ApplicationAlbumEntry& out_entry, const ScreenShotAttribute& attribute,
|
||||
const ApplicationData& app_data, std::span<const u8> image_data,
|
||||
AlbumReportOption report_option, std::span<const u8> image_data,
|
||||
u64 aruid);
|
||||
Result SaveScreenShot(ApplicationAlbumEntry& out_entry, const ScreenShotAttribute& attribute,
|
||||
AlbumReportOption report_option, const ApplicationData& app_data,
|
||||
std::span<const u8> image_data, u64 aruid);
|
||||
Result SaveEditedScreenShot(ApplicationAlbumEntry& out_entry,
|
||||
const ScreenShotAttribute& attribute, const AlbumFileId& file_id,
|
||||
std::span<const u8> image_data);
|
||||
|
||||
void FlipVerticallyOnWrite(bool flip);
|
||||
|
||||
private:
|
||||
static constexpr std::size_t NandAlbumFileLimit = 1000;
|
||||
static constexpr std::size_t SdAlbumFileLimit = 10000;
|
||||
|
@@ -34,7 +34,7 @@ void IScreenShotService::SaveScreenShotEx0(HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
struct Parameters {
|
||||
ScreenShotAttribute attribute{};
|
||||
u32 report_option{};
|
||||
AlbumReportOption report_option{};
|
||||
INSERT_PADDING_BYTES(0x4);
|
||||
u64 applet_resource_user_id{};
|
||||
};
|
||||
@@ -49,13 +49,16 @@ void IScreenShotService::SaveScreenShotEx0(HLERequestContext& ctx) {
|
||||
parameters.applet_resource_user_id);
|
||||
|
||||
ApplicationAlbumEntry entry{};
|
||||
const auto result = manager->SaveScreenShot(entry, parameters.attribute, image_data_buffer,
|
||||
parameters.applet_resource_user_id);
|
||||
manager->FlipVerticallyOnWrite(false);
|
||||
const auto result =
|
||||
manager->SaveScreenShot(entry, parameters.attribute, parameters.report_option,
|
||||
image_data_buffer, parameters.applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 10};
|
||||
rb.Push(result);
|
||||
rb.PushRaw(entry);
|
||||
}
|
||||
|
||||
void IScreenShotService::SaveEditedScreenShotEx1(HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
struct Parameters {
|
||||
@@ -83,6 +86,7 @@ void IScreenShotService::SaveEditedScreenShotEx1(HLERequestContext& ctx) {
|
||||
image_data_buffer.size(), thumbnail_image_data_buffer.size());
|
||||
|
||||
ApplicationAlbumEntry entry{};
|
||||
manager->FlipVerticallyOnWrite(false);
|
||||
const auto result = manager->SaveEditedScreenShot(entry, parameters.attribute,
|
||||
parameters.file_id, image_data_buffer);
|
||||
|
||||
|
@@ -2,10 +2,12 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/service/caps/caps_manager.h"
|
||||
#include "core/hle/service/caps/caps_su.h"
|
||||
#include "core/hle/service/caps/caps_types.h"
|
||||
#include "core/hle/service/ipc_helpers.h"
|
||||
#include "video_core/renderer_base.h"
|
||||
|
||||
namespace Service::Capture {
|
||||
|
||||
@@ -58,8 +60,10 @@ void IScreenShotApplicationService::SaveScreenShotEx0(HLERequestContext& ctx) {
|
||||
parameters.applet_resource_user_id);
|
||||
|
||||
ApplicationAlbumEntry entry{};
|
||||
const auto result = manager->SaveScreenShot(entry, parameters.attribute, image_data_buffer,
|
||||
parameters.applet_resource_user_id);
|
||||
manager->FlipVerticallyOnWrite(false);
|
||||
const auto result =
|
||||
manager->SaveScreenShot(entry, parameters.attribute, parameters.report_option,
|
||||
image_data_buffer, parameters.applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 10};
|
||||
rb.Push(result);
|
||||
@@ -88,13 +92,43 @@ void IScreenShotApplicationService::SaveScreenShotEx1(HLERequestContext& ctx) {
|
||||
ApplicationAlbumEntry entry{};
|
||||
ApplicationData app_data{};
|
||||
std::memcpy(&app_data, app_data_buffer.data(), sizeof(ApplicationData));
|
||||
manager->FlipVerticallyOnWrite(false);
|
||||
const auto result =
|
||||
manager->SaveScreenShot(entry, parameters.attribute, app_data, image_data_buffer,
|
||||
parameters.applet_resource_user_id);
|
||||
manager->SaveScreenShot(entry, parameters.attribute, parameters.report_option, app_data,
|
||||
image_data_buffer, parameters.applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 10};
|
||||
rb.Push(result);
|
||||
rb.PushRaw(entry);
|
||||
}
|
||||
|
||||
void IScreenShotApplicationService::CaptureAndSaveScreenshot(AlbumReportOption report_option) {
|
||||
auto& renderer = system.Renderer();
|
||||
Layout::FramebufferLayout layout =
|
||||
Layout::DefaultFrameLayout(screenshot_width, screenshot_height);
|
||||
|
||||
const Capture::ScreenShotAttribute attribute{
|
||||
.unknown_0{},
|
||||
.orientation = Capture::AlbumImageOrientation::None,
|
||||
.unknown_1{},
|
||||
.unknown_2{},
|
||||
};
|
||||
|
||||
renderer.RequestScreenshot(
|
||||
image_data.data(),
|
||||
[attribute, report_option, this](bool invert_y) {
|
||||
// Convert from BGRA to RGBA
|
||||
for (std::size_t i = 0; i < image_data.size(); i += bytes_per_pixel) {
|
||||
const u8 temp = image_data[i];
|
||||
image_data[i] = image_data[i + 2];
|
||||
image_data[i + 2] = temp;
|
||||
}
|
||||
|
||||
Capture::ApplicationAlbumEntry entry{};
|
||||
manager->FlipVerticallyOnWrite(invert_y);
|
||||
manager->SaveScreenShot(entry, attribute, report_option, image_data, {});
|
||||
},
|
||||
layout);
|
||||
}
|
||||
|
||||
} // namespace Service::Capture
|
||||
|
@@ -10,6 +10,7 @@ class System;
|
||||
}
|
||||
|
||||
namespace Service::Capture {
|
||||
enum class AlbumReportOption : s32;
|
||||
class AlbumManager;
|
||||
|
||||
class IScreenShotApplicationService final : public ServiceFramework<IScreenShotApplicationService> {
|
||||
@@ -18,11 +19,19 @@ public:
|
||||
std::shared_ptr<AlbumManager> album_manager);
|
||||
~IScreenShotApplicationService() override;
|
||||
|
||||
void CaptureAndSaveScreenshot(AlbumReportOption report_option);
|
||||
|
||||
private:
|
||||
static constexpr std::size_t screenshot_width = 1280;
|
||||
static constexpr std::size_t screenshot_height = 720;
|
||||
static constexpr std::size_t bytes_per_pixel = 4;
|
||||
|
||||
void SetShimLibraryVersion(HLERequestContext& ctx);
|
||||
void SaveScreenShotEx0(HLERequestContext& ctx);
|
||||
void SaveScreenShotEx1(HLERequestContext& ctx);
|
||||
|
||||
std::array<u8, screenshot_width * screenshot_height * bytes_per_pixel> image_data;
|
||||
|
||||
std::shared_ptr<AlbumManager> manager;
|
||||
};
|
||||
|
||||
|
@@ -19,7 +19,9 @@ Controller_Palma::Controller_Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared
|
||||
operation_complete_event = service_context.CreateEvent("hid:PalmaOperationCompleteEvent");
|
||||
}
|
||||
|
||||
Controller_Palma::~Controller_Palma() = default;
|
||||
Controller_Palma::~Controller_Palma() {
|
||||
service_context.CloseEvent(operation_complete_event);
|
||||
};
|
||||
|
||||
void Controller_Palma::OnInit() {}
|
||||
|
||||
|
@@ -2757,6 +2757,10 @@ public:
|
||||
joy_detach_event = service_context.CreateEvent("HidSys::JoyDetachEvent");
|
||||
}
|
||||
|
||||
~HidSys() {
|
||||
service_context.CloseEvent(joy_detach_event);
|
||||
};
|
||||
|
||||
private:
|
||||
void ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_HID, "called");
|
||||
|
@@ -13,7 +13,10 @@ HidbusBase::HidbusBase(Core::System& system_, KernelHelpers::ServiceContext& ser
|
||||
: system(system_), service_context(service_context_) {
|
||||
send_command_async_event = service_context.CreateEvent("hidbus:SendCommandAsyncEvent");
|
||||
}
|
||||
HidbusBase::~HidbusBase() = default;
|
||||
|
||||
HidbusBase::~HidbusBase() {
|
||||
service_context.CloseEvent(send_command_async_event);
|
||||
};
|
||||
|
||||
void HidbusBase::ActivateDevice() {
|
||||
if (is_activated) {
|
||||
|
@@ -3,6 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Service::android {
|
||||
@@ -21,5 +22,6 @@ enum class BufferTransformFlags : u32 {
|
||||
/// Rotate source image 270 degrees clockwise
|
||||
Rotate270 = 0x07,
|
||||
};
|
||||
DECLARE_ENUM_FLAG_OPERATORS(BufferTransformFlags);
|
||||
|
||||
} // namespace Service::android
|
||||
|
@@ -141,6 +141,12 @@ public:
|
||||
service_context.CreateEvent("IParentalControlService::RequestSuspensionEvent");
|
||||
}
|
||||
|
||||
~IParentalControlService() {
|
||||
service_context.CloseEvent(synchronization_event);
|
||||
service_context.CloseEvent(unlinked_event);
|
||||
service_context.CloseEvent(request_suspension_event);
|
||||
};
|
||||
|
||||
private:
|
||||
bool CheckFreeCommunicationPermissionImpl() const {
|
||||
if (states.temporary_unlocked) {
|
||||
|
@@ -39,6 +39,18 @@ bool IsConnectionBased(Type type) {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T GetValue(std::span<const u8> buffer) {
|
||||
T t{};
|
||||
std::memcpy(&t, buffer.data(), std::min(sizeof(T), buffer.size()));
|
||||
return t;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void PutValue(std::span<u8> buffer, const T& t) {
|
||||
std::memcpy(buffer.data(), &t, std::min(sizeof(T), buffer.size()));
|
||||
}
|
||||
|
||||
} // Anonymous namespace
|
||||
|
||||
void BSD::PollWork::Execute(BSD* bsd) {
|
||||
@@ -316,22 +328,12 @@ void BSD::SetSockOpt(HLERequestContext& ctx) {
|
||||
const s32 fd = rp.Pop<s32>();
|
||||
const u32 level = rp.Pop<u32>();
|
||||
const OptName optname = static_cast<OptName>(rp.Pop<u32>());
|
||||
|
||||
const auto buffer = ctx.ReadBuffer();
|
||||
const u8* optval = buffer.empty() ? nullptr : buffer.data();
|
||||
size_t optlen = buffer.size();
|
||||
|
||||
std::array<u64, 2> values;
|
||||
if ((optname == OptName::SNDTIMEO || optname == OptName::RCVTIMEO) && buffer.size() == 8) {
|
||||
std::memcpy(values.data(), buffer.data(), sizeof(values));
|
||||
optlen = sizeof(values);
|
||||
optval = reinterpret_cast<const u8*>(values.data());
|
||||
}
|
||||
const auto optval = ctx.ReadBuffer();
|
||||
|
||||
LOG_DEBUG(Service, "called. fd={} level={} optname=0x{:x} optlen={}", fd, level,
|
||||
static_cast<u32>(optname), optlen);
|
||||
static_cast<u32>(optname), optval.size());
|
||||
|
||||
BuildErrnoResponse(ctx, SetSockOptImpl(fd, level, optname, optlen, optval));
|
||||
BuildErrnoResponse(ctx, SetSockOptImpl(fd, level, optname, optval));
|
||||
}
|
||||
|
||||
void BSD::Shutdown(HLERequestContext& ctx) {
|
||||
@@ -521,18 +523,19 @@ std::pair<s32, Errno> BSD::SocketImpl(Domain domain, Type type, Protocol protoco
|
||||
|
||||
std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer,
|
||||
s32 nfds, s32 timeout) {
|
||||
if (nfds <= 0) {
|
||||
// When no entries are provided, -1 is returned with errno zero
|
||||
return {-1, Errno::SUCCESS};
|
||||
}
|
||||
if (read_buffer.size() < nfds * sizeof(PollFD)) {
|
||||
return {-1, Errno::INVAL};
|
||||
}
|
||||
if (write_buffer.size() < nfds * sizeof(PollFD)) {
|
||||
return {-1, Errno::INVAL};
|
||||
}
|
||||
|
||||
if (nfds == 0) {
|
||||
// When no entries are provided, -1 is returned with errno zero
|
||||
return {-1, Errno::SUCCESS};
|
||||
}
|
||||
|
||||
const size_t length = std::min(read_buffer.size(), write_buffer.size());
|
||||
std::vector<PollFD> fds(nfds);
|
||||
std::memcpy(fds.data(), read_buffer.data(), length);
|
||||
std::memcpy(fds.data(), read_buffer.data(), nfds * sizeof(PollFD));
|
||||
|
||||
if (timeout >= 0) {
|
||||
const s64 seconds = timeout / 1000;
|
||||
@@ -580,7 +583,7 @@ std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<con
|
||||
for (size_t i = 0; i < num; ++i) {
|
||||
fds[i].revents = Translate(host_pollfds[i].revents);
|
||||
}
|
||||
std::memcpy(write_buffer.data(), fds.data(), length);
|
||||
std::memcpy(write_buffer.data(), fds.data(), nfds * sizeof(PollFD));
|
||||
|
||||
return Translate(result);
|
||||
}
|
||||
@@ -608,8 +611,7 @@ std::pair<s32, Errno> BSD::AcceptImpl(s32 fd, std::vector<u8>& write_buffer) {
|
||||
new_descriptor.is_connection_based = descriptor.is_connection_based;
|
||||
|
||||
const SockAddrIn guest_addr_in = Translate(result.sockaddr_in);
|
||||
const size_t length = std::min(sizeof(guest_addr_in), write_buffer.size());
|
||||
std::memcpy(write_buffer.data(), &guest_addr_in, length);
|
||||
PutValue(write_buffer, guest_addr_in);
|
||||
|
||||
return {new_fd, Errno::SUCCESS};
|
||||
}
|
||||
@@ -619,8 +621,7 @@ Errno BSD::BindImpl(s32 fd, std::span<const u8> addr) {
|
||||
return Errno::BADF;
|
||||
}
|
||||
ASSERT(addr.size() == sizeof(SockAddrIn));
|
||||
SockAddrIn addr_in;
|
||||
std::memcpy(&addr_in, addr.data(), sizeof(addr_in));
|
||||
auto addr_in = GetValue<SockAddrIn>(addr);
|
||||
|
||||
return Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in)));
|
||||
}
|
||||
@@ -631,8 +632,7 @@ Errno BSD::ConnectImpl(s32 fd, std::span<const u8> addr) {
|
||||
}
|
||||
|
||||
UNIMPLEMENTED_IF(addr.size() != sizeof(SockAddrIn));
|
||||
SockAddrIn addr_in;
|
||||
std::memcpy(&addr_in, addr.data(), sizeof(addr_in));
|
||||
auto addr_in = GetValue<SockAddrIn>(addr);
|
||||
|
||||
return Translate(file_descriptors[fd]->socket->Connect(Translate(addr_in)));
|
||||
}
|
||||
@@ -650,7 +650,7 @@ Errno BSD::GetPeerNameImpl(s32 fd, std::vector<u8>& write_buffer) {
|
||||
|
||||
ASSERT(write_buffer.size() >= sizeof(guest_addrin));
|
||||
write_buffer.resize(sizeof(guest_addrin));
|
||||
std::memcpy(write_buffer.data(), &guest_addrin, sizeof(guest_addrin));
|
||||
PutValue(write_buffer, guest_addrin);
|
||||
return Translate(bsd_errno);
|
||||
}
|
||||
|
||||
@@ -667,7 +667,7 @@ Errno BSD::GetSockNameImpl(s32 fd, std::vector<u8>& write_buffer) {
|
||||
|
||||
ASSERT(write_buffer.size() >= sizeof(guest_addrin));
|
||||
write_buffer.resize(sizeof(guest_addrin));
|
||||
std::memcpy(write_buffer.data(), &guest_addrin, sizeof(guest_addrin));
|
||||
PutValue(write_buffer, guest_addrin);
|
||||
return Translate(bsd_errno);
|
||||
}
|
||||
|
||||
@@ -725,7 +725,7 @@ Errno BSD::GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& o
|
||||
optval.size() == sizeof(Errno), { return Errno::INVAL; },
|
||||
"Incorrect getsockopt option size");
|
||||
optval.resize(sizeof(Errno));
|
||||
memcpy(optval.data(), &translated_pending_err, sizeof(Errno));
|
||||
PutValue(optval, translated_pending_err);
|
||||
}
|
||||
return Translate(getsockopt_err);
|
||||
}
|
||||
@@ -735,7 +735,7 @@ Errno BSD::GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& o
|
||||
}
|
||||
}
|
||||
|
||||
Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, size_t optlen, const void* optval) {
|
||||
Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span<const u8> optval) {
|
||||
if (!IsFileDescriptorValid(fd)) {
|
||||
return Errno::BADF;
|
||||
}
|
||||
@@ -748,17 +748,15 @@ Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, size_t optlen, con
|
||||
Network::SocketBase* const socket = file_descriptors[fd]->socket.get();
|
||||
|
||||
if (optname == OptName::LINGER) {
|
||||
ASSERT(optlen == sizeof(Linger));
|
||||
Linger linger;
|
||||
std::memcpy(&linger, optval, sizeof(linger));
|
||||
ASSERT(optval.size() == sizeof(Linger));
|
||||
auto linger = GetValue<Linger>(optval);
|
||||
ASSERT(linger.onoff == 0 || linger.onoff == 1);
|
||||
|
||||
return Translate(socket->SetLinger(linger.onoff != 0, linger.linger));
|
||||
}
|
||||
|
||||
ASSERT(optlen == sizeof(u32));
|
||||
u32 value;
|
||||
std::memcpy(&value, optval, sizeof(value));
|
||||
ASSERT(optval.size() == sizeof(u32));
|
||||
auto value = GetValue<u32>(optval);
|
||||
|
||||
switch (optname) {
|
||||
case OptName::REUSEADDR:
|
||||
@@ -862,7 +860,7 @@ std::pair<s32, Errno> BSD::RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& mess
|
||||
} else {
|
||||
ASSERT(addr.size() == sizeof(SockAddrIn));
|
||||
const SockAddrIn result = Translate(addr_in);
|
||||
std::memcpy(addr.data(), &result, sizeof(result));
|
||||
PutValue(addr, result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -886,8 +884,7 @@ std::pair<s32, Errno> BSD::SendToImpl(s32 fd, u32 flags, std::span<const u8> mes
|
||||
Network::SockAddrIn* p_addr_in = nullptr;
|
||||
if (!addr.empty()) {
|
||||
ASSERT(addr.size() == sizeof(SockAddrIn));
|
||||
SockAddrIn guest_addr_in;
|
||||
std::memcpy(&guest_addr_in, addr.data(), sizeof(guest_addr_in));
|
||||
auto guest_addr_in = GetValue<SockAddrIn>(addr);
|
||||
addr_in = Translate(guest_addr_in);
|
||||
p_addr_in = &addr_in;
|
||||
}
|
||||
|
@@ -163,7 +163,7 @@ private:
|
||||
Errno ListenImpl(s32 fd, s32 backlog);
|
||||
std::pair<s32, Errno> FcntlImpl(s32 fd, FcntlCmd cmd, s32 arg);
|
||||
Errno GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& optval);
|
||||
Errno SetSockOptImpl(s32 fd, u32 level, OptName optname, size_t optlen, const void* optval);
|
||||
Errno SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span<const u8> optval);
|
||||
Errno ShutdownImpl(s32 fd, s32 how);
|
||||
std::pair<s32, Errno> RecvImpl(s32 fd, u32 flags, std::vector<u8>& message);
|
||||
std::pair<s32, Errno> RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& message,
|
||||
|
Reference in New Issue
Block a user