aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHanspeter Portner <dev@open-music-kontrollers.ch>2020-04-17 20:49:50 +0200
committerHanspeter Portner <dev@open-music-kontrollers.ch>2020-04-17 20:49:50 +0200
commit3f0576a7c3e87cccfb93998232410350909d77e2 (patch)
treeef1cd879aa17630433e66262b37e53e8e179d18f
parent469bdc323596e457eb49ed28773431dd802d0430 (diff)
parent2c5f16dbea6138b3d0782c9c85bda20f7e000a64 (diff)
downloadd2tk.lv2-3f0576a7c3e87cccfb93998232410350909d77e2.tar.xz
Merge commit '2c5f16dbea6138b3d0782c9c85bda20f7e000a64'
-rw-r--r--subprojects/d2tk/VERSION2
-rw-r--r--subprojects/d2tk/d2tk/config.h.in2
-rw-r--r--subprojects/d2tk/example/example.c2
-rw-r--r--subprojects/d2tk/meson.build20
-rw-r--r--subprojects/d2tk/src/base_pty.c126
5 files changed, 122 insertions, 30 deletions
diff --git a/subprojects/d2tk/VERSION b/subprojects/d2tk/VERSION
index 7b21b02..ae9bae8 100644
--- a/subprojects/d2tk/VERSION
+++ b/subprojects/d2tk/VERSION
@@ -1 +1 @@
-0.1.1061
+0.1.1063
diff --git a/subprojects/d2tk/d2tk/config.h.in b/subprojects/d2tk/d2tk/config.h.in
index 5bf1ed2..c1d746e 100644
--- a/subprojects/d2tk/d2tk/config.h.in
+++ b/subprojects/d2tk/d2tk/config.h.in
@@ -2,3 +2,5 @@
#define D2TK_EVDEV @D2TK_EVDEV@
#define D2TK_INPUT_1_15 @D2TK_INPUT_1_15@
#define D2TK_FONTCONFIG @D2TK_FONTCONFIG@
+#define D2TK_VFORK @D2TK_VFORK@
+#define D2TK_CLONE @D2TK_CLONE@
diff --git a/subprojects/d2tk/example/example.c b/subprojects/d2tk/example/example.c
index 92f3199..ce80f48 100644
--- a/subprojects/d2tk/example/example.c
+++ b/subprojects/d2tk/example/example.c
@@ -62,7 +62,7 @@ typedef enum _bar_t {
BAR_MAX
} bar_t;
-static bar_t bar = BAR_MIX;
+static bar_t bar = BAR_PTY;
static const char *bar_lbl [BAR_MAX] = {
[BAR_MIX] = "Mix of many",
[BAR_SPINNER] = "Spinner",
diff --git a/subprojects/d2tk/meson.build b/subprojects/d2tk/meson.build
index 4fc39c6..e13ad99 100644
--- a/subprojects/d2tk/meson.build
+++ b/subprojects/d2tk/meson.build
@@ -30,14 +30,6 @@ check_for_font = find_program('check_for_font',
native : true,
required : use_fontconfig)
-prefix = get_option('prefix')
-datadir = get_option('datadir')
-bindir = get_option('bindir')
-
-pdatadir = join_paths(prefix, datadir, 'd2tk', '')
-
-add_project_arguments('-DD2TK_DATA_DIR="'+pdatadir+'"', language : 'c')
-
cc = meson.get_compiler('c')
# mandatory dependencies
@@ -181,6 +173,18 @@ else
conf_data.set('D2TK_FONTCONFIG', 0)
endif
+if cc.has_function('vfork')
+ conf_data.set('D2TK_VFORK', 1)
+else
+ conf_data.set('D2TK_VFORK', 0)
+endif
+
+if cc.has_function('clone')
+ conf_data.set('D2TK_CLONE', 1)
+else
+ conf_data.set('D2TK_CLONE', 0)
+endif
+
example_srcs = [
join_paths('example', 'example.c')
]
diff --git a/subprojects/d2tk/src/base_pty.c b/subprojects/d2tk/src/base_pty.c
index 6faac7a..246b206 100644
--- a/subprojects/d2tk/src/base_pty.c
+++ b/subprojects/d2tk/src/base_pty.c
@@ -22,7 +22,10 @@
#include <fcntl.h>
#include <vterm.h>
#include <pty.h>
+#include <utmp.h>
+#include <sched.h>
#include <sys/wait.h>
+#include <sys/mman.h>
#include <poll.h>
#include "base_internal.h"
@@ -127,7 +130,7 @@ _term_read(d2tk_atom_body_pty_t *vpty,
{
if(errno != EAGAIN)
{
- fprintf(stderr, "read failed '%s'\n", strerror(errno));
+ //FIXME fprintf(stderr, "read failed '%s'\n", strerror(errno));
}
break;
}
@@ -245,6 +248,107 @@ static const VTermScreenCallbacks screen_callbacks = {
.resize = _screen_resize
};
+typedef struct _clone_data_t clone_data_t;
+
+struct _clone_data_t {
+ int master;
+ int slave;
+ int stderr_save_fileno;
+ char **argv;
+};
+
+static int
+_clone(void *data)
+{
+ clone_data_t *clone_data = data;
+
+ close(clone_data->master);
+
+ if(login_tty(clone_data->slave) == -1)
+ {
+ _exit(1);
+ }
+
+ fcntl(clone_data->stderr_save_fileno, F_SETFD,
+ fcntl(clone_data->stderr_save_fileno, F_GETFD) | FD_CLOEXEC);
+ FILE *stderr_save = fdopen(clone_data->stderr_save_fileno, "a");
+
+ /* Restore the ISIG signals back to defaults */
+ signal(SIGINT, SIG_DFL);
+ signal(SIGQUIT, SIG_DFL);
+ signal(SIGSTOP, SIG_DFL);
+ signal(SIGCONT, SIG_DFL);
+
+ putenv("TERM=xterm-256color");
+ //putenv("COLORTERM=truecolor");
+
+ execvp(clone_data->argv[0], clone_data->argv);
+ fprintf(stderr_save, "cannot exec(%s) - %s\n", clone_data->argv[0], strerror(errno));
+ _exit(EXIT_FAILURE);
+
+ return 0;
+}
+
+static int
+_forkpty(int *amaster, char *name, const struct termios *termp,
+ const struct winsize *winp, char **argv, int stderr_save_fileno)
+{
+ clone_data_t clone_data = {
+ .master = 0,
+ .slave = 0,
+ .argv = argv,
+ .stderr_save_fileno = stderr_save_fileno
+ };
+
+ if(openpty(&clone_data.master, &clone_data.slave, name, termp, winp) == -1)
+ {
+ return -1;
+ }
+
+#if D2TK_CLONE == 1
+# define STACK_SIZE (1024 * 1024)
+ uint8_t *stack = mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
+ if(stack == MAP_FAILED)
+ {
+ close(clone_data.master);
+ close(clone_data.slave);
+ return -1;
+ }
+
+ uint8_t *stack_top = stack + STACK_SIZE;
+ const int flags = CLONE_FS | CLONE_IO | CLONE_VFORK | CLONE_VM;
+ const int pid = clone(_clone, stack_top, flags, &clone_data);
+# undef STACK_SIZE
+#elif D2TK_VFORK == 1
+ const int pid = vfork();
+#else
+ const int pid = fork();
+#endif
+
+ switch(pid)
+ {
+ case -1:
+ {
+ close(clone_data.master);
+ close(clone_data.slave);
+ } return -1;
+
+#if D2TK_CLONE == 0
+ case 0: //child
+ {
+ // everything is done in _clone
+ } return _clone(&clone_data);
+#endif
+
+ default: // parent
+ {
+ *amaster = clone_data.master;
+ close(clone_data.slave);
+ } return pid;
+ }
+}
+
static int
_term_init(d2tk_atom_body_pty_t *vpty, char **argv,
d2tk_coord_t height, d2tk_coord_t ncols, d2tk_coord_t nrows)
@@ -317,30 +421,12 @@ _term_init(d2tk_atom_body_pty_t *vpty, char **argv,
const int stderr_save_fileno = dup(STDERR_FILENO);
- vpty->kid = forkpty(&vpty->fd, NULL, &termios, &winsize);
+ vpty->kid = _forkpty(&vpty->fd, NULL, &termios, &winsize, argv, stderr_save_fileno);
if(vpty->kid == -1)
{
vpty->kid = 0;
return 1;
}
- else if(vpty->kid == 0) // child
- {
- fcntl(stderr_save_fileno, F_SETFD, fcntl(stderr_save_fileno, F_GETFD) | FD_CLOEXEC);
- FILE *stderr_save = fdopen(stderr_save_fileno, "a");
-
- /* Restore the ISIG signals back to defaults */
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
- signal(SIGSTOP, SIG_DFL);
- signal(SIGCONT, SIG_DFL);
-
- putenv("TERM=xterm-256color");
- //putenv("COLORTERM=truecolor");
-
- execvp(argv[0], argv);
- fprintf(stderr_save, "cannot exec(%s) - %s\n", argv[0], strerror(errno));
- _exit(EXIT_FAILURE);
- }
fcntl(vpty->fd, F_SETFL, fcntl(vpty->fd, F_GETFL) | O_NONBLOCK);
close(stderr_save_fileno);