2024-02-24 07:47:12 +01:00
|
|
|
// SPDX-FileCopyrightText: 2021-2024 Leroy Hopson <godot-xterm@leroy.nix.nz>
|
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2024-03-02 01:20:33 +01:00
|
|
|
#include <godot_cpp/classes/mutex.hpp>
|
2024-02-24 07:47:12 +01:00
|
|
|
#include <godot_cpp/classes/node.hpp>
|
|
|
|
#include <godot_cpp/classes/os.hpp>
|
2024-03-02 01:20:33 +01:00
|
|
|
#include <godot_cpp/classes/semaphore.hpp>
|
|
|
|
#include <godot_cpp/classes/thread.hpp>
|
2024-02-25 04:30:39 +01:00
|
|
|
#include <uv.h>
|
2024-02-24 07:47:12 +01:00
|
|
|
|
|
|
|
namespace godot
|
|
|
|
{
|
|
|
|
class PTY : public Node
|
|
|
|
{
|
|
|
|
GDCLASS(PTY, Node)
|
|
|
|
|
|
|
|
public:
|
|
|
|
enum Signal {
|
|
|
|
SIGNAL_SIGHUP = 1,
|
|
|
|
SIGNAL_SIGINT = 2,
|
|
|
|
SIGNAL_SIGQUIT = 3,
|
|
|
|
SIGNAL_SIGILL = 4,
|
|
|
|
SIGNAL_SIGTRAP = 5,
|
|
|
|
SIGNAL_SIGABRT = 6,
|
|
|
|
SIGNAL_SIGFPE = 8,
|
|
|
|
SIGNAL_SIGKILL = 9,
|
|
|
|
SIGNAL_SIGSEGV = 11,
|
|
|
|
SIGNAL_SIGPIPE = 13,
|
|
|
|
SIGNAL_SIGALRM = 14,
|
|
|
|
SIGNAL_SIGTERM = 15,
|
|
|
|
};
|
|
|
|
|
2024-02-25 04:30:39 +01:00
|
|
|
enum Status {
|
2024-03-01 10:35:47 +01:00
|
|
|
STATUS_CLOSED,
|
|
|
|
STATUS_OPEN,
|
2024-02-25 04:30:39 +01:00
|
|
|
STATUS_PAUSED,
|
|
|
|
STATUS_ERROR,
|
|
|
|
};
|
|
|
|
|
2024-02-24 07:47:12 +01:00
|
|
|
PTY();
|
|
|
|
|
2024-03-01 10:35:47 +01:00
|
|
|
Status status = STATUS_CLOSED;
|
2024-02-25 04:30:39 +01:00
|
|
|
|
2024-03-28 10:37:42 +01:00
|
|
|
void set_cols(const int num_cols);
|
2024-02-24 07:47:12 +01:00
|
|
|
int get_cols() const;
|
2024-03-28 10:37:42 +01:00
|
|
|
void set_rows(const int num_rows);
|
2024-02-24 07:47:12 +01:00
|
|
|
int get_rows() const;
|
|
|
|
|
|
|
|
Dictionary get_env() const;
|
|
|
|
void set_env(const Dictionary &value);
|
|
|
|
|
|
|
|
bool get_use_os_env() const;
|
|
|
|
void set_use_os_env(const bool value);
|
|
|
|
|
2024-03-02 01:20:33 +01:00
|
|
|
void set_use_threads(bool p_use);
|
|
|
|
bool is_using_threads() const;
|
|
|
|
|
2024-03-03 05:49:49 +01:00
|
|
|
String get_pts_name() const;
|
2024-02-25 04:30:39 +01:00
|
|
|
|
2024-02-24 07:47:12 +01:00
|
|
|
Error fork(const String &file = "", const PackedStringArray &args = PackedStringArray(), const String &cwd = ".", const int cols = 80, const int rows = 24);
|
|
|
|
void kill(const int signum = Signal::SIGNAL_SIGHUP);
|
2024-02-25 04:30:39 +01:00
|
|
|
Error open(const int cols = 80, const int rows = 24);
|
2024-03-28 10:37:42 +01:00
|
|
|
void resize(const int cols, const int rows);
|
|
|
|
void resizev(const Vector2i &size) { resize(size.x, size.y); };
|
2024-02-24 07:47:12 +01:00
|
|
|
void write(const Variant &data) const;
|
|
|
|
|
2024-03-01 08:25:51 +01:00
|
|
|
void _notification(int p_what);
|
2024-02-25 04:30:39 +01:00
|
|
|
|
2024-02-24 07:47:12 +01:00
|
|
|
protected:
|
|
|
|
static void _bind_methods();
|
|
|
|
|
|
|
|
private:
|
|
|
|
int pid = -1;
|
|
|
|
int fd = -1;
|
|
|
|
|
2024-03-28 10:37:42 +01:00
|
|
|
unsigned int cols = 80;
|
|
|
|
unsigned int rows = 24;
|
2024-02-24 07:47:12 +01:00
|
|
|
|
|
|
|
Dictionary env = Dictionary();
|
|
|
|
bool use_os_env = true;
|
|
|
|
|
2024-03-03 05:49:49 +01:00
|
|
|
String pts_name = "";
|
2024-02-25 04:30:39 +01:00
|
|
|
|
2024-02-24 07:47:12 +01:00
|
|
|
String _get_fork_file(const String &file) const;
|
|
|
|
Dictionary _get_fork_env() const;
|
2024-02-25 10:09:04 +01:00
|
|
|
PackedStringArray _parse_env(const Dictionary &env) const;
|
2024-02-24 07:47:12 +01:00
|
|
|
void _on_exit(int exit_code, int exit_signal);
|
2024-02-25 04:30:39 +01:00
|
|
|
void _close();
|
|
|
|
|
2024-03-02 01:20:33 +01:00
|
|
|
Ref<Thread> thread;
|
|
|
|
Ref<Mutex> buffer_write_mutex;
|
|
|
|
Ref<Semaphore> buffer_cleared;
|
|
|
|
PackedByteArray buffer;
|
|
|
|
SafeFlag stop_thread;
|
|
|
|
uv_async_t async_handle;
|
|
|
|
bool use_threads;
|
|
|
|
void _thread_func();
|
|
|
|
|
2024-02-25 04:30:39 +01:00
|
|
|
#if defined(__linux__) || defined(__APPLE__)
|
2024-03-02 12:15:07 +01:00
|
|
|
uv_loop_t loop;
|
2024-02-25 04:30:39 +01:00
|
|
|
uv_pipe_t pipe;
|
|
|
|
Error _pipe_open(const int fd);
|
|
|
|
#endif
|
|
|
|
|
2024-03-02 01:20:33 +01:00
|
|
|
static void _read_cb(uv_stream_t *pipe, ssize_t nread, const uv_buf_t *buf);
|
2024-02-25 04:30:39 +01:00
|
|
|
static Error uv_err_to_godot_err(const int uv_err);
|
2024-02-24 07:47:12 +01:00
|
|
|
};
|
|
|
|
} // namespace godot
|
|
|
|
|
|
|
|
VARIANT_ENUM_CAST(PTY::Signal);
|