aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHanspeter Portner <dev@open-music-kontrollers.ch>2019-12-30 21:02:13 +0100
committerHanspeter Portner <dev@open-music-kontrollers.ch>2019-12-30 21:02:13 +0100
commit4d4595b988ea488e9b55251822f7415b6c8da9bd (patch)
tree7fab3cf31835e6831221dbb614f9bbbd0f29055e
parent1d2997b2d587602aee9769842d34f9f67810a479 (diff)
downloadd2tk-4d4595b988ea488e9b55251822f7415b6c8da9bd.tar.xz
base: fix killing of child pty process.
-rw-r--r--VERSION2
-rw-r--r--d2tk/base.h3
-rw-r--r--example/example.c2
-rw-r--r--src/base.c6
-rw-r--r--src/base_pty.c45
-rw-r--r--test/base.c3
6 files changed, 50 insertions, 11 deletions
diff --git a/VERSION b/VERSION
index 91fca19..b8f9776 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.1.937
+0.1.939
diff --git a/d2tk/base.h b/d2tk/base.h
index 8f46f6c..07b95ca 100644
--- a/d2tk/base.h
+++ b/d2tk/base.h
@@ -353,6 +353,9 @@ D2TK_API bool
d2tk_state_is_over(d2tk_state_t state);
D2TK_API bool
+d2tk_state_is_close(d2tk_state_t state);
+
+D2TK_API bool
d2tk_base_is_hit(d2tk_base_t *base, const d2tk_rect_t *rect);
D2TK_API void
diff --git a/example/example.c b/example/example.c
index 2f63028..fdb2084 100644
--- a/example/example.c
+++ b/example/example.c
@@ -872,7 +872,7 @@ _curses(FILE *err __attribute__((unused)), void *data __attribute__((unused)))
linenoiseFree(line);
}
- _exit(1);
+ _exit(EXIT_SUCCESS);
}
static inline void
diff --git a/src/base.c b/src/base.c
index 75cd8c4..81f546e 100644
--- a/src/base.c
+++ b/src/base.c
@@ -336,6 +336,12 @@ d2tk_state_is_over(d2tk_state_t state)
}
D2TK_API bool
+d2tk_state_is_close(d2tk_state_t state)
+{
+ return (state & D2TK_STATE_CLOSE);
+}
+
+D2TK_API bool
d2tk_base_is_hit(d2tk_base_t *base, const d2tk_rect_t *rect)
{
if( (base->mouse.x < rect->x)
diff --git a/src/base_pty.c b/src/base_pty.c
index 75ba0af..4d25007 100644
--- a/src/base_pty.c
+++ b/src/base_pty.c
@@ -71,8 +71,6 @@ struct _d2tk_atom_body_pty_t {
bool cursor_visible;
int cursor_shape;
- d2tk_base_t *base;
-
cell_t cells [NROWS_MAX][NCOLS_MAX];
};
@@ -125,8 +123,14 @@ _term_read(d2tk_atom_body_pty_t *vpty,
static inline int
_term_done(d2tk_atom_body_pty_t *vpty)
{
+ if(vpty->kid == 0)
+ {
+ return 1;
+ }
+
if(waitpid(vpty->kid, NULL, WNOHANG) == vpty->kid)
{
+ vpty->kid = 0;
return 1;
}
@@ -291,6 +295,7 @@ _term_init(d2tk_atom_body_pty_t *vpty, d2tk_clone_t clone, void *data,
vpty->kid = forkpty(&vpty->fd, NULL, &termios, &winsize);
if(vpty->kid == -1)
{
+ vpty->kid = 0;
return 1;
}
else if(vpty->kid == 0) // child
@@ -370,12 +375,36 @@ _term_deinit(d2tk_atom_body_pty_t *vpty)
return 1;
}
- kill(vpty->kid, SIGINT);
- kill(vpty->kid, SIGTERM);
- kill(vpty->kid, SIGQUIT);
- waitpid(vpty->kid, NULL, WNOHANG); //FIXME should also work without nohang
+ if(vpty->kid != 0)
+ {
+ kill(vpty->kid, SIGTERM);
- vterm_free(vpty->vterm);
+#define RETRIES 100 // over the course of 100 ms
+ for(int i = 0; i < RETRIES; i++)
+ {
+ if(waitpid(vpty->kid, NULL, WNOHANG) == vpty->kid)
+ {
+ vpty->kid = 0;
+ break;
+ }
+
+ usleep(1000000 / RETRIES);
+ }
+#undef RETRIES
+ }
+
+ if(vpty->kid != 0)
+ {
+ fprintf(stderr, "[%s] sending SIGKILL to pid %i\n", __func__, vpty->kid);
+ kill(vpty->kid, SIGKILL);
+ waitpid(vpty->kid, NULL, 0);
+ vpty->kid = 0;
+ }
+
+ if(vpty->vterm)
+ {
+ vterm_free(vpty->vterm);
+ }
memset(vpty, 0x0, sizeof(d2tk_atom_body_pty_t));
@@ -829,8 +858,6 @@ d2tk_base_pty(d2tk_base_t *base, d2tk_id_t id, d2tk_clone_t clone, void *data,
{
fprintf(stderr, "[%s] _term_init failed\n", __func__);
}
-
- vpty->base = base; //FIXME put somewhere else
}
const d2tk_style_t *old_style = d2tk_base_get_style(base);
diff --git a/test/base.c b/test/base.c
index 48026ff..0a50c7f 100644
--- a/test/base.c
+++ b/test/base.c
@@ -1434,6 +1434,9 @@ _test_state()
assert(d2tk_state_is_over(D2TK_STATE_OVER));
assert(!d2tk_state_is_over(D2TK_STATE_NONE));
+
+ assert(d2tk_state_is_close(D2TK_STATE_CLOSE));
+ assert(!d2tk_state_is_close(D2TK_STATE_NONE));
}
static void