diff options
Diffstat (limited to 'drivers/unix')
26 files changed, 572 insertions, 705 deletions
diff --git a/drivers/unix/SCsub b/drivers/unix/SCsub index 3d46a85cdf..3766e782e4 100644 --- a/drivers/unix/SCsub +++ b/drivers/unix/SCsub @@ -1,15 +1,17 @@ +#!/usr/bin/env python + Import('env') -g_set_p='#ifdef UNIX_ENABLED\n' -g_set_p+='#include "os_unix.h"\n' -g_set_p+='String OS_Unix::get_global_settings_path() const {\n' -g_set_p+='\treturn "' + env["unix_global_settings_path"]+'";\n' -g_set_p+='}\n' -g_set_p+='#endif' -f = open("os_unix_global_settings_path.cpp","wb") +g_set_p = '#ifdef UNIX_ENABLED\n' +g_set_p += '#include "os_unix.h"\n' +g_set_p += 'String OS_Unix::get_global_settings_path() const {\n' +g_set_p += '\treturn "' + env["unix_global_settings_path"] + '";\n' +g_set_p += '}\n' +g_set_p += '#endif' +f = open("os_unix_global_settings_path.cpp", "wb") f.write(g_set_p) f.close() -env.add_source_files(env.drivers_sources,"*.cpp") +env.add_source_files(env.drivers_sources, "*.cpp") Export('env') diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index 8b097ad25e..a09cf80e6c 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -44,20 +44,20 @@ DirAccess *DirAccessUnix::create_fs() { return memnew( DirAccessUnix ); } -bool DirAccessUnix::list_dir_begin() { +Error DirAccessUnix::list_dir_begin() { list_dir_end(); //close any previous dir opening! -// char real_current_dir_name[2048]; //is this enough?! + //char real_current_dir_name[2048]; //is this enough?! //getcwd(real_current_dir_name,2048); //chdir(curent_path.utf8().get_data()); dir_stream = opendir(current_dir.utf8().get_data()); //chdir(real_current_dir_name); if (!dir_stream) - return true; //error! + return ERR_CANT_OPEN; //error! - return false; + return OK; } bool DirAccessUnix::file_exists(String p_file) { @@ -66,9 +66,9 @@ bool DirAccessUnix::file_exists(String p_file) { if (p_file.is_rel_path()) - p_file=current_dir+"/"+p_file; - else - p_file=fix_path(p_file); + p_file=current_dir.plus_file(p_file); + + p_file=fix_path(p_file); struct stat flags; bool success = (stat(p_file.utf8().get_data(),&flags)==0); @@ -88,8 +88,8 @@ bool DirAccessUnix::dir_exists(String p_dir) { if (p_dir.is_rel_path()) p_dir=get_current_dir().plus_file(p_dir); - else - p_dir=fix_path(p_dir); + + p_dir=fix_path(p_dir); struct stat flags; bool success = (stat(p_dir.utf8().get_data(),&flags)==0); @@ -104,9 +104,9 @@ bool DirAccessUnix::dir_exists(String p_dir) { uint64_t DirAccessUnix::get_modified_time(String p_file) { if (p_file.is_rel_path()) - p_file=current_dir+"/"+p_file; - else - p_file=fix_path(p_file); + p_file=current_dir.plus_file(p_file); + + p_file=fix_path(p_file); struct stat flags; bool success = (stat(p_file.utf8().get_data(),&flags)==0); @@ -138,11 +138,9 @@ String DirAccessUnix::get_next() { //typedef struct stat Stat; struct stat flags; - String fname; - if (fname.parse_utf8(entry->d_name)) - fname=entry->d_name; //no utf8, maybe latin? + String fname = fix_unicode_name(entry->d_name); - String f=current_dir+"/"+fname; + String f=current_dir.plus_file(fname); if (stat(f.utf8().get_data(),&flags)==0) { @@ -201,8 +199,20 @@ Error DirAccessUnix::make_dir(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); - + + +#if 1 + + + bool success=(mkdir(p_dir.utf8().get_data(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)==0); + int err = errno; + +#else char real_current_dir_name[2048]; getcwd(real_current_dir_name,2048); chdir(current_dir.utf8().get_data()); //ascii since this may be unicode or wathever the host os wants @@ -211,7 +221,7 @@ Error DirAccessUnix::make_dir(String p_dir) { int err = errno; chdir(real_current_dir_name); - +#endif if (success) { return OK; }; @@ -238,7 +248,7 @@ Error DirAccessUnix::change_dir(String p_dir) { chdir(current_dir.utf8().get_data()); //ascii since this may be unicode or wathever the host os wants bool worked=(chdir(p_dir.utf8().get_data())==0); // we can only give this utf8 -#ifndef IPHONE_ENABLED + String base = _get_root_path(); if (base!="") { @@ -248,7 +258,7 @@ Error DirAccessUnix::change_dir(String p_dir) { if (!new_dir.begins_with(base)) worked=false; } -#endif + if (worked) { getcwd(real_current_dir_name,2048); @@ -280,13 +290,13 @@ Error DirAccessUnix::rename(String p_path,String p_new_path) { if (p_path.is_rel_path()) p_path=get_current_dir().plus_file(p_path); - else - p_path=fix_path(p_path); + + p_path=fix_path(p_path); if (p_new_path.is_rel_path()) p_new_path=get_current_dir().plus_file(p_new_path); - else - p_new_path=fix_path(p_new_path); + + p_new_path=fix_path(p_new_path); return ::rename(p_path.utf8().get_data(),p_new_path.utf8().get_data())==0?OK:FAILED; } @@ -294,8 +304,8 @@ Error DirAccessUnix::remove(String p_path) { if (p_path.is_rel_path()) p_path=get_current_dir().plus_file(p_path); - else - p_path=fix_path(p_path); + + p_path=fix_path(p_path); struct stat flags; if ((stat(p_path.utf8().get_data(),&flags)!=0)) @@ -314,7 +324,7 @@ size_t DirAccessUnix::get_space_left() { struct statvfs vfs; if (statvfs(current_dir.utf8().get_data(), &vfs) != 0) { - return -1; + return 0; }; return vfs.f_bfree * vfs.f_bsize; diff --git a/drivers/unix/dir_access_unix.h b/drivers/unix/dir_access_unix.h index 9cba1ed3e0..f075c48268 100644 --- a/drivers/unix/dir_access_unix.h +++ b/drivers/unix/dir_access_unix.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -51,10 +51,13 @@ class DirAccessUnix : public DirAccess { String current_dir; bool _cisdir; bool _cishidden; - +protected: + + virtual String fix_unicode_name(const char* p_name) const { return String::utf8(p_name); } + public: - virtual bool list_dir_begin(); ///< This starts dir listing + virtual Error list_dir_begin(); ///< This starts dir listing virtual String get_next(); virtual bool current_is_dir() const; virtual bool current_is_hidden() const; diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index 9f24633bd4..ee51db6694 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -124,6 +124,11 @@ void FileAccessUnix::close() { //unlink(save_path.utf8().get_data()); //print_line("renaming.."); int rename_error = rename((save_path+".tmp").utf8().get_data(),save_path.utf8().get_data()); + + if (rename_error && close_fail_notify) { + close_fail_notify(save_path); + } + save_path=""; ERR_FAIL_COND( rename_error != 0); } diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h index d6a172bf47..57b643dc26 100644 --- a/drivers/unix/file_access_unix.h +++ b/drivers/unix/file_access_unix.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp index 535a425302..fc0b3faccc 100644 --- a/drivers/unix/ip_unix.cpp +++ b/drivers/unix/ip_unix.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,23 +28,30 @@ /*************************************************************************/ #include "ip_unix.h" -#if defined(UNIX_ENABLED) || defined(WINDOWS_ENABLED) && !defined(WINRT_ENABLED) +#if defined(UNIX_ENABLED) || defined(WINDOWS_ENABLED) +#include <string.h> #ifdef WINDOWS_ENABLED - #ifdef WINRT_ENABLED #include <ws2tcpip.h> #include <winsock2.h> #include <windows.h> #include <stdio.h> - #else - #define WINVER 0x0600 - #include <ws2tcpip.h> - #include <winsock2.h> - #include <windows.h> - #include <stdio.h> - #include <iphlpapi.h> - #endif + #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 // Reenable Vista API + #else + #include <iphlpapi.h> + #endif // MINGW hack + #endif #else #include <netdb.h> #ifdef ANDROID_ENABLED @@ -62,16 +69,50 @@ #endif #endif -IP_Address IP_Unix::_resolve_hostname(const String& p_hostname) { +static IP_Address _sockaddr2ip(struct sockaddr* p_addr) { - struct hostent *he; - if ((he=gethostbyname(p_hostname.utf8().get_data())) == NULL) { // get the host info - ERR_PRINT("gethostbyname failed!"); - return IP_Address(); - } IP_Address ip; + if (p_addr->sa_family == AF_INET) { + struct sockaddr_in* addr = (struct sockaddr_in*)p_addr; + ip.set_ipv4((uint8_t *)&(addr->sin_addr)); + } else { + struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr; + ip.set_ipv6(addr6->sin6_addr.s6_addr); + }; - ip.host= *((unsigned long*)he->h_addr); + return ip; +}; + +IP_Address IP_Unix::_resolve_hostname(const String& p_hostname, Type p_type) { + + struct addrinfo hints; + struct addrinfo* result; + + memset(&hints, 0, sizeof(struct addrinfo)); + if (p_type == TYPE_IPV4) { + hints.ai_family = AF_INET; + } else if (p_type == TYPE_IPV6) { + hints.ai_family = AF_INET6; + hints.ai_flags = 0; + } else { + hints.ai_family = AF_UNSPEC; + hints.ai_flags = AI_ADDRCONFIG; + }; + + int s = getaddrinfo(p_hostname.utf8().get_data(), NULL, &hints, &result); + if (s != 0) { + ERR_PRINT("getaddrinfo failed!"); + return IP_Address(); + }; + + if (result == NULL || result->ai_addr == NULL) { + ERR_PRINT("Invalid response from getaddrinfo"); + return IP_Address(); + }; + + IP_Address ip = _sockaddr2ip(result->ai_addr); + + freeaddrinfo(result); return ip; @@ -79,10 +120,22 @@ IP_Address IP_Unix::_resolve_hostname(const String& p_hostname) { #if defined(WINDOWS_ENABLED) -#if defined(WINRT_ENABLED) +#if defined(UWP_ENABLED) void IP_Unix::get_local_addresses(List<IP_Address> *r_addresses) const { + using namespace Windows::Networking; + using namespace Windows::Networking::Connectivity; + + auto hostnames = NetworkInformation::GetHostNames(); + + for (int i = 0; i < hostnames->Size; i++) { + + if (hostnames->GetAt(i)->Type == HostNameType::Ipv4 || hostnames->GetAt(i)->Type == HostNameType::Ipv6 && hostnames->GetAt(i)->IPInformation != nullptr) { + + r_addresses->push_back(IP_Address(String(hostnames->GetAt(i)->CanonicalName->Data()))); + } + } }; #else @@ -95,7 +148,7 @@ void IP_Unix::get_local_addresses(List<IP_Address> *r_addresses) const { while (true) { addrs = (IP_ADAPTER_ADDRESSES*)memalloc(buf_size); - int err = GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_ANYCAST | + int err = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME, @@ -121,14 +174,20 @@ void IP_Unix::get_local_addresses(List<IP_Address> *r_addresses) const { IP_ADAPTER_UNICAST_ADDRESS* address = adapter->FirstUnicastAddress; while (address != NULL) { - char addr_chr[INET_ADDRSTRLEN]; - SOCKADDR_IN* ipv4 = reinterpret_cast<SOCKADDR_IN*>(address->Address.lpSockaddr); - IP_Address ip; - ip.host= *((unsigned long*)&ipv4->sin_addr); + if (address->Address.lpSockaddr->sa_family == AF_INET) { + + SOCKADDR_IN* ipv4 = reinterpret_cast<SOCKADDR_IN*>(address->Address.lpSockaddr); + + ip.set_ipv4((uint8_t *)&(ipv4->sin_addr)); + } else { // ipv6 + + SOCKADDR_IN6* ipv6 = reinterpret_cast<SOCKADDR_IN6*>(address->Address.lpSockaddr); + + ip.set_ipv6(ipv6->sin6_addr.s6_addr); + }; - //inet_ntop(AF_INET, &ipv4->sin_addr, addr_chr, INET_ADDRSTRLEN); r_addresses->push_back(ip); @@ -154,20 +213,9 @@ void IP_Unix::get_local_addresses(List<IP_Address> *r_addresses) const { for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) { if (!ifa->ifa_addr) continue; - if (ifa ->ifa_addr->sa_family==AF_INET) { // check it is IP4 - // is a valid IP4 Address - - IP_Address ip; - ip.host= *((unsigned long*)&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr); - r_addresses->push_back(ip); - }/* else if (ifa->ifa_addr->sa_family==AF_INET6) { // check it is IP6 - // is a valid IP6 Address - tmpAddrPtr=&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; - char addressBuffer[INET6_ADDRSTRLEN]; - inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN); - printf("%s IP Address %s\n", ifa->ifa_name, addressBuffer); - } */ + IP_Address ip = _sockaddr2ip(ifa->ifa_addr); + r_addresses->push_back(ip); } if (ifAddrStruct!=NULL) freeifaddrs(ifAddrStruct); diff --git a/drivers/unix/ip_unix.h b/drivers/unix/ip_unix.h index c0034c9a3a..eb7ebf8bb0 100644 --- a/drivers/unix/ip_unix.h +++ b/drivers/unix/ip_unix.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -34,9 +34,9 @@ #if defined(UNIX_ENABLED) || defined(WINDOWS_ENABLED) class IP_Unix : public IP { - OBJ_TYPE(IP_Unix, IP); + GDCLASS(IP_Unix, IP); - virtual IP_Address _resolve_hostname(const String& p_hostname); + virtual IP_Address _resolve_hostname(const String& p_hostname, IP::Type p_type); static IP* _create_unix(); public: diff --git a/drivers/unix/memory_pool_static_malloc.cpp b/drivers/unix/memory_pool_static_malloc.cpp index f89b55de12..139597f9cb 100644 --- a/drivers/unix/memory_pool_static_malloc.cpp +++ b/drivers/unix/memory_pool_static_malloc.cpp @@ -1,434 +1,2 @@ -/*************************************************************************/ -/* memory_pool_static_malloc.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "memory_pool_static_malloc.h" -#include "error_macros.h" -#include "os/memory.h" -#include <stdlib.h> -#include <stdio.h> -#include "os/copymem.h" -#include "os/os.h" - -/** - * NOTE NOTE NOTE NOTE - * in debug mode, this prepends the memory size to the allocated block - * so BE CAREFUL! - */ - -void* MemoryPoolStaticMalloc::alloc(size_t p_bytes,const char *p_description) { - - #if DEFAULT_ALIGNMENT == 1 - - return _alloc(p_bytes, p_description); - - #else - - size_t total; - #if defined(_add_overflow) - if (_add_overflow(p_bytes, DEFAULT_ALIGNMENT, &total)) return NULL; - #else - total = p_bytes + DEFAULT_ALIGNMENT; - #endif - uint8_t* ptr = (uint8_t*)_alloc(total, p_description); - ERR_FAIL_COND_V( !ptr, ptr ); - int ofs = (DEFAULT_ALIGNMENT - ((uintptr_t)ptr & (DEFAULT_ALIGNMENT - 1))); - ptr[ofs-1] = ofs; - return (void*)(ptr + ofs); - #endif -}; - -void* MemoryPoolStaticMalloc::_alloc(size_t p_bytes,const char *p_description) { - - ERR_FAIL_COND_V(p_bytes==0,0); - - MutexLock lock(mutex); - -#ifdef DEBUG_MEMORY_ENABLED - - size_t total; - #if defined(_add_overflow) - if (_add_overflow(p_bytes, sizeof(RingPtr), &total)) return NULL; - #else - total = p_bytes + sizeof(RingPtr); - #endif - void *mem=malloc(total); /// add for size and ringlist - - if (!mem) { - printf("**ERROR: out of memory while allocating %lu bytes by %s?\n", (unsigned long) p_bytes, p_description); - printf("**ERROR: memory usage is %lu\n", (unsigned long) get_total_usage()); - }; - - ERR_FAIL_COND_V(!mem,0); //out of memory, or unreasonable request - - /* setup the ringlist element */ - - RingPtr *ringptr = (RingPtr*)mem; - - /* setup the ringlist element data (description and size ) */ - - ringptr->size = p_bytes; - ringptr->descr=p_description; - - if (ringlist) { /* existing ringlist */ - - /* assign next */ - ringptr->next = ringlist->next; - ringlist->next = ringptr; - /* assign prev */ - ringptr->prev = ringlist; - ringptr->next->prev = ringptr; - } else { /* non existing ringlist */ - - ringptr->next=ringptr; - ringptr->prev=ringptr; - ringlist=ringptr; - - } - - total_mem+=p_bytes; - - /* update statistics */ - if (total_mem > max_mem ) - max_mem = total_mem; - - total_pointers++; - - if (total_pointers > max_pointers) - max_pointers=total_pointers; - - return ringptr + 1; /* return memory after ringptr */ - -#else - void *mem=malloc(p_bytes); - - ERR_FAIL_COND_V(!mem,0); //out of memory, or unreasonable request - return mem; -#endif -} - - -void* MemoryPoolStaticMalloc::realloc(void *p_memory,size_t p_bytes) { - - #if DEFAULT_ALIGNMENT == 1 - - return _realloc(p_memory,p_bytes); - #else - if (!p_memory) - return alloc(p_bytes); - - size_t total; - #if defined(_add_overflow) - if (_add_overflow(p_bytes, DEFAULT_ALIGNMENT, &total)) return NULL; - #else - total = p_bytes + DEFAULT_ALIGNMENT; - #endif - uint8_t* mem = (uint8_t*)p_memory; - int ofs = *(mem-1); - mem = mem - ofs; - uint8_t* ptr = (uint8_t*)_realloc(mem, total); - ERR_FAIL_COND_V(ptr == NULL, NULL); - int new_ofs = (DEFAULT_ALIGNMENT - ((uintptr_t)ptr & (DEFAULT_ALIGNMENT - 1))); - if (new_ofs != ofs) { - - //printf("realloc moving %i bytes\n", p_bytes); - movemem((ptr + new_ofs), (ptr + ofs), p_bytes); - ptr[new_ofs-1] = new_ofs; - }; - return ptr + new_ofs; - #endif -}; - -void* MemoryPoolStaticMalloc::_realloc(void *p_memory,size_t p_bytes) { - - if (p_memory==NULL) { - - return alloc( p_bytes ); - } - - if (p_bytes==0) { - - this->free(p_memory); - ERR_FAIL_COND_V( p_bytes < 0 , NULL ); - return NULL; - } - - MutexLock lock(mutex); - -#ifdef DEBUG_MEMORY_ENABLED - - - RingPtr *ringptr = (RingPtr*)p_memory; - ringptr--; /* go back an element to find the tingptr */ - - bool single_element = (ringptr->next == ringptr) && (ringptr->prev == ringptr); - bool is_list = ( ringlist == ringptr ); - - RingPtr *new_ringptr=(RingPtr*)::realloc(ringptr, p_bytes+sizeof(RingPtr)); - - ERR_FAIL_COND_V( new_ringptr == 0, NULL ); /// reallocation failed - - /* actualize mem used */ - total_mem -= new_ringptr->size; - new_ringptr->size = p_bytes; - total_mem += new_ringptr->size; - - if (total_mem > max_mem ) //update statistics - max_mem = total_mem; - - if (new_ringptr == ringptr ) - return ringptr + 1; // block didn't move, don't do anything - - if (single_element) { - - new_ringptr->next=new_ringptr; - new_ringptr->prev=new_ringptr; - } else { - - new_ringptr->next->prev=new_ringptr; - new_ringptr->prev->next=new_ringptr; - } - - if (is_list) - ringlist=new_ringptr; - - - return new_ringptr + 1; - -#else - return ::realloc( p_memory, p_bytes ); -#endif -} - -void MemoryPoolStaticMalloc::free(void *p_ptr) { - - ERR_FAIL_COND( !MemoryPoolStatic::get_singleton()); - - #if DEFAULT_ALIGNMENT == 1 - - _free(p_ptr); - #else - - uint8_t* mem = (uint8_t*)p_ptr; - int ofs = *(mem-1); - mem = mem - ofs; - - _free(mem); - #endif -}; - - -void MemoryPoolStaticMalloc::_free(void *p_ptr) { - - MutexLock lock(mutex); - -#ifdef DEBUG_MEMORY_ENABLED - - if (p_ptr==0) { - printf("**ERROR: STATIC ALLOC: Attempted free of NULL pointer.\n"); - return; - }; - - RingPtr *ringptr = (RingPtr*)p_ptr; - - ringptr--; /* go back an element to find the ringptr */ - - -#if 0 - { // check for existing memory on free. - RingPtr *p = ringlist; - - bool found=false; - - if (ringlist) { - do { - if (p==ringptr) { - found=true; - break; - } - - p=p->next; - } while (p!=ringlist); - } - - if (!found) { - printf("**ERROR: STATIC ALLOC: Attempted free of unknown pointer at %p\n",(ringptr+1)); - return; - } - - } -#endif - /* proceed to erase */ - - bool single_element = (ringptr->next == ringptr) && (ringptr->prev == ringptr); - bool is_list = ( ringlist == ringptr ); - - if (single_element) { - /* just get rid of it */ - ringlist=0; - - } else { - /* auto-remove from ringlist */ - if (is_list) - ringlist=ringptr->next; - - ringptr->prev->next = ringptr->next; - ringptr->next->prev = ringptr->prev; - } - - total_mem -= ringptr->size; - total_pointers--; - // catch more errors - zeromem(ringptr,sizeof(RingPtr)+ringptr->size); - ::free(ringptr); //just free that pointer - -#else - ERR_FAIL_COND(p_ptr==0); - - ::free(p_ptr); -#endif -} - - -size_t MemoryPoolStaticMalloc::get_available_mem() const { - - return 0xffffffff; -} - -size_t MemoryPoolStaticMalloc::get_total_usage() { - -#ifdef DEBUG_MEMORY_ENABLED - - return total_mem; -#else - return 0; -#endif - -} - -size_t MemoryPoolStaticMalloc::get_max_usage() { - - return max_mem; -} - -/* Most likely available only if memory debugger was compiled in */ -int MemoryPoolStaticMalloc::get_alloc_count() { - - return total_pointers; -} -void * MemoryPoolStaticMalloc::get_alloc_ptr(int p_alloc_idx) { - - return 0; -} -const char* MemoryPoolStaticMalloc::get_alloc_description(int p_alloc_idx) { - - - return ""; -} -size_t MemoryPoolStaticMalloc::get_alloc_size(int p_alloc_idx) { - - return 0; -} - -void MemoryPoolStaticMalloc::dump_mem_to_file(const char* p_file) { - -#ifdef DEBUG_MEMORY_ENABLED - - ERR_FAIL_COND( !ringlist ); /** WTF BUG !? */ - RingPtr *p = ringlist; - FILE *f = fopen(p_file,"wb"); - - do { - fprintf(f,"%p-%i-%s\n", p+1, (int)p->size, (p->descr?p->descr:"") ); - p=p->next; - } while (p!=ringlist); - - fclose(f); -#endif - -} - -MemoryPoolStaticMalloc::MemoryPoolStaticMalloc() { - -#ifdef DEBUG_MEMORY_ENABLED - total_mem=0; - total_pointers=0; - ringlist=0; - max_mem=0; - max_pointers=0; - - -#endif - - mutex=NULL; -#ifndef NO_THREADS - - mutex=Mutex::create(); // at this point, this should work -#endif - -} - - -MemoryPoolStaticMalloc::~MemoryPoolStaticMalloc() { - - Mutex *old_mutex=mutex; - mutex=NULL; - if (old_mutex) - memdelete(old_mutex); - -#ifdef DEBUG_MEMORY_ENABLED - - if (OS::get_singleton()->is_stdout_verbose()) { - if (total_mem > 0 ) { - printf("**ERROR: STATIC ALLOC: ** MEMORY LEAKS DETECTED **\n"); - printf("**ERROR: STATIC ALLOC: %i bytes of memory in use at exit.\n",(int)total_mem); - - if (1){ - printf("**ERROR: STATIC ALLOC: Following is the list of leaked allocations: \n"); - - ERR_FAIL_COND( !ringlist ); /** WTF BUG !? */ - RingPtr *p = ringlist; - - do { - printf("\t%p - %i bytes - %s\n", (RingPtr*)(p+1), (int)p->size, (p->descr?p->descr:"") ); - p=p->next; - } while (p!=ringlist); - - printf("**ERROR: STATIC ALLOC: End of Report.\n"); - }; - - printf("mem - max %i, pointers %i, leaks %i.\n",(int)max_mem,max_pointers,(int)total_mem); - } else { - - printf("INFO: mem - max %i, pointers %i, no leaks.\n",(int)max_mem,max_pointers); - } - } - -#endif -} diff --git a/drivers/unix/memory_pool_static_malloc.h b/drivers/unix/memory_pool_static_malloc.h index 78ad82ee22..e69de29bb2 100644 --- a/drivers/unix/memory_pool_static_malloc.h +++ b/drivers/unix/memory_pool_static_malloc.h @@ -1,82 +0,0 @@ -/*************************************************************************/ -/* memory_pool_static_malloc.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef MEMORY_POOL_STATIC_MALLOC_H -#define MEMORY_POOL_STATIC_MALLOC_H - -#include "os/memory_pool_static.h" -#include "os/mutex.h" -/** - @author Juan Linietsky <red@lunatea> -*/ -class MemoryPoolStaticMalloc : public MemoryPoolStatic { - - struct RingPtr { - - size_t size; - const char *descr; /* description of memory */ - RingPtr *next; - RingPtr *prev; - }; - - RingPtr *ringlist; - size_t total_mem; - int total_pointers; - - size_t max_mem; - int max_pointers; - - Mutex *mutex; - - void* _alloc(size_t p_bytes,const char *p_description=""); ///< Pointer in p_description shold be to a const char const like "hello" - void* _realloc(void *p_memory,size_t p_bytes); ///< Pointer in - void _free(void *p_ptr); ///< Pointer in p_description shold be to a const char const - -public: - - virtual void* alloc(size_t p_bytes,const char *p_description=""); ///< Pointer in p_description shold be to a const char const like "hello" - virtual void free(void *p_ptr); ///< Pointer in p_description shold be to a const char const - virtual void* realloc(void *p_memory,size_t p_bytes); ///< Pointer in - virtual size_t get_available_mem() const; - virtual size_t get_total_usage(); - virtual size_t get_max_usage(); - - /* Most likely available only if memory debugger was compiled in */ - virtual int get_alloc_count(); - virtual void * get_alloc_ptr(int p_alloc_idx); - virtual const char* get_alloc_description(int p_alloc_idx); - virtual size_t get_alloc_size(int p_alloc_idx); - - void dump_mem_to_file(const char* p_file); - - MemoryPoolStaticMalloc(); - ~MemoryPoolStaticMalloc(); - -}; - -#endif diff --git a/drivers/unix/mutex_posix.cpp b/drivers/unix/mutex_posix.cpp index fb4fa4a891..c9b5bdce75 100644 --- a/drivers/unix/mutex_posix.cpp +++ b/drivers/unix/mutex_posix.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/drivers/unix/mutex_posix.h b/drivers/unix/mutex_posix.h index a1993be221..a71400924a 100644 --- a/drivers/unix/mutex_posix.h +++ b/drivers/unix/mutex_posix.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 4fa46b16cd..283cff0486 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,11 +30,11 @@ #ifdef UNIX_ENABLED -#include "memory_pool_static_malloc.h" -#include "os/memory_pool_dynamic_static.h" + #include "thread_posix.h" #include "semaphore_posix.h" #include "mutex_posix.h" +#include "rw_lock_posix.h" #include "core/os/thread_dummy.h" //#include "core/io/file_access_buffered_fa.h" @@ -88,6 +88,10 @@ void OS_Unix::print_error(const char* p_function,const char* p_file,int p_line,c print("\E[1;35mSCRIPT ERROR: %s: \E[0m\E[1m%s\n",p_function,err_details); print("\E[0;35m At: %s:%i.\E[0m\n",p_file,p_line); break; + case ERR_SHADER: + print("\E[1;36mSHADER ERROR: %s: \E[0m\E[1m%s\n",p_function,err_details); + print("\E[0;36m At: %s:%i.\E[0m\n",p_file,p_line); + break; } } @@ -112,8 +116,6 @@ int OS_Unix::unix_initialize_audio(int p_audio_driver) { return 0; } -static MemoryPoolStaticMalloc *mempool_static=NULL; -static MemoryPoolDynamicStatic *mempool_dynamic=NULL; void OS_Unix::initialize_core() { @@ -126,6 +128,7 @@ void OS_Unix::initialize_core() { ThreadPosix::make_default(); SemaphorePosix::make_default(); MutexPosix::make_default(); + RWLockPosix::make_default(); #endif FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_RESOURCES); FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_USERDATA); @@ -141,8 +144,6 @@ void OS_Unix::initialize_core() { PacketPeerUDPPosix::make_default(); IP_Unix::make_default(); #endif - mempool_static = new MemoryPoolStaticMalloc; - mempool_dynamic = memnew( MemoryPoolDynamicStatic ); ticks_start=0; ticks_start=get_ticks_usec(); @@ -151,9 +152,6 @@ void OS_Unix::initialize_core() { void OS_Unix::finalize_core() { - if (mempool_dynamic) - memdelete( mempool_dynamic ); - delete mempool_static; } @@ -357,7 +355,6 @@ Error OS_Unix::execute(const String& p_path, const List<String>& p_arguments,boo pid_t pid = fork(); ERR_FAIL_COND_V(pid<0,ERR_CANT_FORK); - //print("execute: %s\n",p_path.utf8().get_data()); if (pid==0) { @@ -391,11 +388,9 @@ Error OS_Unix::execute(const String& p_path, const List<String>& p_arguments,boo if (p_blocking) { int status; - pid_t rpid = waitpid(pid,&status,0); + waitpid(pid,&status,0); if (r_exitcode) *r_exitcode=WEXITSTATUS(status); - - print("returned: %i, waiting for: %i\n",rpid,pid); } else { if (r_child_id) @@ -464,14 +459,14 @@ int OS_Unix::get_processor_count() const { String OS_Unix::get_data_dir() const { - String an = Globals::get_singleton()->get("application/name"); + String an = get_safe_application_name(); if (an!="") { if (has_environment("HOME")) { - bool use_godot = Globals::get_singleton()->get("application/use_shared_user_dir"); + bool use_godot = GlobalConfig::get_singleton()->get("application/use_shared_user_dir"); if (use_godot) return get_environment("HOME")+"/.godot/app_userdata/"+an; else @@ -479,7 +474,7 @@ String OS_Unix::get_data_dir() const { } } - return Globals::get_singleton()->get_resource_path(); + return GlobalConfig::get_singleton()->get_resource_path(); } @@ -498,7 +493,6 @@ String OS_Unix::get_executable_path() const { char buf[256]; memset(buf,0,256); readlink("/proc/self/exe", buf, sizeof(buf)); - //print_line("Exec path is:"+String(buf)); String b; b.parse_utf8(buf); if (b=="") { @@ -526,9 +520,6 @@ String OS_Unix::get_executable_path() const { delete[] resolved_path; return path; -#elif defined(EMSCRIPTEN) - // We return nothing - return String(); #else ERR_PRINT("Warning, don't know how to obtain executable path on this OS! Please override this function properly."); return OS::get_executable_path(); diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h index a889bba0ff..b28adc2ee0 100644 --- a/drivers/unix/os_unix.h +++ b/drivers/unix/os_unix.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index 2111619080..6adb3eea70 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -1,3 +1,31 @@ +/*************************************************************************/ +/* packet_peer_udp_posix.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ #include "packet_peer_udp_posix.h" #ifdef UNIX_ENABLED @@ -26,6 +54,7 @@ #include <arpa/inet.h> #endif +#include "drivers/unix/socket_helpers.h" int PacketPeerUDPPosix::get_available_packet_count() const { @@ -45,7 +74,17 @@ Error PacketPeerUDPPosix::get_packet(const uint8_t **r_buffer,int &r_buffer_size return ERR_UNAVAILABLE; uint32_t size; - rb.read((uint8_t*)&packet_ip.host,4,true); + uint8_t type; + rb.read(&type, 1, true); + if (type == IP::TYPE_IPV4) { + uint8_t ip[4]; + rb.read(ip,4,true); + packet_ip.set_ipv4(ip); + } else { + uint8_t ipv6[16]; + rb.read(ipv6,16,true); + packet_ip.set_ipv6(ipv6); + }; rb.read((uint8_t*)&packet_port,4,true); rb.read((uint8_t*)&size,4,true); rb.read(packet_buffer,size,true); @@ -57,17 +96,17 @@ Error PacketPeerUDPPosix::get_packet(const uint8_t **r_buffer,int &r_buffer_size } Error PacketPeerUDPPosix::put_packet(const uint8_t *p_buffer,int p_buffer_size){ + ERR_FAIL_COND_V(peer_addr == IP_Address(), ERR_UNCONFIGURED); + int sock = _get_socket(); ERR_FAIL_COND_V( sock == -1, FAILED ); - struct sockaddr_in addr; - addr.sin_family = AF_INET; - addr.sin_port = htons(peer_port); - addr.sin_addr = *((struct in_addr*)&peer_addr.host); + struct sockaddr_storage addr; + size_t addr_size = _set_sockaddr(&addr, peer_addr, peer_port, ip_type); errno = 0; int err; - while ( (err = sendto(sock, p_buffer, p_buffer_size, 0, (struct sockaddr*)&addr, sizeof(addr))) != p_buffer_size) { + while ( (err = sendto(sock, p_buffer, p_buffer_size, 0, (struct sockaddr*)&addr, addr_size)) != p_buffer_size) { if (errno != EAGAIN) { return FAILED; @@ -82,21 +121,21 @@ int PacketPeerUDPPosix::get_max_packet_size() const{ return 512; // uhm maybe not } -Error PacketPeerUDPPosix::listen(int p_port, int p_recv_buffer_size){ +Error PacketPeerUDPPosix::listen(int p_port, int p_recv_buffer_size) { close(); int sock = _get_socket(); + if (sock == -1 ) return ERR_CANT_CREATE; - sockaddr_in addr = {0}; - addr.sin_family = AF_INET; - addr.sin_port = htons(p_port); - addr.sin_addr.s_addr = INADDR_ANY; - if (bind(sock, (struct sockaddr*)&addr, sizeof(sockaddr_in)) == -1 ) { + + sockaddr_storage addr = {0}; + size_t addr_size = _set_listen_sockaddr(&addr, p_port, ip_type, NULL); + + if (bind(sock, (struct sockaddr*)&addr, addr_size) == -1 ) { close(); return ERR_UNAVAILABLE; } - printf("UDP Connection listening on port %i bufsize %i \n", p_port,p_recv_buffer_size); rb.resize(nearest_shift(p_recv_buffer_size)); return OK; } @@ -118,16 +157,41 @@ Error PacketPeerUDPPosix::wait() { Error PacketPeerUDPPosix::_poll(bool p_wait) { - struct sockaddr_in from = {0}; - socklen_t len = sizeof(struct sockaddr_in); + struct sockaddr_storage from = {0}; + socklen_t len = sizeof(struct sockaddr_storage); int ret; while ( (ret = recvfrom(sockfd, recv_buffer, MIN((int)sizeof(recv_buffer),MAX(rb.space_left()-12, 0)), p_wait?0:MSG_DONTWAIT, (struct sockaddr*)&from, &len)) > 0) { - rb.write((uint8_t*)&from.sin_addr, 4); - uint32_t port = ntohs(from.sin_port); + + uint32_t port = 0; + + if (from.ss_family == AF_INET) { + uint8_t type = (uint8_t)IP::TYPE_IPV4; + rb.write(&type, 1); + struct sockaddr_in* sin_from = (struct sockaddr_in*)&from; + rb.write((uint8_t*)&sin_from->sin_addr, 4); + port = ntohs(sin_from->sin_port); + + } else if (from.ss_family == AF_INET6) { + + uint8_t type = (uint8_t)IP::TYPE_IPV6; + rb.write(&type, 1); + + struct sockaddr_in6* s6_from = (struct sockaddr_in6*)&from; + rb.write((uint8_t*)&s6_from->sin6_addr, 16); + + port = ntohs(s6_from->sin6_port); + + } else { + // WARN_PRINT("Ignoring packet with unknown address family"); + uint8_t type = (uint8_t)IP::TYPE_NONE; + rb.write(&type, 1); + }; + rb.write((uint8_t*)&port, 4); rb.write((uint8_t*)&ret, 4); rb.write(recv_buffer, ret); - len = sizeof(struct sockaddr_in); + + len = sizeof(struct sockaddr_storage); ++queue_count; }; @@ -160,15 +224,13 @@ int PacketPeerUDPPosix::_get_socket() { if (sockfd != -1) return sockfd; - sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - ERR_FAIL_COND_V( sockfd == -1, -1 ); - //fcntl(sockfd, F_SETFL, O_NONBLOCK); + sockfd = _socket_create(ip_type, SOCK_DGRAM, IPPROTO_UDP); return sockfd; } -void PacketPeerUDPPosix::set_send_address(const IP_Address& p_address,int p_port) { +void PacketPeerUDPPosix::set_dest_address(const IP_Address& p_address,int p_port) { peer_addr=p_address; peer_port=p_port; @@ -191,6 +253,7 @@ PacketPeerUDPPosix::PacketPeerUDPPosix() { packet_port=0; queue_count=0; peer_port=0; + ip_type = IP::TYPE_ANY; } PacketPeerUDPPosix::~PacketPeerUDPPosix() { diff --git a/drivers/unix/packet_peer_udp_posix.h b/drivers/unix/packet_peer_udp_posix.h index b14568eb5f..ead7174a9d 100644 --- a/drivers/unix/packet_peer_udp_posix.h +++ b/drivers/unix/packet_peer_udp_posix.h @@ -1,3 +1,31 @@ +/*************************************************************************/ +/* packet_peer_udp_posix.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ #ifndef PACKET_PEER_UDP_POSIX_H #define PACKET_PEER_UDP_POSIX_H @@ -16,8 +44,8 @@ class PacketPeerUDPPosix : public PacketPeerUDP { mutable RingBuffer<uint8_t> rb; uint8_t recv_buffer[PACKET_BUFFER_SIZE]; mutable uint8_t packet_buffer[PACKET_BUFFER_SIZE]; - IP_Address packet_ip; - int packet_port; + mutable IP_Address packet_ip; + mutable int packet_port; mutable int queue_count; int sockfd; @@ -37,7 +65,7 @@ public: virtual int get_max_packet_size() const; - virtual Error listen(int p_port,int p_recv_buffer_size=65536); + virtual Error listen(int p_port, int p_recv_buffer_size=65536); virtual void close(); virtual Error wait(); virtual bool is_listening() const; @@ -45,7 +73,7 @@ public: virtual IP_Address get_packet_address() const; virtual int get_packet_port() const; - virtual void set_send_address(const IP_Address& p_address,int p_port); + virtual void set_dest_address(const IP_Address& p_address,int p_port); static void make_default(); diff --git a/drivers/unix/rw_lock_posix.cpp b/drivers/unix/rw_lock_posix.cpp new file mode 100644 index 0000000000..b51e5fd420 --- /dev/null +++ b/drivers/unix/rw_lock_posix.cpp @@ -0,0 +1,77 @@ + +#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED) + +#include "os/memory.h" +#include "rw_lock_posix.h" +#include "error_macros.h" +#include <stdio.h> + +void RWLockPosix::read_lock() { + + int err =pthread_rwlock_rdlock(&rwlock); + if (err!=0) { + perror("wtf: "); + } + ERR_FAIL_COND(err!=0); +} + +void RWLockPosix::read_unlock() { + + pthread_rwlock_unlock(&rwlock); +} + +Error RWLockPosix::read_try_lock() { + + if (pthread_rwlock_tryrdlock(&rwlock)!=0) { + return ERR_BUSY; + } else { + return OK; + } + +} + +void RWLockPosix::write_lock() { + + int err = pthread_rwlock_wrlock(&rwlock); + ERR_FAIL_COND(err!=0); +} + +void RWLockPosix::write_unlock() { + + pthread_rwlock_unlock(&rwlock); +} + +Error RWLockPosix::write_try_lock() { + if (pthread_rwlock_trywrlock(&rwlock)!=0) { + return ERR_BUSY; + } else { + return OK; + } +} + + +RWLock *RWLockPosix::create_func_posix() { + + return memnew( RWLockPosix ); +} + +void RWLockPosix::make_default() { + + create_func=create_func_posix; +} + + +RWLockPosix::RWLockPosix() { + + //rwlock=PTHREAD_RWLOCK_INITIALIZER; fails on OSX + pthread_rwlock_init(&rwlock,NULL); +} + + +RWLockPosix::~RWLockPosix() { + + pthread_rwlock_destroy(&rwlock); + +} + +#endif diff --git a/drivers/unix/rw_lock_posix.h b/drivers/unix/rw_lock_posix.h new file mode 100644 index 0000000000..bcc102f6a6 --- /dev/null +++ b/drivers/unix/rw_lock_posix.h @@ -0,0 +1,37 @@ +#ifndef RWLOCKPOSIX_H +#define RWLOCKPOSIX_H + +#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED) + +#include <pthread.h> +#include "os/rw_lock.h" + +class RWLockPosix : public RWLock { + + + pthread_rwlock_t rwlock; + + static RWLock *create_func_posix(); + +public: + + virtual void read_lock(); + virtual void read_unlock(); + virtual Error read_try_lock(); + + virtual void write_lock(); + virtual void write_unlock(); + virtual Error write_try_lock(); + + static void make_default(); + + RWLockPosix(); + + ~RWLockPosix(); + +}; + +#endif + + +#endif // RWLOCKPOSIX_H diff --git a/drivers/unix/semaphore_posix.cpp b/drivers/unix/semaphore_posix.cpp index 3ae94ae5d9..83b34a42dd 100644 --- a/drivers/unix/semaphore_posix.cpp +++ b/drivers/unix/semaphore_posix.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/drivers/unix/semaphore_posix.h b/drivers/unix/semaphore_posix.h index 0a3cf36749..96d1ff5c06 100644 --- a/drivers/unix/semaphore_posix.h +++ b/drivers/unix/semaphore_posix.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h new file mode 100644 index 0000000000..6d4f7e7519 --- /dev/null +++ b/drivers/unix/socket_helpers.h @@ -0,0 +1,106 @@ +#ifndef SOCKET_HELPERS_H +#define SOCKET_HELPERS_H + +#include <string.h> + +#if defined(__MINGW32__ ) && (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 4) + // Workaround for mingw-w64 < 4.0 + #ifndef IPV6_V6ONLY + #define IPV6_V6ONLY 27 + #endif +#endif + +// helpers for sockaddr -> IP_Address and back, should work for posix and winsock. All implementations should use this + +static size_t _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p_ip, int p_port, IP::Type p_sock_type = IP::TYPE_ANY) { + + memset(p_addr, 0, sizeof(struct sockaddr_storage)); + + ERR_FAIL_COND_V(p_ip==IP_Address(),0); + + // IPv6 socket + if (p_sock_type == IP::TYPE_IPV6 || p_sock_type == IP::TYPE_ANY) { + + // IPv6 only socket with IPv4 address + ERR_FAIL_COND_V(p_sock_type == IP::TYPE_IPV6 && p_ip.is_ipv4(),0); + + struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr; + addr6->sin6_family = AF_INET6; + addr6->sin6_port = htons(p_port); + copymem(&addr6->sin6_addr.s6_addr, p_ip.get_ipv6(), 16); + return sizeof(sockaddr_in6); + + } else { // IPv4 socket + + // IPv4 socket with IPv6 address + ERR_FAIL_COND_V(!p_ip.is_ipv4(),0); + + uint32_t ipv4 = *((uint32_t *)p_ip.get_ipv4()); + struct sockaddr_in* addr4 = (struct sockaddr_in*)p_addr; + addr4->sin_family = AF_INET; + addr4->sin_port = htons(p_port); // short, network byte order + copymem(&addr4->sin_addr.s_addr, p_ip.get_ipv4(), 16); + return sizeof(sockaddr_in); + }; +}; + +static size_t _set_listen_sockaddr(struct sockaddr_storage* p_addr, int p_port, IP::Type p_sock_type, const List<String> *p_accepted_hosts) { + + memset(p_addr, 0, sizeof(struct sockaddr_storage)); + if (p_sock_type == IP::TYPE_IPV4) { + struct sockaddr_in* addr4 = (struct sockaddr_in*)p_addr; + addr4->sin_family = AF_INET; + addr4->sin_port = htons(p_port); + addr4->sin_addr.s_addr = INADDR_ANY; // TODO: use accepted hosts list + return sizeof(sockaddr_in); + } else { + struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr; + + addr6->sin6_family = AF_INET6; + addr6->sin6_port = htons(p_port); + addr6->sin6_addr = in6addr_any; // TODO: use accepted hosts list + return sizeof(sockaddr_in6); + }; +}; + +static int _socket_create(IP::Type p_type, int type, int protocol) { + + ERR_FAIL_COND_V(p_type > IP::TYPE_ANY || p_type < IP::TYPE_NONE, ERR_INVALID_PARAMETER); + + int family = p_type == IP::TYPE_IPV4 ? AF_INET : AF_INET6; + int sockfd = socket(family, type, protocol); + + ERR_FAIL_COND_V( sockfd == -1, -1 ); + + if(family == AF_INET6) { + // Select IPv4 over IPv6 mapping + int opt = p_type != IP::TYPE_ANY; + if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&opt, sizeof(opt)) != 0) { + WARN_PRINT("Unable to set/unset IPv4 address mapping over IPv6"); + } + } + + return sockfd; +} + + +static void _set_ip_addr_port(IP_Address& r_ip, int& r_port, struct sockaddr_storage* p_addr) { + + 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); + + } 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); + }; +}; + + +#endif diff --git a/drivers/unix/stream_peer_tcp_posix.cpp b/drivers/unix/stream_peer_tcp_posix.cpp index 45a4b934c1..82f3115f4b 100644 --- a/drivers/unix/stream_peer_tcp_posix.cpp +++ b/drivers/unix/stream_peer_tcp_posix.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -61,13 +61,7 @@ #define MSG_NOSIGNAL SO_NOSIGPIPE #endif -static void set_addr_in(struct sockaddr_in& their_addr, const IP_Address& p_host, uint16_t p_port) { - - their_addr.sin_family = AF_INET; // host byte order - their_addr.sin_port = htons(p_port); // short, network byte order - their_addr.sin_addr = *((struct in_addr*)&p_host.host); - memset(&(their_addr.sin_zero), '\0', 8); -}; +#include "drivers/unix/socket_helpers.h" StreamPeerTCP* StreamPeerTCPPosix::_create() { @@ -103,16 +97,22 @@ Error StreamPeerTCPPosix::_poll_connection(bool p_block) const { _block(sockfd, false, true); }; - struct sockaddr_in their_addr; - set_addr_in(their_addr, peer_host, peer_port); - if (::connect(sockfd, (struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == -1) { + struct sockaddr_storage their_addr; + size_t addr_size = _set_sockaddr(&their_addr, peer_host, peer_port, ip_type); + + if (::connect(sockfd, (struct sockaddr *)&their_addr,addr_size) == -1) { if (errno == EISCONN) { status = STATUS_CONNECTED; return OK; }; - return OK; + if (errno == EINPROGRESS || errno == EALREADY) { + return OK; + } + + status = STATUS_ERROR; + return ERR_CONNECTION_ERROR; } else { status = STATUS_CONNECTED; @@ -122,8 +122,9 @@ Error StreamPeerTCPPosix::_poll_connection(bool p_block) const { return OK; }; -void StreamPeerTCPPosix::set_socket(int p_sockfd, IP_Address p_host, int p_port) { +void StreamPeerTCPPosix::set_socket(int p_sockfd, IP_Address p_host, int p_port, IP::Type p_ip_type) { + ip_type = p_ip_type; sockfd = p_sockfd; #ifndef NO_FCNTL fcntl(sockfd, F_SETFL, O_NONBLOCK); @@ -138,13 +139,14 @@ void StreamPeerTCPPosix::set_socket(int p_sockfd, IP_Address p_host, int p_port) peer_port = p_port; }; -Error StreamPeerTCPPosix::connect(const IP_Address& p_host, uint16_t p_port) { +Error StreamPeerTCPPosix::connect_to_host(const IP_Address& p_host, uint16_t p_port) { - ERR_FAIL_COND_V( p_host.host == 0, ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V( p_host == IP_Address(), ERR_INVALID_PARAMETER); - if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + sockfd = _socket_create(ip_type, SOCK_STREAM, IPPROTO_TCP); + if (sockfd == -1) { ERR_PRINT("Socket creation failed!"); - disconnect(); + disconnect_from_host(); //perror("socket"); return FAILED; }; @@ -156,14 +158,14 @@ Error StreamPeerTCPPosix::connect(const IP_Address& p_host, uint16_t p_port) { ioctl(sockfd, FIONBIO, &bval); #endif - struct sockaddr_in their_addr; - set_addr_in(their_addr, p_host, p_port); + struct sockaddr_storage their_addr; + size_t addr_size = _set_sockaddr(&their_addr, p_host, p_port, ip_type); errno = 0; - if (::connect(sockfd, (struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == -1 && errno != EINPROGRESS) { + if (::connect(sockfd, (struct sockaddr *)&their_addr,addr_size) == -1 && errno != EINPROGRESS) { ERR_PRINT("Connection to remote host failed!"); - disconnect(); + disconnect_from_host(); return FAILED; }; @@ -215,7 +217,7 @@ Error StreamPeerTCPPosix::write(const uint8_t* p_data,int p_bytes, int &r_sent, if (errno != EAGAIN) { perror("shit?"); - disconnect(); + disconnect_from_host(); ERR_PRINT("Server disconnected!\n"); return FAILED; }; @@ -241,7 +243,7 @@ Error StreamPeerTCPPosix::write(const uint8_t* p_data,int p_bytes, int &r_sent, Error StreamPeerTCPPosix::read(uint8_t* p_buffer, int p_bytes,int &r_received, bool p_block) { - if (!is_connected()) { + if (!is_connected_to_host()) { return FAILED; }; @@ -272,7 +274,7 @@ Error StreamPeerTCPPosix::read(uint8_t* p_buffer, int p_bytes,int &r_received, b if (errno != EAGAIN) { perror("shit?"); - disconnect(); + disconnect_from_host(); ERR_PRINT("Server disconnected!\n"); return FAILED; }; @@ -306,12 +308,12 @@ Error StreamPeerTCPPosix::read(uint8_t* p_buffer, int p_bytes,int &r_received, b void StreamPeerTCPPosix::set_nodelay(bool p_enabled) { - ERR_FAIL_COND(!is_connected()); + ERR_FAIL_COND(!is_connected_to_host()); int flag=p_enabled?1:0; setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int)); } -bool StreamPeerTCPPosix::is_connected() const { +bool StreamPeerTCPPosix::is_connected_to_host() const { if (status == STATUS_NONE || status == STATUS_ERROR) { @@ -334,7 +336,7 @@ StreamPeerTCP::Status StreamPeerTCPPosix::get_status() const { }; -void StreamPeerTCPPosix::disconnect() { +void StreamPeerTCPPosix::disconnect_from_host() { if (sockfd != -1) close(sockfd); @@ -391,11 +393,12 @@ StreamPeerTCPPosix::StreamPeerTCPPosix() { sockfd = -1; status = STATUS_NONE; peer_port = 0; + ip_type = IP::TYPE_ANY; }; StreamPeerTCPPosix::~StreamPeerTCPPosix() { - disconnect(); + disconnect_from_host(); }; #endif diff --git a/drivers/unix/stream_peer_tcp_posix.h b/drivers/unix/stream_peer_tcp_posix.h index a379efe3ca..e0091d55b7 100644 --- a/drivers/unix/stream_peer_tcp_posix.h +++ b/drivers/unix/stream_peer_tcp_posix.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -59,7 +59,7 @@ protected: public: - virtual Error connect(const IP_Address& p_host, uint16_t p_port); + virtual Error connect_to_host(const IP_Address& p_host, uint16_t p_port); virtual Error put_data(const uint8_t* p_data,int p_bytes); virtual Error put_partial_data(const uint8_t* p_data,int p_bytes, int &r_sent); @@ -69,14 +69,14 @@ public: virtual int get_available_bytes() const; - void set_socket(int p_sockfd, IP_Address p_host, int p_port); + void set_socket(int p_sockfd, IP_Address p_host, int p_port, IP::Type p_ip_type); virtual IP_Address get_connected_host() const; virtual uint16_t get_connected_port() const; - virtual bool is_connected() const; + virtual bool is_connected_to_host() const; virtual Status get_status() const; - virtual void disconnect(); + virtual void disconnect_from_host(); virtual void set_nodelay(bool p_enabled); diff --git a/drivers/unix/tcp_server_posix.cpp b/drivers/unix/tcp_server_posix.cpp index 98451957fd..0178f08b8c 100644 --- a/drivers/unix/tcp_server_posix.cpp +++ b/drivers/unix/tcp_server_posix.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -55,6 +55,9 @@ #include <netinet/in.h> #include <sys/socket.h> #include <assert.h> + +#include "drivers/unix/socket_helpers.h" + TCP_Server* TCPServerPosix::_create() { return memnew(TCPServerPosix); @@ -67,10 +70,11 @@ void TCPServerPosix::make_default() { Error TCPServerPosix::listen(uint16_t p_port,const List<String> *p_accepted_hosts) { - printf("********* listening on port %i\n", p_port); int sockfd; - sockfd = socket(AF_INET, SOCK_STREAM, 0); + sockfd = _socket_create(ip_type, SOCK_STREAM, IPPROTO_TCP); + ERR_FAIL_COND_V(sockfd == -1, FAILED); + #ifndef NO_FCNTL fcntl(sockfd, F_SETFL, O_NONBLOCK); #else @@ -80,17 +84,15 @@ Error TCPServerPosix::listen(uint16_t p_port,const List<String> *p_accepted_host int reuse=1; if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0) { - - printf("REUSEADDR failed!"); + WARN_PRINT("REUSEADDR failed!") } - struct sockaddr_in my_addr; - my_addr.sin_family = AF_INET; // host byte order - my_addr.sin_port = htons(p_port); // short, network byte order - my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP TODO: use p_accepted_hosts - memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero); + struct sockaddr_storage addr; + size_t addr_size = _set_listen_sockaddr(&addr, p_port, ip_type, p_accepted_hosts); - if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof my_addr) != -1) { + // automatically fill with my IP TODO: use p_accepted_hosts + + if (bind(sockfd, (struct sockaddr *)&addr, addr_size) != -1) { if (::listen(sockfd, 1) == -1) { @@ -103,14 +105,11 @@ Error TCPServerPosix::listen(uint16_t p_port,const List<String> *p_accepted_host }; if (listen_sockfd != -1) { - - printf("FAILED\n"); stop(); }; listen_sockfd = sockfd; - printf("OK! %i\n", listen_sockfd); return OK; }; @@ -129,7 +128,6 @@ bool TCPServerPosix::is_connection_available() const { ERR_FAIL_COND_V(ret < 0, FAILED); if (ret && (pfd.revents & POLLIN)) { - printf("has connection!\n"); return true; }; @@ -142,9 +140,9 @@ Ref<StreamPeerTCP> TCPServerPosix::take_connection() { return Ref<StreamPeerTCP>(); }; - struct sockaddr_in their_addr; - socklen_t sin_size = sizeof(their_addr); - int fd = accept(listen_sockfd, (struct sockaddr *)&their_addr, &sin_size); + struct sockaddr_storage their_addr; + socklen_t size = sizeof(their_addr); + int fd = accept(listen_sockfd, (struct sockaddr *)&their_addr, &size); ERR_FAIL_COND_V(fd == -1, Ref<StreamPeerTCP>()); #ifndef NO_FCNTL fcntl(fd, F_SETFL, O_NONBLOCK); @@ -155,8 +153,11 @@ Ref<StreamPeerTCP> TCPServerPosix::take_connection() { Ref<StreamPeerTCPPosix> conn = memnew(StreamPeerTCPPosix); IP_Address ip; - ip.host = (uint32_t)their_addr.sin_addr.s_addr; - conn->set_socket(fd, ip, ntohs(their_addr.sin_port)); + + int port; + _set_ip_addr_port(ip, port, &their_addr); + + conn->set_socket(fd, ip, port, ip_type); return conn; }; @@ -164,7 +165,6 @@ Ref<StreamPeerTCP> TCPServerPosix::take_connection() { void TCPServerPosix::stop() { if (listen_sockfd != -1) { - print_line("CLOSING CONNECTION"); int ret = close(listen_sockfd); ERR_FAIL_COND(ret!=0); }; @@ -176,6 +176,7 @@ void TCPServerPosix::stop() { TCPServerPosix::TCPServerPosix() { listen_sockfd = -1; + ip_type = IP::TYPE_ANY; }; TCPServerPosix::~TCPServerPosix() { diff --git a/drivers/unix/tcp_server_posix.h b/drivers/unix/tcp_server_posix.h index 570bcaab12..6f9fa8cb5b 100644 --- a/drivers/unix/tcp_server_posix.h +++ b/drivers/unix/tcp_server_posix.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/drivers/unix/thread_posix.cpp b/drivers/unix/thread_posix.cpp index 6ace64a923..ecea67c37b 100644 --- a/drivers/unix/thread_posix.cpp +++ b/drivers/unix/thread_posix.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -27,6 +27,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "thread_posix.h" +#include "script_language.h" #if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED) @@ -50,7 +51,13 @@ void *ThreadPosix::thread_callback(void *userdata) { ThreadPosix *t=reinterpret_cast<ThreadPosix*>(userdata); t->id=(ID)pthread_self(); + + ScriptServer::thread_enter(); //scripts may need to attach a stack + t->callback(t->user); + + ScriptServer::thread_exit(); + return NULL; } diff --git a/drivers/unix/thread_posix.h b/drivers/unix/thread_posix.h index 06a17c2ae6..cf360e164a 100644 --- a/drivers/unix/thread_posix.h +++ b/drivers/unix/thread_posix.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ |