2023-01-08 10:41:48 +01:00
|
|
|
// SPDX-FileCopyrightText: 2021-2023 Leroy Hopson <godot-xterm@leroy.geek.nz>
|
2022-12-29 10:52:13 +01:00
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
|
2021-07-02 19:27:34 +02:00
|
|
|
#include "libuv_utils.h"
|
2022-12-29 10:52:13 +01:00
|
|
|
#include <godot_cpp/classes/global_constants.hpp>
|
2021-07-02 19:27:34 +02:00
|
|
|
#include <uv.h>
|
|
|
|
|
|
|
|
using namespace godot;
|
|
|
|
|
2022-12-29 10:52:13 +01:00
|
|
|
void LibuvUtils::_bind_methods() {
|
2023-01-08 10:41:48 +01:00
|
|
|
ClassDB::bind_static_method("LibuvUtils", D_METHOD("get_os_environ"),
|
|
|
|
&LibuvUtils::get_os_environ);
|
|
|
|
ClassDB::bind_static_method("LibuvUtils", D_METHOD("get_os_release"),
|
|
|
|
&LibuvUtils::get_os_release);
|
|
|
|
ClassDB::bind_static_method("LibuvUtils", D_METHOD("get_cwd"),
|
|
|
|
&LibuvUtils::get_cwd);
|
|
|
|
|
|
|
|
ClassDB::bind_static_method("LibuvUtils", D_METHOD("kill", "pid", "signum"),
|
|
|
|
&LibuvUtils::kill);
|
2021-07-02 19:27:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LibuvUtils::LibuvUtils() {}
|
|
|
|
LibuvUtils::~LibuvUtils() {}
|
|
|
|
|
|
|
|
Dictionary LibuvUtils::get_os_environ() {
|
|
|
|
Dictionary result;
|
|
|
|
|
|
|
|
uv_env_item_t *env;
|
|
|
|
int count;
|
|
|
|
uv_os_environ(&env, &count);
|
|
|
|
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
|
|
result[String(env[i].name)] = String(env[i].value);
|
|
|
|
}
|
|
|
|
|
|
|
|
uv_os_free_environ(env, count);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
String LibuvUtils::get_os_release() { return "TODO"; }
|
|
|
|
|
|
|
|
String LibuvUtils::get_cwd() {
|
|
|
|
#ifndef PATH_MAX
|
|
|
|
#define PATH_MAX MAX_PATH
|
|
|
|
#endif
|
|
|
|
size_t size = PATH_MAX;
|
|
|
|
char *buffer = (char *)malloc(size * sizeof(char));
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = uv_cwd(buffer, &size);
|
|
|
|
|
|
|
|
if (err == UV_ENOBUFS) {
|
|
|
|
// Buffer was too small. `size` has been set to the required length, so
|
|
|
|
// resize buffer and try again.
|
|
|
|
buffer = (char *)realloc(buffer, size * sizeof(char));
|
|
|
|
err = uv_cwd(buffer, &size);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (err < 0) {
|
|
|
|
UV_ERR_PRINT(err);
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
String result = String(buffer);
|
|
|
|
std::free(buffer);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2022-12-29 10:52:13 +01:00
|
|
|
Error LibuvUtils::kill(int pid, int signum) {
|
2021-07-22 07:17:23 +02:00
|
|
|
RETURN_UV_ERR(uv_kill(pid, signum));
|
|
|
|
}
|
|
|
|
|
2022-12-29 10:52:13 +01:00
|
|
|
Error LibuvUtils::translate_uv_errno(int uv_err) {
|
2021-07-02 19:27:34 +02:00
|
|
|
if (uv_err >= 0)
|
2022-12-29 10:52:13 +01:00
|
|
|
return OK;
|
2021-07-02 19:27:34 +02:00
|
|
|
|
|
|
|
// Rough translation of libuv error to godot error.
|
|
|
|
// Not necessarily accurate.
|
|
|
|
|
|
|
|
switch (uv_err) {
|
|
|
|
case UV_EEXIST: // file already exists
|
2022-12-29 10:52:13 +01:00
|
|
|
return ERR_ALREADY_EXISTS;
|
2021-07-02 19:27:34 +02:00
|
|
|
|
|
|
|
case UV_EADDRINUSE: // address already in use
|
2022-12-29 10:52:13 +01:00
|
|
|
return ERR_ALREADY_IN_USE;
|
2021-07-02 19:27:34 +02:00
|
|
|
|
|
|
|
case UV_EBUSY: // resource busy or locked
|
|
|
|
case UV_ETXTBSY: // text file is busy
|
2022-12-29 10:52:13 +01:00
|
|
|
return ERR_BUSY;
|
2021-07-02 19:27:34 +02:00
|
|
|
|
|
|
|
case UV_ECONNREFUSED: // connection refused
|
2022-12-29 10:52:13 +01:00
|
|
|
return ERR_CANT_CONNECT;
|
2021-07-02 19:27:34 +02:00
|
|
|
|
|
|
|
case UV_ECONNABORTED: // software caused connection abort
|
|
|
|
case UV_ECONNRESET: // connection reset by peer
|
|
|
|
case UV_EISCONN: // socket is already connected
|
|
|
|
case UV_ENOTCONN: // socket is not connected
|
2022-12-29 10:52:13 +01:00
|
|
|
return ERR_CONNECTION_ERROR;
|
2021-07-02 19:27:34 +02:00
|
|
|
|
|
|
|
case UV_ENODEV: // no such device
|
|
|
|
case UV_ENXIO: // no such device or address
|
|
|
|
case UV_ESRCH: // no such process
|
2022-12-29 10:52:13 +01:00
|
|
|
return ERR_DOES_NOT_EXIST;
|
2021-07-02 19:27:34 +02:00
|
|
|
|
|
|
|
case UV_EROFS: // read-only file system
|
2022-12-29 10:52:13 +01:00
|
|
|
return ERR_FILE_CANT_WRITE;
|
2021-07-02 19:27:34 +02:00
|
|
|
|
|
|
|
case UV_EOF: // end of file
|
2022-12-29 10:52:13 +01:00
|
|
|
return ERR_FILE_EOF;
|
2021-07-02 19:27:34 +02:00
|
|
|
|
|
|
|
case UV_ENOENT: // no such file or directory
|
2022-12-29 10:52:13 +01:00
|
|
|
return ERR_FILE_NOT_FOUND;
|
2021-07-02 19:27:34 +02:00
|
|
|
|
2023-01-08 10:41:48 +01:00
|
|
|
case UV_EAI_BADFLAGS: // bad ai_flags value
|
|
|
|
case UV_EAI_BADHINTS: // invalid value for hints
|
|
|
|
case UV_EFAULT: // bad address in system call argument
|
|
|
|
case UV_EFTYPE: // inappropriate file type or format
|
|
|
|
case UV_EINVAL: // invalid argument
|
|
|
|
case UV_ENOTTY: // inappropriate ioctl for device
|
|
|
|
case UV_EPROTOTYPE: // protocol wrong type for socket
|
|
|
|
return ERR_INVALID_PARAMETER; // Parameter passed is invalid
|
2021-07-02 19:27:34 +02:00
|
|
|
|
|
|
|
case UV_ENOSYS: // function not implemented
|
2022-12-29 10:52:13 +01:00
|
|
|
return ERR_METHOD_NOT_FOUND;
|
2021-07-02 19:27:34 +02:00
|
|
|
|
|
|
|
case UV_EAI_MEMORY: // out of memory
|
2022-12-29 10:52:13 +01:00
|
|
|
return ERR_OUT_OF_MEMORY;
|
2021-07-02 19:27:34 +02:00
|
|
|
|
2023-01-08 10:41:48 +01:00
|
|
|
case UV_E2BIG: // argument list too long
|
|
|
|
case UV_EFBIG: // file too large
|
|
|
|
case UV_EMSGSIZE: // message too long
|
|
|
|
case UV_ENAMETOOLONG: // name too long
|
|
|
|
case UV_EOVERFLOW: // value too large for defined data type
|
|
|
|
case UV_ERANGE: // result too large
|
2022-12-29 10:52:13 +01:00
|
|
|
return ERR_PARAMETER_RANGE_ERROR; // Parameter given out of range
|
2021-07-02 19:27:34 +02:00
|
|
|
|
|
|
|
case UV_ETIMEDOUT:
|
2022-12-29 10:52:13 +01:00
|
|
|
return ERR_TIMEOUT; // connection timed out
|
2021-07-02 19:27:34 +02:00
|
|
|
|
|
|
|
case UV_EACCES: // permission denied
|
|
|
|
case UV_EPERM: // operation not permitted
|
|
|
|
case UV_EXDEV: // cross-device link not permitted
|
2022-12-29 10:52:13 +01:00
|
|
|
return ERR_UNAUTHORIZED;
|
2021-07-02 19:27:34 +02:00
|
|
|
|
2023-01-08 10:41:48 +01:00
|
|
|
case UV_EADDRNOTAVAIL: // address not available
|
|
|
|
case UV_EAFNOSUPPORT: // address family not supported
|
|
|
|
case UV_EAGAIN: // resource temporarily unavailable
|
|
|
|
case UV_EAI_ADDRFAMILY: // address family not supported
|
|
|
|
case UV_EAI_FAMILY: // ai_family not supported
|
|
|
|
case UV_EAI_SERVICE: // service not available for socket type
|
|
|
|
case UV_EAI_SOCKTYPE: // socket type not supported
|
|
|
|
case UV_ENOPROTOOPT: // protocol not available
|
|
|
|
case UV_ENOTSUP: // operation not supported on socket
|
|
|
|
case UV_EPROTONOSUPPORT: // protocol not supported
|
|
|
|
case UV_ESOCKTNOSUPPORT: // socket type not supported
|
|
|
|
return ERR_UNAVAILABLE; // What is requested is
|
|
|
|
// unsupported/unavailable
|
2021-07-02 19:27:34 +02:00
|
|
|
|
|
|
|
case UV_EAI_NODATA: // no address
|
|
|
|
case UV_EDESTADDRREQ: // destination address required
|
2022-12-29 10:52:13 +01:00
|
|
|
return ERR_UNCONFIGURED;
|
2021-07-02 19:27:34 +02:00
|
|
|
|
|
|
|
case UV_EAI_AGAIN: // temporary failure
|
|
|
|
case UV_EAI_CANCELED: // request canceled
|
|
|
|
case UV_EAI_FAIL: // permanent failure
|
|
|
|
case UV_EAI_NONAME: // unknown node or service
|
|
|
|
case UV_EAI_OVERFLOW: // argument buffer overflow
|
|
|
|
case UV_EAI_PROTOCOL: // resolved protocol is unknown
|
|
|
|
case UV_EALREADY: // connection already in progress
|
|
|
|
case UV_EBADF: // bad file descriptor
|
|
|
|
case UV_ECANCELED: // operation canceled
|
|
|
|
case UV_ECHARSET: // invalid Unicode character
|
|
|
|
case UV_EHOSTUNREACH: // host is unreachable
|
|
|
|
case UV_EIO: // i/o error
|
|
|
|
case UV_EILSEQ: // illegal byte sequence
|
|
|
|
case UV_EISDIR: // illegal operation on a directory
|
|
|
|
case UV_ELOOP: // too many symbolic links encountered
|
|
|
|
case UV_EMFILE: // too many open files
|
|
|
|
case UV_ENETDOWN: // network is down
|
|
|
|
case UV_ENETUNREACH: // network is unreachable
|
|
|
|
case UV_ENFILE: // file table overflow
|
|
|
|
case UV_ENOBUFS: // no buffer space available
|
|
|
|
case UV_ENOMEM: // not enough memory
|
|
|
|
case UV_ESHUTDOWN: // cannot send after transport endpoint shutdown
|
|
|
|
case UV_EINTR: // interrupted system call
|
|
|
|
case UV_EMLINK: // too many links
|
|
|
|
case UV_ENONET: // machine is not on the network
|
|
|
|
case UV_ENOSPC: // no space left on device
|
|
|
|
case UV_ENOTDIR: // not a directory
|
|
|
|
case UV_ENOTEMPTY: // directory not empty
|
|
|
|
case UV_ENOTSOCK: // socket operation on non-socket
|
|
|
|
case UV_EPIPE: // broken pipe
|
|
|
|
case UV_EPROTO: // protocol error
|
|
|
|
case UV_ESPIPE: // invalid seek
|
|
|
|
case UV_UNKNOWN: // unknown error
|
|
|
|
default:
|
2023-01-08 10:41:48 +01:00
|
|
|
return FAILED; // Generic fail error
|
2021-07-02 19:27:34 +02:00
|
|
|
}
|
2022-12-29 10:52:13 +01:00
|
|
|
}
|