diff options
author | Nicholas Marriott <nicholas.marriott@gmail.com> | 2009-02-08 16:11:26 +0000 |
---|---|---|
committer | Nicholas Marriott <nicholas.marriott@gmail.com> | 2009-02-08 16:11:26 +0000 |
commit | 62d2ab3e687bfc7e0a02adedee30314b8ef1b08b (patch) | |
tree | fe5a18bde27c761f87eb287c6c5cd4b4e9c71440 | |
parent | 85fd2147af097184e596e5bbbb521bd1f3c0a0f1 (diff) |
Continue process if suspended.
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | client.c | 7 | ||||
-rw-r--r-- | server.c | 48 | ||||
-rw-r--r-- | tmux.c | 6 | ||||
-rw-r--r-- | tmux.h | 6 | ||||
-rw-r--r-- | window.c | 6 |
6 files changed, 62 insertions, 13 deletions
@@ -86,6 +86,4 @@ - 88 colour support; new grid cell flag, and 256<->88 88<->16 translation tables - some fix for SF feature request 2527847 - now remain-by-default has gone cannot control it per-session -- if the child is suspended in window with eg ^Z it should be restarted, or - ^Z should be ignored - clear window title on exit @@ -1,4 +1,4 @@ -/* $Id: client.c,v 1.42 2009-01-21 22:47:31 nicm Exp $ */ +/* $Id: client.c,v 1.43 2009-02-08 16:11:26 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -21,6 +21,7 @@ #include <sys/socket.h> #include <sys/stat.h> #include <sys/un.h> +#include <sys/wait.h> #include <errno.h> #include <fcntl.h> @@ -142,6 +143,10 @@ client_main(struct client_ctx *cctx) error = NULL; xtimeout = INFTIM; while (!sigterm) { + if (sigchld) { + waitpid(WAIT_ANY, NULL, WNOHANG); + sigchld = 0; + } if (sigwinch) client_handle_winch(cctx); if (sigcont) { @@ -1,4 +1,4 @@ -/* $Id: server.c,v 1.116 2009-01-29 20:13:12 nicm Exp $ */ +/* $Id: server.c,v 1.117 2009-02-08 16:11:26 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -21,6 +21,7 @@ #include <sys/socket.h> #include <sys/stat.h> #include <sys/un.h> +#include <sys/wait.h> #include <errno.h> #include <fcntl.h> @@ -44,6 +45,7 @@ struct clients clients; int server_main(const char *, int); void server_shutdown(void); +void server_child_signal(void); void server_fill_windows(struct pollfd **); void server_handle_windows(struct pollfd **); void server_fill_clients(struct pollfd **); @@ -230,6 +232,12 @@ server_main(const char *srv_path, int srv_fd) if (sigterm) server_shutdown(); + /* Handle child exit. */ + if (sigchld) { + server_child_signal(); + sigchld = 0; + } + /* Initialise pollfd array. */ nfds = 1; for (i = 0; i < ARRAY_LENGTH(&windows); i++) { @@ -358,6 +366,44 @@ server_shutdown(void) server_write_client(c, MSG_SHUTDOWN, NULL, 0); } } + +/* Handle SIGCHLD. */ +void +server_child_signal(void) +{ + struct window *w; + struct window_pane *wp; + int status; + pid_t pid; + u_int i; + + for (;;) { + switch (pid = waitpid(WAIT_ANY, &status, WNOHANG|WUNTRACED)) { + case -1: + if (errno == ECHILD) + return; + fatal("waitpid"); + case 0: + return; + } + if (!WIFSTOPPED(status)) + continue; + if (WSTOPSIG(status) == SIGTTIN || WSTOPSIG(status) == SIGTTOU) + continue; + + for (i = 0; i < ARRAY_LENGTH(&windows); i++) { + w = ARRAY_ITEM(&windows, i); + if (w == NULL) + continue; + TAILQ_FOREACH(wp, &w->panes, entry) { + if (wp->pid == pid) { + if (killpg(pid, SIGCONT) != 0) + kill(pid, SIGCONT); + } + } + } + } +} /* Fill window pollfds. */ void @@ -1,4 +1,4 @@ -/* $Id: tmux.c,v 1.104 2009-01-30 00:24:49 nicm Exp $ */ +/* $Id: tmux.c,v 1.105 2009-02-08 16:11:26 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -17,7 +17,6 @@ */ #include <sys/types.h> -#include <sys/wait.h> #include <errno.h> #include <pwd.h> @@ -46,6 +45,7 @@ const char *_malloc_options = "AJX"; volatile sig_atomic_t sigwinch; volatile sig_atomic_t sigterm; volatile sig_atomic_t sigcont; +volatile sig_atomic_t sigchld; char *cfg_file; struct options global_options; @@ -103,7 +103,7 @@ sighandler(int sig) sigterm = 1; break; case SIGCHLD: - waitpid(WAIT_ANY, NULL, WNOHANG); + sigchld = 1; break; case SIGCONT: sigcont = 1; @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.259 2009-02-03 17:21:19 tcunha Exp $ */ +/* $Id: tmux.h,v 1.260 2009-02-08 16:11:26 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -585,10 +585,12 @@ struct window_pane { int flags; #define PANE_HIDDEN 0x1 +#define PANE_RESTART 0x2 char *cmd; char *cwd; + pid_t pid; int fd; char tty[TTY_NAME_MAX]; struct buffer *in; @@ -610,7 +612,6 @@ TAILQ_HEAD(window_panes, window_pane); struct window { char *name; struct timeval name_timer; - pid_t pgrp; struct window_pane *active; struct window_panes panes; @@ -974,6 +975,7 @@ char *fgetln(FILE *, size_t *); extern volatile sig_atomic_t sigwinch; extern volatile sig_atomic_t sigterm; extern volatile sig_atomic_t sigcont; +extern volatile sig_atomic_t sigchld; extern struct options global_options; extern struct options global_window_options; extern char *cfg_file; @@ -1,4 +1,4 @@ -/* $Id: window.c,v 1.64 2009-01-28 19:52:21 nicm Exp $ */ +/* $Id: window.c,v 1.65 2009-02-08 16:11:26 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -213,7 +213,6 @@ window_create(const char *name, const char *cmd, const char *cwd, TAILQ_INIT(&w->panes); w->active = NULL; - w->pgrp = -1; w->sx = sx; w->sy = sy; @@ -562,14 +561,13 @@ window_pane_spawn(struct window_pane *wp, ws.ws_col = screen_size_x(&wp->base); ws.ws_row = screen_size_y(&wp->base); - wp->window->pgrp = -1; if (gettimeofday(&wp->window->name_timer, NULL) != 0) fatal("gettimeofday"); tv.tv_sec = 0; tv.tv_usec = NAME_INTERVAL * 1000L; timeradd(&wp->window->name_timer, &tv, &wp->window->name_timer); - switch (forkpty(&wp->fd, wp->tty, NULL, &ws)) { + switch (wp->pid = forkpty(&wp->fd, wp->tty, NULL, &ws)) { case -1: wp->fd = -1; xasprintf(cause, "%s: %s", cmd, strerror(errno)); |