summaryrefslogtreecommitdiff
path: root/drivers/unix
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/unix')
-rw-r--r--drivers/unix/dir_access_unix.cpp31
-rw-r--r--drivers/unix/dir_access_unix.h4
-rw-r--r--drivers/unix/file_access_unix.cpp70
-rw-r--r--drivers/unix/file_access_unix.h4
-rw-r--r--drivers/unix/ip_unix.cpp6
-rw-r--r--drivers/unix/net_socket_posix.cpp26
-rw-r--r--drivers/unix/net_socket_posix.h1
-rw-r--r--drivers/unix/os_unix.cpp28
-rw-r--r--drivers/unix/os_unix.h4
-rw-r--r--drivers/unix/semaphore_posix.cpp2
-rw-r--r--drivers/unix/semaphore_posix.h6
-rw-r--r--drivers/unix/thread_posix.h4
12 files changed, 104 insertions, 82 deletions
diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp
index 251bab5783..6817137a94 100644
--- a/drivers/unix/dir_access_unix.cpp
+++ b/drivers/unix/dir_access_unix.cpp
@@ -126,37 +126,32 @@ String DirAccessUnix::get_next() {
if (!dir_stream)
return "";
- dirent *entry;
- entry = readdir(dir_stream);
+ dirent *entry = readdir(dir_stream);
if (entry == NULL) {
-
list_dir_end();
return "";
}
- //typedef struct stat Stat;
- struct stat flags;
-
String fname = fix_unicode_name(entry->d_name);
- String f = current_dir.plus_file(fname);
-
- if (stat(f.utf8().get_data(), &flags) == 0) {
-
- if (S_ISDIR(flags.st_mode)) {
-
- _cisdir = true;
-
+ // Look at d_type to determine if the entry is a directory, unless
+ // its type is unknown (the file system does not support it) or if
+ // the type is a link, in that case we want to resolve the link to
+ // known if it points to a directory. stat() will resolve the link
+ // for us.
+ if (entry->d_type == DT_UNKNOWN || entry->d_type == DT_LNK) {
+ String f = current_dir.plus_file(fname);
+
+ struct stat flags;
+ if (stat(f.utf8().get_data(), &flags) == 0) {
+ _cisdir = S_ISDIR(flags.st_mode);
} else {
-
_cisdir = false;
}
-
} else {
-
- _cisdir = false;
+ _cisdir = (entry->d_type == DT_DIR);
}
_cishidden = (fname != "." && fname != ".." && fname.begins_with("."));
diff --git a/drivers/unix/dir_access_unix.h b/drivers/unix/dir_access_unix.h
index 579cb0e798..88674d2769 100644
--- a/drivers/unix/dir_access_unix.h
+++ b/drivers/unix/dir_access_unix.h
@@ -40,10 +40,6 @@
#include <sys/types.h>
#include <unistd.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class DirAccessUnix : public DirAccess {
DIR *dir_stream;
diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp
index a285b3b65f..e3026f9fd9 100644
--- a/drivers/unix/file_access_unix.cpp
+++ b/drivers/unix/file_access_unix.cpp
@@ -38,6 +38,8 @@
#include <sys/stat.h>
#include <sys/types.h>
+#include <errno.h>
+
#if defined(UNIX_ENABLED)
#include <unistd.h>
#endif
@@ -54,9 +56,15 @@
#define S_ISREG(m) ((m)&S_IFREG)
#endif
+#ifndef NO_FCNTL
+#include <fcntl.h>
+#else
+#include <sys/ioctl.h>
+#endif
+
void FileAccessUnix::check_errors() const {
- ERR_FAIL_COND(!f);
+ ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
if (feof(f)) {
@@ -74,7 +82,7 @@ Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) {
path = fix_path(p_path);
//printf("opening %ls, %i\n", path.c_str(), Memory::get_static_mem_usage());
- ERR_FAIL_COND_V(f, ERR_ALREADY_IN_USE);
+ ERR_FAIL_COND_V_MSG(f, ERR_ALREADY_IN_USE, "File is already in use.");
const char *mode_string;
if (p_mode_flags == READ)
@@ -112,13 +120,33 @@ Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) {
f = fopen(path.utf8().get_data(), mode_string);
if (f == NULL) {
- last_error = ERR_FILE_CANT_OPEN;
- return ERR_FILE_CANT_OPEN;
- } else {
- last_error = OK;
- flags = p_mode_flags;
- return OK;
+ switch (errno) {
+ case ENOENT: {
+ last_error = ERR_FILE_NOT_FOUND;
+ } break;
+ default: {
+ last_error = ERR_FILE_CANT_OPEN;
+ } break;
+ }
+ return last_error;
}
+
+ // Set close on exec to avoid leaking it to subprocesses.
+ int fd = fileno(f);
+
+ if (fd != -1) {
+#if defined(NO_FCNTL)
+ unsigned long par = 0;
+ ioctl(fd, FIOCLEX, &par);
+#else
+ int opts = fcntl(fd, F_GETFD);
+ fcntl(fd, F_SETFD, opts | FD_CLOEXEC);
+#endif
+ }
+
+ last_error = OK;
+ flags = p_mode_flags;
+ return OK;
}
void FileAccessUnix::close() {
@@ -162,7 +190,7 @@ String FileAccessUnix::get_path_absolute() const {
void FileAccessUnix::seek(size_t p_position) {
- ERR_FAIL_COND(!f);
+ ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
last_error = OK;
if (fseek(f, p_position, SEEK_SET))
@@ -171,7 +199,7 @@ void FileAccessUnix::seek(size_t p_position) {
void FileAccessUnix::seek_end(int64_t p_position) {
- ERR_FAIL_COND(!f);
+ ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
if (fseek(f, p_position, SEEK_END))
check_errors();
@@ -179,7 +207,7 @@ void FileAccessUnix::seek_end(int64_t p_position) {
size_t FileAccessUnix::get_position() const {
- ERR_FAIL_COND_V(!f, 0);
+ ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
long pos = ftell(f);
if (pos < 0) {
@@ -191,7 +219,7 @@ size_t FileAccessUnix::get_position() const {
size_t FileAccessUnix::get_len() const {
- ERR_FAIL_COND_V(!f, 0);
+ ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
long pos = ftell(f);
ERR_FAIL_COND_V(pos < 0, 0);
@@ -210,7 +238,7 @@ bool FileAccessUnix::eof_reached() const {
uint8_t FileAccessUnix::get_8() const {
- ERR_FAIL_COND_V(!f, 0);
+ ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
uint8_t b;
if (fread(&b, 1, 1, f) == 0) {
check_errors();
@@ -221,7 +249,7 @@ uint8_t FileAccessUnix::get_8() const {
int FileAccessUnix::get_buffer(uint8_t *p_dst, int p_length) const {
- ERR_FAIL_COND_V(!f, -1);
+ ERR_FAIL_COND_V_MSG(!f, -1, "File must be opened before use.");
int read = fread(p_dst, 1, p_length, f);
check_errors();
return read;
@@ -234,18 +262,20 @@ Error FileAccessUnix::get_error() const {
void FileAccessUnix::flush() {
- ERR_FAIL_COND(!f);
+ ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
fflush(f);
}
void FileAccessUnix::store_8(uint8_t p_dest) {
- ERR_FAIL_COND(!f);
+ ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
ERR_FAIL_COND(fwrite(&p_dest, 1, 1, f) != 1);
}
void FileAccessUnix::store_buffer(const uint8_t *p_src, int p_length) {
- ERR_FAIL_COND(!f);
+
+ 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);
}
@@ -288,8 +318,7 @@ uint64_t FileAccessUnix::_get_modified_time(const String &p_file) {
if (!err) {
return flags.st_mtime;
} else {
- ERR_EXPLAIN("Failed to get modified time for: " + p_file);
- ERR_FAIL_V(0);
+ ERR_FAIL_V_MSG(0, "Failed to get modified time for: " + p_file + ".");
};
}
@@ -302,8 +331,7 @@ uint32_t FileAccessUnix::_get_unix_permissions(const String &p_file) {
if (!err) {
return flags.st_mode & 0x7FF; //only permissions
} else {
- ERR_EXPLAIN("Failed to get unix permissions for: " + p_file);
- ERR_FAIL_V(0);
+ ERR_FAIL_V_MSG(0, "Failed to get unix permissions for: " + p_file + ".");
};
}
diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h
index 2a369048a4..e26591e3e8 100644
--- a/drivers/unix/file_access_unix.h
+++ b/drivers/unix/file_access_unix.h
@@ -38,10 +38,6 @@
#if defined(UNIX_ENABLED) || defined(LIBC_FILEIO_ENABLED)
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
typedef void (*CloseNotificationFunc)(const String &p_file, int p_flags);
class FileAccessUnix : public FileAccess {
diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp
index ce66f07a19..cf47cdc7e8 100644
--- a/drivers/unix/ip_unix.cpp
+++ b/drivers/unix/ip_unix.cpp
@@ -152,7 +152,7 @@ void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) co
Interface_Info info;
info.name = name;
info.name_friendly = hostname->DisplayName->Data();
- info.index = 0;
+ info.index = String::num_uint64(0);
E = r_interfaces->insert(name, info);
ERR_CONTINUE(!E);
}
@@ -184,9 +184,7 @@ void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) co
continue; // will go back and alloc the right size
};
- ERR_EXPLAIN("Call to GetAdaptersAddresses failed with error " + itos(err));
- ERR_FAIL();
- return;
+ ERR_FAIL_MSG("Call to GetAdaptersAddresses failed with error " + itos(err) + ".");
};
IP_ADAPTER_ADDRESSES *adapter = addrs;
diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp
index 6a57a2e562..5f99a40c79 100644
--- a/drivers/unix/net_socket_posix.cpp
+++ b/drivers/unix/net_socket_posix.cpp
@@ -30,6 +30,7 @@
#include "net_socket_posix.h"
+#ifndef UNIX_SOCKET_UNAVAILABLE
#if defined(UNIX_ENABLED)
#include <errno.h>
@@ -69,6 +70,7 @@
#define SOCK_CBUF(x) x
#define SOCK_IOCTL ioctl
#define SOCK_CLOSE ::close
+#define SOCK_CONNECT(p_sock, p_addr, p_addr_len) ::connect(p_sock, p_addr, p_addr_len)
/* Windows */
#elif defined(WINDOWS_ENABLED)
@@ -82,6 +84,9 @@
#define SOCK_CBUF(x) (const char *)(x)
#define SOCK_IOCTL ioctlsocket
#define SOCK_CLOSE closesocket
+// connect is broken on windows under certain conditions, reasons unknown:
+// See https://github.com/godotengine/webrtc-native/issues/6
+#define SOCK_CONNECT(p_sock, p_addr, p_addr_len) ::WSAConnect(p_sock, p_addr, p_addr_len, NULL, NULL, NULL, NULL)
// Workaround missing flag in MinGW
#if defined(__MINGW32__) && !defined(SIO_UDP_NETRESET)
@@ -280,6 +285,21 @@ void NetSocketPosix::_set_socket(SOCKET_TYPE p_sock, IP::Type p_ip_type, bool p_
_sock = p_sock;
_ip_type = p_ip_type;
_is_stream = p_is_stream;
+ // Disable descriptor sharing with subprocesses.
+ _set_close_exec_enabled(true);
+}
+
+void NetSocketPosix::_set_close_exec_enabled(bool p_enabled) {
+#ifndef WINDOWS_ENABLED
+ // Enable close on exec to avoid sharing with subprocesses. Off by default on Windows.
+#if defined(NO_FCNTL)
+ unsigned long par = p_enabled ? 1 : 0;
+ SOCK_IOCTL(_sock, FIOCLEX, &par);
+#else
+ int opts = fcntl(_sock, F_GETFD);
+ fcntl(_sock, F_SETFD, opts | FD_CLOEXEC);
+#endif
+#endif
}
Error NetSocketPosix::open(Type p_sock_type, IP::Type &ip_type) {
@@ -320,6 +340,9 @@ Error NetSocketPosix::open(Type p_sock_type, IP::Type &ip_type) {
_is_stream = p_sock_type == TYPE_TCP;
+ // Disable descriptor sharing with subprocesses.
+ _set_close_exec_enabled(true);
+
#if defined(WINDOWS_ENABLED)
if (!_is_stream) {
// Disable windows feature/bug reporting WSAECONNRESET/WSAENETRESET when
@@ -390,7 +413,7 @@ Error NetSocketPosix::connect_to_host(IP_Address p_host, uint16_t p_port) {
struct sockaddr_storage addr;
size_t addr_size = _set_addr_storage(&addr, p_host, p_port, _ip_type);
- if (::connect(_sock, (struct sockaddr *)&addr, addr_size) != 0) {
+ if (SOCK_CONNECT(_sock, (struct sockaddr *)&addr, addr_size) != 0) {
NetError err = _get_socket_error();
@@ -691,3 +714,4 @@ Error NetSocketPosix::join_multicast_group(const IP_Address &p_multi_address, St
Error NetSocketPosix::leave_multicast_group(const IP_Address &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 40406b241a..e549ea1d6a 100644
--- a/drivers/unix/net_socket_posix.h
+++ b/drivers/unix/net_socket_posix.h
@@ -61,6 +61,7 @@ private:
NetError _get_socket_error();
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_ void _set_close_exec_enabled(bool p_enabled);
protected:
static NetSocket *_create_func();
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index aa61cf5dcc..25dee6aedb 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -72,8 +72,7 @@ static double _clock_scale = 0;
static void _setup_clock() {
mach_timebase_info_data_t info;
kern_return_t ret = mach_timebase_info(&info);
- ERR_EXPLAIN("OS CLOCK IS NOT WORKING!");
- ERR_FAIL_COND(ret != 0);
+ ERR_FAIL_COND_MSG(ret != 0, "OS CLOCK IS NOT WORKING!");
_clock_scale = ((double)info.numer / (double)info.denom) / 1000.0;
_clock_start = mach_absolute_time() * _clock_scale;
}
@@ -85,8 +84,7 @@ static void _setup_clock() {
#endif
static void _setup_clock() {
struct timespec tv_now = { 0, 0 };
- ERR_EXPLAIN("OS CLOCK IS NOT WORKING!");
- ERR_FAIL_COND(clock_gettime(GODOT_CLOCK, &tv_now) != 0);
+ ERR_FAIL_COND_MSG(clock_gettime(GODOT_CLOCK, &tv_now) != 0, "OS CLOCK IS NOT WORKING!");
_clock_start = ((uint64_t)tv_now.tv_nsec / 1000L) + (uint64_t)tv_now.tv_sec * 1000000L;
}
#endif
@@ -128,7 +126,9 @@ void OS_Unix::initialize_core() {
RWLockDummy::make_default();
#else
ThreadPosix::make_default();
+#if !defined(OSX_ENABLED) && !defined(IPHONE_ENABLED)
SemaphorePosix::make_default();
+#endif
MutexPosix::make_default();
RWLockPosix::make_default();
#endif
@@ -189,7 +189,7 @@ uint64_t OS_Unix::get_system_time_secs() const {
uint64_t OS_Unix::get_system_time_msecs() const {
struct timeval tv_now;
gettimeofday(&tv_now, NULL);
- return uint64_t(tv_now.tv_sec * 1000 + tv_now.tv_usec / 1000);
+ return uint64_t(tv_now.tv_sec) * 1000 + uint64_t(tv_now.tv_usec) / 1000;
}
OS::Date OS_Unix::get_date(bool utc) const {
@@ -300,7 +300,7 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo
}
FILE *f = popen(argss.utf8().get_data(), "r");
- ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
+ ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, "Cannot pipe stream from process running with following arguments '" + argss + "'.");
char buf[65535];
@@ -316,7 +316,7 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo
}
int rv = pclose(f);
if (r_exitcode)
- *r_exitcode = rv;
+ *r_exitcode = WEXITSTATUS(rv);
return OK;
}
@@ -420,10 +420,7 @@ Error OS_Unix::open_dynamic_library(const String p_path, void *&p_library_handle
}
p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW);
- if (!p_library_handle) {
- ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + dlerror());
- ERR_FAIL_V(ERR_CANT_OPEN);
- }
+ ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ". Error: " + dlerror());
return OK;
}
@@ -442,12 +439,9 @@ Error OS_Unix::get_dynamic_library_symbol_handle(void *p_library_handle, const S
error = dlerror();
if (error != NULL) {
- if (!p_optional) {
- ERR_EXPLAIN("Can't resolve symbol " + p_name + ". Error: " + error);
- ERR_FAIL_V(ERR_CANT_RESOLVE);
- } else {
- return ERR_CANT_RESOLVE;
- }
+ ERR_FAIL_COND_V_MSG(!p_optional, ERR_CANT_RESOLVE, "Can't resolve symbol " + p_name + ". Error: " + error + ".");
+
+ return ERR_CANT_RESOLVE;
}
return OK;
}
diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h
index 53446a6b6f..a263147e23 100644
--- a/drivers/unix/os_unix.h
+++ b/drivers/unix/os_unix.h
@@ -31,10 +31,6 @@
#ifndef OS_UNIX_H
#define OS_UNIX_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#ifdef UNIX_ENABLED
#include "core/os/os.h"
diff --git a/drivers/unix/semaphore_posix.cpp b/drivers/unix/semaphore_posix.cpp
index 5aa51d77d1..fc2d5b0dfe 100644
--- a/drivers/unix/semaphore_posix.cpp
+++ b/drivers/unix/semaphore_posix.cpp
@@ -30,7 +30,7 @@
#include "semaphore_posix.h"
-#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)
+#if (defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)) && !defined(OSX_ENABLED) && !defined(IPHONE_ENABLED)
#include "core/os/memory.h"
#include <errno.h>
diff --git a/drivers/unix/semaphore_posix.h b/drivers/unix/semaphore_posix.h
index 089f088d33..8aff01fc27 100644
--- a/drivers/unix/semaphore_posix.h
+++ b/drivers/unix/semaphore_posix.h
@@ -33,12 +33,10 @@
#include "core/os/semaphore.h"
-#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)
+#if (defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)) && !defined(OSX_ENABLED) && !defined(IPHONE_ENABLED)
#include <semaphore.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class SemaphorePosix : public Semaphore {
mutable sem_t sem;
diff --git a/drivers/unix/thread_posix.h b/drivers/unix/thread_posix.h
index d6b6267c49..5edacd3a0c 100644
--- a/drivers/unix/thread_posix.h
+++ b/drivers/unix/thread_posix.h
@@ -31,10 +31,6 @@
#ifndef THREAD_POSIX_H
#define THREAD_POSIX_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#if (defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)) && !defined(NO_THREADS)
#include "core/os/thread.h"