summaryrefslogtreecommitdiffstats
path: root/src/osd/modules/file/winsocket.cpp
diff options
context:
space:
mode:
author Vas Crabb <cuavas@users.noreply.github.com>2021-08-22 09:06:15 +1000
committer GitHub <noreply@github.com>2021-08-22 09:06:15 +1000
commite8bbea1fc6e94e14768509d322f6c624403ffb36 (patch)
tree74dd1606a900d83de8aecff17a6737af4113308d /src/osd/modules/file/winsocket.cpp
parente319bde5fc3696d7f48f62b15b6366c4377fe5d1 (diff)
formats, osd, util: Started refactoring file I/O stuff. (#8456)
Added more modern generic I/O interfaces with implementation backed by stdio, osd_file and core_file, replacing io_generic. Also replaced core_file's build-in zlib compression with a filter. unzip.cpp, un7z.cpp: Added option to supply abstract I/O interface rather than filename. Converted osd_file, core_file, archive_file, chd_file and device_image_interface to use std::error_condition rather than their own error enums. Allow mounting TI-99 RPK from inside archives.
Diffstat (limited to 'src/osd/modules/file/winsocket.cpp')
-rw-r--r--src/osd/modules/file/winsocket.cpp130
1 files changed, 75 insertions, 55 deletions
diff --git a/src/osd/modules/file/winsocket.cpp b/src/osd/modules/file/winsocket.cpp
index 948e57db822..f818f3b1991 100644
--- a/src/osd/modules/file/winsocket.cpp
+++ b/src/osd/modules/file/winsocket.cpp
@@ -6,7 +6,6 @@
//
//============================================================
-
#include "winfile.h"
// MAMEOS headers
@@ -28,6 +27,7 @@
namespace {
+
char const *const winfile_socket_identifier = "socket.";
@@ -39,7 +39,7 @@ public:
win_osd_socket& operator=(win_osd_socket const &) = delete;
win_osd_socket& operator=(win_osd_socket &&) = delete;
- win_osd_socket(SOCKET s, bool l)
+ win_osd_socket(SOCKET s, bool l) noexcept
: m_socket(s)
, m_listening(l)
{
@@ -51,7 +51,7 @@ public:
closesocket(m_socket);
}
- virtual error read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override
+ virtual std::error_condition read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) noexcept override
{
fd_set readfds;
FD_ZERO(&readfds);
@@ -62,10 +62,7 @@ public:
if (select(m_socket + 1, &readfds, nullptr, nullptr, &timeout) < 0)
{
- char line[80];
- std::sprintf(line, "win_read_socket : %s : %d ", __FILE__, __LINE__);
- std::perror(line);
- return error::FAILURE;
+ return wsa_error_to_file_error(WSAGetLastError());
}
else if (FD_ISSET(m_socket, &readfds))
{
@@ -80,7 +77,7 @@ public:
else
{
actual = result;
- return error::NONE;
+ return std::error_condition();
}
}
else
@@ -98,50 +95,82 @@ public:
m_listening = false;
actual = 0;
- return error::NONE;
+ return std::error_condition();
}
}
}
else
{
- return error::FAILURE;
+ // no data available
+ actual = 0;
+ return std::error_condition();
}
}
- virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override
+ virtual std::error_condition write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) noexcept override
{
auto const result = send(m_socket, reinterpret_cast<const char *>(buffer), length, 0);
if (result < 0)
return wsa_error_to_file_error(WSAGetLastError());
actual = result;
- return error::NONE;
+ return std::error_condition();
}
- virtual error truncate(std::uint64_t offset) override
+ virtual std::error_condition truncate(std::uint64_t offset) noexcept override
{
// doesn't make sense for a socket
- return error::INVALID_ACCESS;
+ return std::errc::bad_file_descriptor;
}
- virtual error flush() override
+ virtual std::error_condition flush() noexcept override
{
// no buffers to flush
- return error::NONE;
+ return std::error_condition();
}
- static error wsa_error_to_file_error(int err)
+ static std::error_condition wsa_error_to_file_error(int err)
{
+ // TODO: determine if there's a better way to do this
switch (err)
{
- case 0: return error::NONE;
- case WSAEACCES: return error::ACCESS_DENIED;
- case WSAEADDRINUSE: return error::ALREADY_OPEN;
- case WSAEADDRNOTAVAIL: return error::NOT_FOUND;
- case WSAECONNREFUSED: return error::NOT_FOUND;
- case WSAEHOSTUNREACH: return error::NOT_FOUND;
- case WSAENETUNREACH: return error::NOT_FOUND;
- default: return error::FAILURE;
+ case 0: return std::error_condition();
+ case WSA_NOT_ENOUGH_MEMORY: return std::errc::not_enough_memory;
+ case WSA_INVALID_PARAMETER: return std::errc::invalid_argument;
+ case WSAEINTR: return std::errc::interrupted;
+ case WSAEBADF: return std::errc::bad_file_descriptor;
+ case WSAEACCES: return std::errc::permission_denied;
+ case WSAEFAULT: return std::errc::bad_address;
+ case WSAEINVAL: return std::errc::invalid_argument;
+ case WSAEMFILE: return std::errc::too_many_files_open;
+ case WSAENETRESET: return std::errc::network_reset;
+ case WSAECONNABORTED: return std::errc::connection_aborted;
+ case WSAEWOULDBLOCK: return std::errc::operation_would_block;
+ case WSAEINPROGRESS: return std::errc::operation_in_progress;
+ case WSAEALREADY: return std::errc::connection_already_in_progress;
+ case WSAENOTSOCK: return std::errc::not_a_socket;
+ case WSAEDESTADDRREQ: return std::errc::destination_address_required;
+ case WSAEMSGSIZE: return std::errc::message_size;
+ case WSAEPROTOTYPE: return std::errc::wrong_protocol_type;
+ case WSAENOPROTOOPT: return std::errc::no_protocol_option;
+ case WSAEPROTONOSUPPORT: return std::errc::protocol_not_supported;
+ case WSAEOPNOTSUPP: return std::errc::operation_not_supported;
+ case WSAEAFNOSUPPORT: return std::errc::address_family_not_supported;
+ case WSAEADDRINUSE: return std::errc::address_in_use;
+ case WSAEADDRNOTAVAIL: return std::errc::address_not_available;
+ case WSAENETDOWN: return std::errc::network_down;
+ case WSAENETUNREACH: return std::errc::network_unreachable;
+ case WSAECONNRESET: return std::errc::connection_reset;
+ case WSAENOBUFS: return std::errc::no_buffer_space;
+ case WSAEISCONN: return std::errc::already_connected;
+ case WSAENOTCONN: return std::errc::not_connected;
+ case WSAETIMEDOUT: return std::errc::timed_out;
+ case WSAECONNREFUSED: return std::errc::connection_refused;
+ case WSAEHOSTUNREACH: return std::errc::host_unreachable;
+ case WSAECANCELLED: return std::errc::operation_canceled;
+
+ // TODO: better default error code?
+ default: return std::errc::io_error;
}
}
@@ -153,7 +182,7 @@ private:
} // anonymous namespace
-bool win_init_sockets()
+bool win_init_sockets() noexcept
{
WSADATA wsaData;
WORD const version = MAKEWORD(2, 0);
@@ -179,13 +208,13 @@ bool win_init_sockets()
}
-void win_cleanup_sockets()
+void win_cleanup_sockets() noexcept
{
WSACleanup();
}
-bool win_check_socket_path(std::string const &path)
+bool win_check_socket_path(std::string const &path) noexcept
{
if (strncmp(path.c_str(), winfile_socket_identifier, strlen(winfile_socket_identifier)) == 0 &&
strchr(path.c_str(), ':') != nullptr) return true;
@@ -193,7 +222,7 @@ bool win_check_socket_path(std::string const &path)
}
-osd_file::error win_open_socket(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize)
+std::error_condition win_open_socket(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize) noexcept
{
char hostname[256];
int port;
@@ -201,7 +230,7 @@ osd_file::error win_open_socket(std::string const &path, std::uint32_t openflags
struct hostent const *const localhost = gethostbyname(hostname);
if (!localhost)
- return osd_file::error::NOT_FOUND;
+ return std::errc::no_such_file_or_directory;
struct sockaddr_in sai;
memset(&sai, 0, sizeof(sai));
@@ -222,11 +251,12 @@ osd_file::error win_open_socket(std::string const &path, std::uint32_t openflags
}
// listening socket support
+ osd_file::ptr result;
if (openflags & OPEN_FLAG_CREATE)
{
//printf("Listening for client at '%s' on port '%d'\n", hostname, port);
// bind socket...
- if (bind(sock, reinterpret_cast<struct sockaddr const *>(&sai), sizeof(struct sockaddr)) == SOCKET_ERROR)
+ if (bind(sock, reinterpret_cast<struct sockaddr const *>(&sai), sizeof(sai)) == SOCKET_ERROR)
{
int const err = WSAGetLastError();
closesocket(sock);
@@ -242,36 +272,26 @@ osd_file::error win_open_socket(std::string const &path, std::uint32_t openflags
}
// mark socket as "listening"
- try
- {
- file = std::make_unique<win_osd_socket>(sock, true);
- filesize = 0;
- return osd_file::error::NONE;
- }
- catch (...)
- {
- closesocket(sock);
- return osd_file::error::OUT_OF_MEMORY;
- }
+ result.reset(new (std::nothrow) win_osd_socket(sock, true));
}
else
{
//printf("Connecting to server '%s' on port '%d'\n", hostname, port);
- if (connect(sock, reinterpret_cast<struct sockaddr const *>(&sai), sizeof(struct sockaddr)) == SOCKET_ERROR)
- {
- closesocket(sock);
- return osd_file::error::ACCESS_DENIED; // have to return this value or bitb won't try to bind on connect failure
- }
- try
- {
- file = std::make_unique<win_osd_socket>(sock, false);
- filesize = 0;
- return osd_file::error::NONE;
- }
- catch (...)
+ if (connect(sock, reinterpret_cast<struct sockaddr const *>(&sai), sizeof(sai)) == SOCKET_ERROR)
{
+ int const err = WSAGetLastError();
closesocket(sock);
- return osd_file::error::OUT_OF_MEMORY;
+ return win_osd_socket::wsa_error_to_file_error(err);
}
+ result.reset(new (std::nothrow) win_osd_socket(sock, false));
+ }
+
+ if (!result)
+ {
+ closesocket(sock);
+ return std::errc::not_enough_memory;
}
+ file = std::move(result);
+ filesize = 0;
+ return std::error_condition();
}