diff options
Diffstat (limited to 'drivers/unix')
-rw-r--r-- | drivers/unix/dir_access_unix.cpp | 85 | ||||
-rw-r--r-- | drivers/unix/dir_access_unix.h | 10 | ||||
-rw-r--r-- | drivers/unix/file_access_unix.cpp | 32 | ||||
-rw-r--r-- | drivers/unix/file_access_unix.h | 12 | ||||
-rw-r--r-- | drivers/unix/ip_unix.cpp | 54 | ||||
-rw-r--r-- | drivers/unix/ip_unix.h | 8 | ||||
-rw-r--r-- | drivers/unix/net_socket_posix.cpp | 101 | ||||
-rw-r--r-- | drivers/unix/net_socket_posix.h | 27 | ||||
-rw-r--r-- | drivers/unix/os_unix.cpp | 6 | ||||
-rw-r--r-- | drivers/unix/thread_posix.cpp | 4 |
10 files changed, 228 insertions, 111 deletions
diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index eda929850c..a2c9bae852 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -102,6 +102,28 @@ bool DirAccessUnix::dir_exists(String p_dir) { return (success && S_ISDIR(flags.st_mode)); } +bool DirAccessUnix::is_readable(String p_dir) { + GLOBAL_LOCK_FUNCTION + + if (p_dir.is_rel_path()) { + p_dir = get_current_dir().plus_file(p_dir); + } + + p_dir = fix_path(p_dir); + return (access(p_dir.utf8().get_data(), R_OK) == 0); +} + +bool DirAccessUnix::is_writable(String p_dir) { + GLOBAL_LOCK_FUNCTION + + if (p_dir.is_rel_path()) { + p_dir = get_current_dir().plus_file(p_dir); + } + + p_dir = fix_path(p_dir); + return (access(p_dir.utf8().get_data(), W_OK) == 0); +} + uint64_t DirAccessUnix::get_modified_time(String p_file) { if (p_file.is_rel_path()) { p_file = current_dir.plus_file(p_file); @@ -204,8 +226,9 @@ static void _get_drives(List<String> *list) { while (getmntent_r(mtab, &mnt, strings, sizeof(strings))) { if (mnt.mnt_dir != nullptr && _filter_drive(&mnt)) { // Avoid duplicates - if (!list->find(mnt.mnt_dir)) { - list->push_back(mnt.mnt_dir); + String name = String::utf8(mnt.mnt_dir); + if (!list->find(name)) { + list->push_back(name); } } } @@ -218,8 +241,9 @@ static void _get_drives(List<String> *list) { const char *home = getenv("HOME"); if (home) { // Only add if it's not a duplicate - if (!list->find(home)) { - list->push_back(home); + String home_name = String::utf8(home); + if (!list->find(home_name)) { + list->push_back(home_name); } // Check $HOME/.config/gtk-3.0/bookmarks @@ -232,7 +256,7 @@ static void _get_drives(List<String> *list) { // Parse only file:// links if (strncmp(string, "file://", 7) == 0) { // Strip any unwanted edges on the strings and push_back if it's not a duplicate - String fpath = String(string + 7).strip_edges().split_spaces()[0].uri_decode(); + String fpath = String::utf8(string + 7).strip_edges().split_spaces()[0].uri_decode(); if (!list->find(fpath)) { list->push_back(fpath); } @@ -382,14 +406,61 @@ Error DirAccessUnix::remove(String p_path) { } } -size_t DirAccessUnix::get_space_left() { +bool DirAccessUnix::is_link(String p_file) { + if (p_file.is_rel_path()) { + p_file = get_current_dir().plus_file(p_file); + } + + p_file = fix_path(p_file); + + struct stat flags; + if ((lstat(p_file.utf8().get_data(), &flags) != 0)) { + return FAILED; + } + + return S_ISLNK(flags.st_mode); +} + +String DirAccessUnix::read_link(String p_file) { + if (p_file.is_rel_path()) { + p_file = get_current_dir().plus_file(p_file); + } + + p_file = fix_path(p_file); + + char buf[256]; + memset(buf, 0, 256); + ssize_t len = readlink(p_file.utf8().get_data(), buf, sizeof(buf)); + String link; + if (len > 0) { + link.parse_utf8(buf, len); + } + return link; +} + +Error DirAccessUnix::create_link(String p_source, String p_target) { + if (p_target.is_rel_path()) { + p_target = get_current_dir().plus_file(p_target); + } + + p_source = fix_path(p_source); + p_target = fix_path(p_target); + + if (symlink(p_source.utf8().get_data(), p_target.utf8().get_data()) == 0) { + return OK; + } else { + return FAILED; + } +} + +uint64_t DirAccessUnix::get_space_left() { #ifndef NO_STATVFS struct statvfs vfs; if (statvfs(current_dir.utf8().get_data(), &vfs) != 0) { return 0; }; - return vfs.f_bfree * vfs.f_bsize; + return (uint64_t)vfs.f_bavail * (uint64_t)vfs.f_frsize; #else // FIXME: Implement this. return 0; diff --git a/drivers/unix/dir_access_unix.h b/drivers/unix/dir_access_unix.h index b70df1ca02..8b19308967 100644 --- a/drivers/unix/dir_access_unix.h +++ b/drivers/unix/dir_access_unix.h @@ -33,7 +33,7 @@ #if defined(UNIX_ENABLED) || defined(LIBC_FILEIO_ENABLED) -#include "core/os/dir_access.h" +#include "core/io/dir_access.h" #include <dirent.h> #include <sys/stat.h> @@ -71,13 +71,19 @@ public: virtual bool file_exists(String p_file); virtual bool dir_exists(String p_dir); + virtual bool is_readable(String p_dir); + virtual bool is_writable(String p_dir); virtual uint64_t get_modified_time(String p_file); virtual Error rename(String p_path, String p_new_path); virtual Error remove(String p_path); - virtual size_t get_space_left(); + virtual bool is_link(String p_file); + virtual String read_link(String p_file); + virtual Error create_link(String p_source, String p_target); + + virtual uint64_t get_space_left(); virtual String get_filesystem_type() const; diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index 6b24a85ff6..6ea55219bb 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -184,11 +184,11 @@ String FileAccessUnix::get_path_absolute() const { return path; } -void FileAccessUnix::seek(size_t p_position) { +void FileAccessUnix::seek(uint64_t p_position) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); last_error = OK; - if (fseek(f, p_position, SEEK_SET)) { + if (fseeko(f, p_position, SEEK_SET)) { check_errors(); } } @@ -196,15 +196,15 @@ void FileAccessUnix::seek(size_t p_position) { void FileAccessUnix::seek_end(int64_t p_position) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); - if (fseek(f, p_position, SEEK_END)) { + if (fseeko(f, p_position, SEEK_END)) { check_errors(); } } -size_t FileAccessUnix::get_position() const { +uint64_t FileAccessUnix::get_position() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); - long pos = ftell(f); + int64_t pos = ftello(f); if (pos < 0) { check_errors(); ERR_FAIL_V(0); @@ -212,15 +212,15 @@ size_t FileAccessUnix::get_position() const { return pos; } -size_t FileAccessUnix::get_len() const { +uint64_t FileAccessUnix::get_length() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); - long pos = ftell(f); + int64_t pos = ftello(f); ERR_FAIL_COND_V(pos < 0, 0); - ERR_FAIL_COND_V(fseek(f, 0, SEEK_END), 0); - long size = ftell(f); + ERR_FAIL_COND_V(fseeko(f, 0, SEEK_END), 0); + int64_t size = ftello(f); ERR_FAIL_COND_V(size < 0, 0); - ERR_FAIL_COND_V(fseek(f, pos, SEEK_SET), 0); + ERR_FAIL_COND_V(fseeko(f, pos, SEEK_SET), 0); return size; } @@ -239,9 +239,11 @@ uint8_t FileAccessUnix::get_8() const { return b; } -int FileAccessUnix::get_buffer(uint8_t *p_dst, int p_length) const { +uint64_t FileAccessUnix::get_buffer(uint8_t *p_dst, uint64_t p_length) const { + ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); ERR_FAIL_COND_V_MSG(!f, -1, "File must be opened before use."); - int read = fread(p_dst, 1, p_length, f); + + uint64_t read = fread(p_dst, 1, p_length, f); check_errors(); return read; }; @@ -260,10 +262,10 @@ void FileAccessUnix::store_8(uint8_t p_dest) { ERR_FAIL_COND(fwrite(&p_dest, 1, 1, f) != 1); } -void FileAccessUnix::store_buffer(const uint8_t *p_src, int p_length) { +void FileAccessUnix::store_buffer(const uint8_t *p_src, uint64_t p_length) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); - ERR_FAIL_COND(!p_src); - ERR_FAIL_COND((int)fwrite(p_src, 1, p_length, f) != p_length); + ERR_FAIL_COND(!p_src && p_length > 0); + ERR_FAIL_COND(fwrite(p_src, 1, p_length, f) != p_length); } bool FileAccessUnix::file_exists(const String &p_path) { diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h index 998fad7909..8b27c308e1 100644 --- a/drivers/unix/file_access_unix.h +++ b/drivers/unix/file_access_unix.h @@ -31,7 +31,7 @@ #ifndef FILE_ACCESS_UNIX_H #define FILE_ACCESS_UNIX_H -#include "core/os/file_access.h" +#include "core/io/file_access.h" #include "core/os/memory.h" #include <stdio.h> @@ -61,21 +61,21 @@ public: virtual String get_path() const; /// returns the path for the current open file virtual String get_path_absolute() const; /// returns the absolute path for the current open file - virtual void seek(size_t p_position); ///< seek to a given position + virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file - virtual size_t get_position() const; ///< get position in the file - virtual size_t get_len() const; ///< get size of the file + virtual uint64_t get_position() const; ///< get position in the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF virtual uint8_t get_8() const; ///< get a byte - virtual int get_buffer(uint8_t *p_dst, int p_length) const; + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; virtual Error get_error() const; ///< get last error virtual void flush(); virtual void store_8(uint8_t p_dest); ///< store a byte - virtual void store_buffer(const uint8_t *p_src, int p_length); ///< store an array of bytes + virtual void store_buffer(const uint8_t *p_src, uint64_t p_length); ///< store an array of bytes virtual bool file_exists(const String &p_path); ///< return true if a file exists diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp index 8ec1de4386..8a880ab9c8 100644 --- a/drivers/unix/ip_unix.cpp +++ b/drivers/unix/ip_unix.cpp @@ -41,19 +41,7 @@ #include <windows.h> #include <ws2tcpip.h> #ifndef UWP_ENABLED -#if defined(__MINGW32__) && (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 4) -// MinGW-w64 on Ubuntu 12.04 (our Travis build env) has bugs in this code where -// some includes are missing in dependencies of iphlpapi.h for WINVER >= 0x0600 (Vista). -// We don't use this Vista code for now, so working it around by disabling it. -// MinGW-w64 >= 4.0 seems to be better judging by its headers. -#undef _WIN32_WINNT -#define _WIN32_WINNT 0x0501 // Windows XP, disable Vista API #include <iphlpapi.h> -#undef _WIN32_WINNT -#define _WIN32_WINNT 0x0600 // Re-enable Vista API -#else -#include <iphlpapi.h> -#endif // MINGW hack #endif #else // UNIX #include <netdb.h> @@ -75,8 +63,8 @@ #include <net/if.h> // Order is important on OpenBSD, leave as last #endif -static IP_Address _sockaddr2ip(struct sockaddr *p_addr) { - IP_Address ip; +static IPAddress _sockaddr2ip(struct sockaddr *p_addr) { + IPAddress ip; if (p_addr->sa_family == AF_INET) { struct sockaddr_in *addr = (struct sockaddr_in *)p_addr; @@ -89,7 +77,7 @@ static IP_Address _sockaddr2ip(struct sockaddr *p_addr) { return ip; }; -IP_Address IP_Unix::_resolve_hostname(const String &p_hostname, Type p_type) { +void IPUnix::_resolve_hostname(List<IPAddress> &r_addresses, const String &p_hostname, Type p_type) const { struct addrinfo hints; struct addrinfo *result = nullptr; @@ -108,7 +96,7 @@ IP_Address IP_Unix::_resolve_hostname(const String &p_hostname, Type p_type) { int s = getaddrinfo(p_hostname.utf8().get_data(), nullptr, &hints, &result); if (s != 0) { ERR_PRINT("getaddrinfo failed! Cannot resolve hostname."); - return IP_Address(); + return; }; if (result == nullptr || result->ai_addr == nullptr) { @@ -116,21 +104,31 @@ IP_Address IP_Unix::_resolve_hostname(const String &p_hostname, Type p_type) { if (result) { freeaddrinfo(result); } - return IP_Address(); + return; }; - IP_Address ip = _sockaddr2ip(result->ai_addr); + struct addrinfo *next = result; - freeaddrinfo(result); + do { + if (next->ai_addr == NULL) { + next = next->ai_next; + continue; + } + IPAddress ip = _sockaddr2ip(next->ai_addr); + if (!r_addresses.find(ip)) { + r_addresses.push_back(ip); + } + next = next->ai_next; + } while (next); - return ip; + freeaddrinfo(result); } #if defined(WINDOWS_ENABLED) #if defined(UWP_ENABLED) -void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) const { +void IPUnix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) const { using namespace Windows::Networking; using namespace Windows::Networking::Connectivity; @@ -156,14 +154,14 @@ void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) co Interface_Info &info = E->get(); - IP_Address ip = IP_Address(hostname->CanonicalName->Data()); + IPAddress ip = IPAddress(hostname->CanonicalName->Data()); info.ip_addresses.push_front(ip); } } #else -void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) const { +void IPUnix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) const { ULONG buf_size = 1024; IP_ADAPTER_ADDRESSES *addrs; @@ -211,7 +209,7 @@ void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) co #else // UNIX -void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) const { +void IPUnix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) const { struct ifaddrs *ifAddrStruct = nullptr; struct ifaddrs *ifa = nullptr; int family; @@ -249,15 +247,15 @@ void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) co } #endif -void IP_Unix::make_default() { +void IPUnix::make_default() { _create = _create_unix; } -IP *IP_Unix::_create_unix() { - return memnew(IP_Unix); +IP *IPUnix::_create_unix() { + return memnew(IPUnix); } -IP_Unix::IP_Unix() { +IPUnix::IPUnix() { } #endif diff --git a/drivers/unix/ip_unix.h b/drivers/unix/ip_unix.h index ca2ee17f4e..0d64648b39 100644 --- a/drivers/unix/ip_unix.h +++ b/drivers/unix/ip_unix.h @@ -35,10 +35,10 @@ #if defined(UNIX_ENABLED) || defined(WINDOWS_ENABLED) -class IP_Unix : public IP { - GDCLASS(IP_Unix, IP); +class IPUnix : public IP { + GDCLASS(IPUnix, IP); - virtual IP_Address _resolve_hostname(const String &p_hostname, IP::Type p_type) override; + virtual void _resolve_hostname(List<IPAddress> &r_addresses, const String &p_hostname, Type p_type = TYPE_ANY) const override; static IP *_create_unix(); @@ -46,7 +46,7 @@ public: virtual void get_local_interfaces(Map<String, Interface_Info> *r_interfaces) const override; static void make_default(); - IP_Unix(); + IPUnix(); }; #endif diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp index 19753943c8..efeaf32ff7 100644 --- a/drivers/unix/net_socket_posix.cpp +++ b/drivers/unix/net_socket_posix.cpp @@ -95,7 +95,7 @@ #endif -size_t NetSocketPosix::_set_addr_storage(struct sockaddr_storage *p_addr, const IP_Address &p_ip, uint16_t p_port, IP::Type p_ip_type) { +size_t NetSocketPosix::_set_addr_storage(struct sockaddr_storage *p_addr, const IPAddress &p_ip, uint16_t p_port, IP::Type p_ip_type) { memset(p_addr, 0, sizeof(struct sockaddr_storage)); if (p_ip_type == IP::TYPE_IPV6 || p_ip_type == IP::TYPE_ANY) { // IPv6 socket @@ -106,7 +106,7 @@ size_t NetSocketPosix::_set_addr_storage(struct sockaddr_storage *p_addr, const addr6->sin6_family = AF_INET6; addr6->sin6_port = htons(p_port); if (p_ip.is_valid()) { - copymem(&addr6->sin6_addr.s6_addr, p_ip.get_ipv6(), 16); + memcpy(&addr6->sin6_addr.s6_addr, p_ip.get_ipv6(), 16); } else { addr6->sin6_addr = in6addr_any; } @@ -121,7 +121,7 @@ size_t NetSocketPosix::_set_addr_storage(struct sockaddr_storage *p_addr, const addr4->sin_port = htons(p_port); // short, network byte order if (p_ip.is_valid()) { - copymem(&addr4->sin_addr.s_addr, p_ip.get_ipv4(), 4); + memcpy(&addr4->sin_addr.s_addr, p_ip.get_ipv4(), 4); } else { addr4->sin_addr.s_addr = INADDR_ANY; } @@ -130,18 +130,23 @@ size_t NetSocketPosix::_set_addr_storage(struct sockaddr_storage *p_addr, const } } -void NetSocketPosix::_set_ip_port(struct sockaddr_storage *p_addr, IP_Address &r_ip, uint16_t &r_port) { +void NetSocketPosix::_set_ip_port(struct sockaddr_storage *p_addr, IPAddress *r_ip, uint16_t *r_port) { if (p_addr->ss_family == AF_INET) { struct sockaddr_in *addr4 = (struct sockaddr_in *)p_addr; - r_ip.set_ipv4((uint8_t *)&(addr4->sin_addr.s_addr)); - - r_port = ntohs(addr4->sin_port); - + if (r_ip) { + r_ip->set_ipv4((uint8_t *)&(addr4->sin_addr.s_addr)); + } + if (r_port) { + *r_port = ntohs(addr4->sin_port); + } } else if (p_addr->ss_family == AF_INET6) { struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)p_addr; - r_ip.set_ipv6(addr6->sin6_addr.s6_addr); - - r_port = ntohs(addr6->sin6_port); + if (r_ip) { + r_ip->set_ipv6(addr6->sin6_addr.s6_addr); + } + if (r_port) { + *r_port = ntohs(addr6->sin6_port); + } }; } @@ -186,13 +191,21 @@ NetSocketPosix::~NetSocketPosix() { NetSocketPosix::NetError NetSocketPosix::_get_socket_error() const { #if defined(WINDOWS_ENABLED) int err = WSAGetLastError(); - - if (err == WSAEISCONN) + if (err == WSAEISCONN) { return ERR_NET_IS_CONNECTED; - if (err == WSAEINPROGRESS || err == WSAEALREADY) + } + if (err == WSAEINPROGRESS || err == WSAEALREADY) { return ERR_NET_IN_PROGRESS; - if (err == WSAEWOULDBLOCK) + } + if (err == WSAEWOULDBLOCK) { return ERR_NET_WOULD_BLOCK; + } + if (err == WSAEADDRINUSE || err == WSAEADDRNOTAVAIL) { + return ERR_NET_ADDRESS_INVALID_OR_UNAVAILABLE; + } + if (err == WSAEACCES) { + return ERR_NET_UNAUTHORIZED; + } print_verbose("Socket error: " + itos(err)); return ERR_NET_OTHER; #else @@ -205,6 +218,12 @@ NetSocketPosix::NetError NetSocketPosix::_get_socket_error() const { if (errno == EAGAIN || errno == EWOULDBLOCK) { return ERR_NET_WOULD_BLOCK; } + if (errno == EADDRINUSE || errno == EINVAL || errno == EADDRNOTAVAIL) { + return ERR_NET_ADDRESS_INVALID_OR_UNAVAILABLE; + } + if (errno == EACCES) { + return ERR_NET_UNAUTHORIZED; + } print_verbose("Socket error: " + itos(errno)); return ERR_NET_OTHER; #endif @@ -214,7 +233,7 @@ NetSocketPosix::NetError NetSocketPosix::_get_socket_error() const { #pragma GCC diagnostic pop #endif -bool NetSocketPosix::_can_use_ip(const IP_Address &p_ip, const bool p_for_bind) const { +bool NetSocketPosix::_can_use_ip(const IPAddress &p_ip, const bool p_for_bind) const { if (p_for_bind && !(p_ip.is_valid() || p_ip.is_wildcard())) { return false; } else if (!p_for_bind && !p_ip.is_valid()) { @@ -225,7 +244,7 @@ bool NetSocketPosix::_can_use_ip(const IP_Address &p_ip, const bool p_for_bind) return !(_ip_type != IP::TYPE_ANY && !p_ip.is_wildcard() && _ip_type != type); } -_FORCE_INLINE_ Error NetSocketPosix::_change_multicast_group(IP_Address p_ip, String p_if_name, bool p_add) { +_FORCE_INLINE_ Error NetSocketPosix::_change_multicast_group(IPAddress p_ip, String p_if_name, bool p_add) { ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); ERR_FAIL_COND_V(!_can_use_ip(p_ip, false), ERR_INVALID_PARAMETER); @@ -235,7 +254,7 @@ _FORCE_INLINE_ Error NetSocketPosix::_change_multicast_group(IP_Address p_ip, St int level = type == IP::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; int ret = -1; - IP_Address if_ip; + IPAddress if_ip; uint32_t if_v6id = 0; Map<String, IP::Interface_Info> if_info; IP::get_singleton()->get_local_interfaces(&if_info); @@ -250,7 +269,7 @@ _FORCE_INLINE_ Error NetSocketPosix::_change_multicast_group(IP_Address p_ip, St break; // IPv6 uses index. } - for (List<IP_Address>::Element *F = c.ip_addresses.front(); F; F = F->next()) { + for (List<IPAddress>::Element *F = c.ip_addresses.front(); F; F = F->next()) { if (!F->get().is_ipv4()) { continue; // Wrong IP type } @@ -264,13 +283,13 @@ _FORCE_INLINE_ Error NetSocketPosix::_change_multicast_group(IP_Address p_ip, St ERR_FAIL_COND_V(!if_ip.is_valid(), ERR_INVALID_PARAMETER); struct ip_mreq greq; int sock_opt = p_add ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP; - copymem(&greq.imr_multiaddr, p_ip.get_ipv4(), 4); - copymem(&greq.imr_interface, if_ip.get_ipv4(), 4); + memcpy(&greq.imr_multiaddr, p_ip.get_ipv4(), 4); + memcpy(&greq.imr_interface, if_ip.get_ipv4(), 4); ret = setsockopt(_sock, level, sock_opt, (const char *)&greq, sizeof(greq)); } else { struct ipv6_mreq greq; int sock_opt = p_add ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP; - copymem(&greq.ipv6mr_multiaddr, p_ip.get_ipv6(), 16); + memcpy(&greq.ipv6mr_multiaddr, p_ip.get_ipv6(), 16); greq.ipv6mr_interface = if_v6id; ret = setsockopt(_sock, level, sock_opt, (const char *)&greq, sizeof(greq)); } @@ -376,7 +395,7 @@ void NetSocketPosix::close() { _is_stream = false; } -Error NetSocketPosix::bind(IP_Address p_addr, uint16_t p_port) { +Error NetSocketPosix::bind(IPAddress p_addr, uint16_t p_port) { ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); ERR_FAIL_COND_V(!_can_use_ip(p_addr, true), ERR_INVALID_PARAMETER); @@ -384,8 +403,8 @@ Error NetSocketPosix::bind(IP_Address p_addr, uint16_t p_port) { size_t addr_size = _set_addr_storage(&addr, p_addr, p_port, _ip_type); if (::bind(_sock, (struct sockaddr *)&addr, addr_size) != 0) { - _get_socket_error(); - print_verbose("Failed to bind socket."); + NetError err = _get_socket_error(); + print_verbose("Failed to bind socket. Error: " + itos(err)); close(); return ERR_UNAVAILABLE; } @@ -406,7 +425,7 @@ Error NetSocketPosix::listen(int p_max_pending) { return OK; } -Error NetSocketPosix::connect_to_host(IP_Address p_host, uint16_t p_port) { +Error NetSocketPosix::connect_to_host(IPAddress p_host, uint16_t p_port) { ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); ERR_FAIL_COND_V(!_can_use_ip(p_host, false), ERR_INVALID_PARAMETER); @@ -446,8 +465,8 @@ Error NetSocketPosix::poll(PollType p_type, int p_timeout) const { FD_ZERO(&wr); FD_ZERO(&ex); FD_SET(_sock, &ex); - struct timeval timeout = { p_timeout, 0 }; - // For blocking operation, pass nullptr timeout pointer to select. + struct timeval timeout = { p_timeout / 1000, (p_timeout % 1000) * 1000 }; + // For blocking operation, pass nullptr timeout pointer to select. struct timeval *tp = nullptr; if (p_timeout >= 0) { // If timeout is non-negative, we want to specify the timeout instead. @@ -540,7 +559,7 @@ Error NetSocketPosix::recv(uint8_t *p_buffer, int p_len, int &r_read) { return OK; } -Error NetSocketPosix::recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IP_Address &r_ip, uint16_t &r_port, bool p_peek) { +Error NetSocketPosix::recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IPAddress &r_ip, uint16_t &r_port, bool p_peek) { ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); struct sockaddr_storage from; @@ -597,7 +616,7 @@ Error NetSocketPosix::send(const uint8_t *p_buffer, int p_len, int &r_sent) { return OK; } -Error NetSocketPosix::sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IP_Address p_ip, uint16_t p_port) { +Error NetSocketPosix::sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IPAddress p_ip, uint16_t p_port) { ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); struct sockaddr_storage addr; @@ -716,7 +735,21 @@ int NetSocketPosix::get_available_bytes() const { return len; } -Ref<NetSocket> NetSocketPosix::accept(IP_Address &r_ip, uint16_t &r_port) { +Error NetSocketPosix::get_socket_address(IPAddress *r_ip, uint16_t *r_port) const { + ERR_FAIL_COND_V(!is_open(), FAILED); + + struct sockaddr_storage saddr; + socklen_t len = sizeof(saddr); + if (getsockname(_sock, (struct sockaddr *)&saddr, &len) != 0) { + _get_socket_error(); + print_verbose("Error when reading local socket address."); + return FAILED; + } + _set_ip_port(&saddr, r_ip, r_port); + return OK; +} + +Ref<NetSocket> NetSocketPosix::accept(IPAddress &r_ip, uint16_t &r_port) { Ref<NetSocket> out; ERR_FAIL_COND_V(!is_open(), out); @@ -729,7 +762,7 @@ Ref<NetSocket> NetSocketPosix::accept(IP_Address &r_ip, uint16_t &r_port) { return out; } - _set_ip_port(&their_addr, r_ip, r_port); + _set_ip_port(&their_addr, &r_ip, &r_port); NetSocketPosix *ns = memnew(NetSocketPosix); ns->_set_socket(fd, _ip_type, _is_stream); @@ -737,11 +770,11 @@ Ref<NetSocket> NetSocketPosix::accept(IP_Address &r_ip, uint16_t &r_port) { return Ref<NetSocket>(ns); } -Error NetSocketPosix::join_multicast_group(const IP_Address &p_multi_address, String p_if_name) { +Error NetSocketPosix::join_multicast_group(const IPAddress &p_multi_address, String p_if_name) { return _change_multicast_group(p_multi_address, p_if_name, true); } -Error NetSocketPosix::leave_multicast_group(const IP_Address &p_multi_address, String p_if_name) { +Error NetSocketPosix::leave_multicast_group(const IPAddress &p_multi_address, String p_if_name) { return _change_multicast_group(p_multi_address, p_if_name, false); } #endif diff --git a/drivers/unix/net_socket_posix.h b/drivers/unix/net_socket_posix.h index cc6af661c8..38c8170a52 100644 --- a/drivers/unix/net_socket_posix.h +++ b/drivers/unix/net_socket_posix.h @@ -54,39 +54,42 @@ private: ERR_NET_WOULD_BLOCK, ERR_NET_IS_CONNECTED, ERR_NET_IN_PROGRESS, - ERR_NET_OTHER + ERR_NET_ADDRESS_INVALID_OR_UNAVAILABLE, + ERR_NET_UNAUTHORIZED, + ERR_NET_OTHER, }; NetError _get_socket_error() const; void _set_socket(SOCKET_TYPE p_sock, IP::Type p_ip_type, bool p_is_stream); - _FORCE_INLINE_ Error _change_multicast_group(IP_Address p_ip, String p_if_name, bool p_add); + _FORCE_INLINE_ Error _change_multicast_group(IPAddress p_ip, String p_if_name, bool p_add); _FORCE_INLINE_ void _set_close_exec_enabled(bool p_enabled); protected: static NetSocket *_create_func(); - bool _can_use_ip(const IP_Address &p_ip, const bool p_for_bind) const; + bool _can_use_ip(const IPAddress &p_ip, const bool p_for_bind) const; public: static void make_default(); static void cleanup(); - static void _set_ip_port(struct sockaddr_storage *p_addr, IP_Address &r_ip, uint16_t &r_port); - static size_t _set_addr_storage(struct sockaddr_storage *p_addr, const IP_Address &p_ip, uint16_t p_port, IP::Type p_ip_type); + static void _set_ip_port(struct sockaddr_storage *p_addr, IPAddress *r_ip, uint16_t *r_port); + static size_t _set_addr_storage(struct sockaddr_storage *p_addr, const IPAddress &p_ip, uint16_t p_port, IP::Type p_ip_type); virtual Error open(Type p_sock_type, IP::Type &ip_type); virtual void close(); - virtual Error bind(IP_Address p_addr, uint16_t p_port); + virtual Error bind(IPAddress p_addr, uint16_t p_port); virtual Error listen(int p_max_pending); - virtual Error connect_to_host(IP_Address p_host, uint16_t p_port); + virtual Error connect_to_host(IPAddress p_host, uint16_t p_port); virtual Error poll(PollType p_type, int timeout) const; virtual Error recv(uint8_t *p_buffer, int p_len, int &r_read); - virtual Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IP_Address &r_ip, uint16_t &r_port, bool p_peek = false); + virtual Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IPAddress &r_ip, uint16_t &r_port, bool p_peek = false); virtual Error send(const uint8_t *p_buffer, int p_len, int &r_sent); - virtual Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IP_Address p_ip, uint16_t p_port); - virtual Ref<NetSocket> accept(IP_Address &r_ip, uint16_t &r_port); + virtual Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IPAddress p_ip, uint16_t p_port); + virtual Ref<NetSocket> accept(IPAddress &r_ip, uint16_t &r_port); virtual bool is_open() const; virtual int get_available_bytes() const; + virtual Error get_socket_address(IPAddress *r_ip, uint16_t *r_port) const; virtual Error set_broadcasting_enabled(bool p_enabled); virtual void set_blocking_enabled(bool p_enabled); @@ -94,8 +97,8 @@ public: virtual void set_tcp_no_delay_enabled(bool p_enabled); virtual void set_reuse_address_enabled(bool p_enabled); virtual void set_reuse_port_enabled(bool p_enabled); - virtual Error join_multicast_group(const IP_Address &p_multi_address, String p_if_name); - virtual Error leave_multicast_group(const IP_Address &p_multi_address, String p_if_name); + virtual Error join_multicast_group(const IPAddress &p_multi_address, String p_if_name); + virtual Error leave_multicast_group(const IPAddress &p_multi_address, String p_if_name); NetSocketPosix(); ~NetSocketPosix(); diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index b9bd773c2e..a5c61bbea5 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -129,7 +129,7 @@ void OS_Unix::initialize_core() { #ifndef NO_NETWORK NetSocketPosix::make_default(); - IP_Unix::make_default(); + IPUnix::make_default(); #endif _setup_clock(); @@ -195,8 +195,8 @@ OS::Time OS_Unix::get_time(bool utc) const { } Time ret; ret.hour = lt.tm_hour; - ret.min = lt.tm_min; - ret.sec = lt.tm_sec; + ret.minute = lt.tm_min; + ret.second = lt.tm_sec; get_time_zone_info(); return ret; } diff --git a/drivers/unix/thread_posix.cpp b/drivers/unix/thread_posix.cpp index 19fab1d475..e47046e3ae 100644 --- a/drivers/unix/thread_posix.cpp +++ b/drivers/unix/thread_posix.cpp @@ -35,6 +35,10 @@ #include "core/os/thread.h" #include "core/string/ustring.h" +#ifdef PTHREAD_BSD_SET_NAME +#include <pthread_np.h> +#endif + static Error set_name(const String &p_name) { #ifdef PTHREAD_NO_RENAME return ERR_UNAVAILABLE; |