summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Marriott <nicholas.marriott@gmail.com>2009-01-18 12:09:42 +0000
committerNicholas Marriott <nicholas.marriott@gmail.com>2009-01-18 12:09:42 +0000
commit8ea49712fd4c9f158128832e6c93308afeb1bd4d (patch)
treea7a4e84c2722ba9f3848f4bbe377c1e38ed14d1c
parent273d63040ab6f0124518fcdb1ad9f2f10c84c2de (diff)
suspend-client command and suspend client when ^Z key binding is used.
-rw-r--r--CHANGES4
-rw-r--r--GNUmakefile3
-rw-r--r--Makefile3
-rw-r--r--TODO2
-rw-r--r--client-msg.c34
-rw-r--r--client.c7
-rw-r--r--cmd-suspend-client.c65
-rw-r--r--cmd.c3
-rw-r--r--key-bindings.c5
-rw-r--r--server-msg.c23
-rw-r--r--server.c12
-rw-r--r--tmux.c7
-rw-r--r--tmux.h14
-rw-r--r--tty-write.c4
-rw-r--r--tty.c102
15 files changed, 220 insertions, 68 deletions
diff --git a/CHANGES b/CHANGES
index b2702008..d5c2beaa 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,7 @@
17 January 2009
+* suspend-client command to suspend a client. Don't try to background it
+ though...
* tmux 0.6 released.
15 January 2009
@@ -932,7 +934,7 @@
(including mutt, emacs). No status bar yet and no key remapping or other
customisation.
-$Id: CHANGES,v 1.214 2009-01-17 19:08:12 nicm Exp $
+$Id: CHANGES,v 1.215 2009-01-18 12:09:42 nicm Exp $
LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr
LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms
diff --git a/GNUmakefile b/GNUmakefile
index a4ff89be..fbfb61ab 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -1,4 +1,4 @@
-# $Id: GNUmakefile,v 1.58 2009-01-18 00:08:43 nicm Exp $
+# $Id: GNUmakefile,v 1.59 2009-01-18 12:09:42 nicm Exp $
.PHONY: clean
@@ -36,6 +36,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
cmd-save-buffer.c cmd-select-pane.c cmd-split-window.c \
cmd-resize-pane-up.c cmd-resize-pane-down.c cmd-kill-pane.c \
cmd-up-pane.c cmd-down-pane.c cmd-choose-window.c cmd-choose-session.c \
+ cmd-suspend-client.c \
window-clock.c window-scroll.c window-more.c window-copy.c \
window-choose.c \
options.c options-cmd.c paste.c colour.c utf8.c clock.c \
diff --git a/Makefile b/Makefile
index 02765128..67672dd2 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.97 2009-01-18 00:08:43 nicm Exp $
+# $Id: Makefile,v 1.98 2009-01-18 12:09:42 nicm Exp $
.SUFFIXES: .c .o .y .h
.PHONY: clean update-index.html upload-index.html
@@ -40,6 +40,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
cmd-save-buffer.c cmd-select-pane.c cmd-split-window.c \
cmd-resize-pane-up.c cmd-resize-pane-down.c cmd-kill-pane.c \
cmd-up-pane.c cmd-down-pane.c cmd-choose-window.c cmd-choose-session.c \
+ cmd-suspend-client.c \
window-clock.c window-scroll.c window-more.c window-copy.c \
window-choose.c \
options.c options-cmd.c paste.c colour.c utf8.c clock.c \
diff --git a/TODO b/TODO
index 7c657ab4..f57ccafc 100644
--- a/TODO
+++ b/TODO
@@ -72,7 +72,7 @@
(copy from other session)
- function groups, bind-key ^W { select-window 0; send-key ^W } etc ***
- neww should support -k
-- suspend-client command bound to ^Z
+- document suspend-client
- flag to scroll-mode/copy-mode to automatically scroll up a page
- would be nice if tmux could be the shell
- key to switch to copy mode from scroll mode
diff --git a/client-msg.c b/client-msg.c
index 3510e3ac..7f2f3dca 100644
--- a/client-msg.c
+++ b/client-msg.c
@@ -1,4 +1,4 @@
-/* $Id: client-msg.c,v 1.16 2009-01-07 22:57:03 nicm Exp $ */
+/* $Id: client-msg.c,v 1.17 2009-01-18 12:09:42 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,8 +29,7 @@ int client_msg_fn_detach(struct hdr *, struct client_ctx *, char **);
int client_msg_fn_error(struct hdr *, struct client_ctx *, char **);
int client_msg_fn_exit(struct hdr *, struct client_ctx *, char **);
int client_msg_fn_exited(struct hdr *, struct client_ctx *, char **);
-int client_msg_fn_okay(struct hdr *, struct client_ctx *, char **);
-int client_msg_fn_pause(struct hdr *, struct client_ctx *, char **);
+int client_msg_fn_suspend(struct hdr *, struct client_ctx *, char **);
struct client_msg {
enum hdrtype type;
@@ -40,7 +39,8 @@ struct client_msg client_msg_table[] = {
{ MSG_DETACH, client_msg_fn_detach },
{ MSG_ERROR, client_msg_fn_error },
{ MSG_EXIT, client_msg_fn_exit },
- { MSG_EXITED, client_msg_fn_exited }
+ { MSG_EXITED, client_msg_fn_exited },
+ { MSG_SUSPEND, client_msg_fn_suspend },
};
int
@@ -116,3 +116,29 @@ client_msg_fn_exited(
return (-1);
}
+
+int
+client_msg_fn_suspend(
+ struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
+{
+ struct sigaction act;
+
+ if (hdr->size != 0)
+ fatalx("bad MSG_SUSPEND size");
+
+ memset(&act, 0, sizeof act);
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = SA_RESTART;
+
+ act.sa_handler = SIG_DFL;
+ if (sigaction(SIGTSTP, &act, NULL) != 0)
+ fatal("sigaction failed");
+
+ act.sa_handler = sighandler;
+ if (sigaction(SIGCONT, &act, NULL) != 0)
+ fatal("sigaction failed");
+
+ kill(getpid(), SIGTSTP);
+
+ return (0);
+}
diff --git a/client.c b/client.c
index 3ad5bff1..e30e1841 100644
--- a/client.c
+++ b/client.c
@@ -1,4 +1,4 @@
-/* $Id: client.c,v 1.39 2009-01-15 00:21:58 nicm Exp $ */
+/* $Id: client.c,v 1.40 2009-01-18 12:09:42 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -146,6 +146,11 @@ client_main(struct client_ctx *cctx)
while (!sigterm) {
if (sigwinch)
client_handle_winch(cctx);
+ if (sigcont) {
+ siginit();
+ client_write_server(cctx, MSG_WAKEUP, NULL, 0);
+ sigcont = 0;
+ }
switch (client_msg_dispatch(cctx, &error)) {
case -1:
diff --git a/cmd-suspend-client.c b/cmd-suspend-client.c
new file mode 100644
index 00000000..540b2f68
--- /dev/null
+++ b/cmd-suspend-client.c
@@ -0,0 +1,65 @@
+/* $Id: cmd-suspend-client.c,v 1.1 2009-01-18 12:09:42 nicm Exp $ */
+
+/*
+ * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "tmux.h"
+
+/*
+ * Suspend client with SIGTSTP.
+ */
+
+void cmd_suspend_client_exec(struct cmd *, struct cmd_ctx *);
+
+struct cmd_suspend_client_data {
+ char *name;
+ char *target;
+};
+
+const struct cmd_entry cmd_suspend_client_entry = {
+ "suspend-client", "suspendc",
+ "[-c target-client]",
+ 0,
+ cmd_target_init,
+ cmd_target_parse,
+ cmd_suspend_client_exec,
+ cmd_target_send,
+ cmd_target_recv,
+ cmd_target_free,
+ cmd_target_print
+};
+
+void
+cmd_suspend_client_exec(struct cmd *self, struct cmd_ctx *ctx)
+{
+ struct cmd_target_data *data = self->data;
+ struct client *c;
+
+ if ((c = cmd_find_client(ctx, data->target)) == NULL)
+ return;
+
+ tty_stop_tty(&c->tty);
+ c->flags |= CLIENT_SUSPENDED;
+ server_write_client(c, MSG_SUSPEND, NULL, 0);
+
+ if (ctx->cmdclient != NULL)
+ server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
+}
diff --git a/cmd.c b/cmd.c
index 0b110bef..8e7a0e52 100644
--- a/cmd.c
+++ b/cmd.c
@@ -1,4 +1,4 @@
-/* $Id: cmd.c,v 1.79 2009-01-15 19:27:31 nicm Exp $ */
+/* $Id: cmd.c,v 1.80 2009-01-18 12:09:42 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -80,6 +80,7 @@ const struct cmd_entry *cmd_table[] = {
&cmd_source_file_entry,
&cmd_split_window_entry,
&cmd_start_server_entry,
+ &cmd_suspend_client_entry,
&cmd_swap_window_entry,
&cmd_switch_client_entry,
&cmd_unbind_key_entry,
diff --git a/key-bindings.c b/key-bindings.c
index 89f39dab..8b20000c 100644
--- a/key-bindings.c
+++ b/key-bindings.c
@@ -1,4 +1,4 @@
-/* $Id: key-bindings.c,v 1.53 2009-01-17 18:34:12 nicm Exp $ */
+/* $Id: key-bindings.c,v 1.54 2009-01-18 12:09:42 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -108,7 +108,8 @@ key_bindings_init(void)
{ 's', &cmd_choose_session_entry },
{ 't', &cmd_clock_mode_entry },
{ 'w', &cmd_choose_window_entry },
- { 'x', &cmd_kill_pane_entry, },
+ { 'x', &cmd_kill_pane_entry, },
+ { '\032', &cmd_suspend_client_entry },
{ KEYC_UP, &cmd_up_pane_entry },
{ KEYC_DOWN, &cmd_down_pane_entry },
{ KEYC_ADDESC(KEYC_UP), &cmd_resize_pane_up_entry },
diff --git a/server-msg.c b/server-msg.c
index 43293a13..a91c8397 100644
--- a/server-msg.c
+++ b/server-msg.c
@@ -1,4 +1,4 @@
-/* $Id: server-msg.c,v 1.57 2009-01-11 23:31:46 nicm Exp $ */
+/* $Id: server-msg.c,v 1.58 2009-01-18 12:09:42 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,6 +31,7 @@ int server_msg_fn_identify(struct hdr *, struct client *);
int server_msg_fn_resize(struct hdr *, struct client *);
int server_msg_fn_exiting(struct hdr *, struct client *);
int server_msg_fn_unlock(struct hdr *, struct client *);
+int server_msg_fn_wakeup(struct hdr *, struct client *);
void printflike2 server_msg_fn_command_error(
struct cmd_ctx *, const char *, ...);
@@ -48,7 +49,8 @@ const struct server_msg server_msg_table[] = {
{ MSG_COMMAND, server_msg_fn_command },
{ MSG_RESIZE, server_msg_fn_resize },
{ MSG_EXITING, server_msg_fn_exiting },
- { MSG_UNLOCK, server_msg_fn_unlock }
+ { MSG_UNLOCK, server_msg_fn_unlock },
+ { MSG_WAKEUP, server_msg_fn_wakeup },
};
int
@@ -242,7 +244,7 @@ server_msg_fn_exiting(struct hdr *hdr, struct client *c)
c->session = NULL;
- tty_close(&c->tty);
+ tty_close(&c->tty, c->flags & CLIENT_SUSPENDED);
server_write_client(c, MSG_EXITED, NULL, 0);
@@ -271,3 +273,18 @@ server_msg_fn_unlock(struct hdr *hdr, struct client *c)
return (0);
}
+
+int
+server_msg_fn_wakeup(struct hdr *hdr, struct client *c)
+{
+ if (hdr->size != 0)
+ fatalx("bad MSG_WAKEUP size");
+
+ log_debug("wakeup msg from client");
+
+ c->flags &= ~CLIENT_SUSPENDED;
+ tty_start_tty(&c->tty);
+ server_redraw_client(c);
+
+ return (0);
+}
diff --git a/server.c b/server.c
index 98490068..c5c482c5 100644
--- a/server.c
+++ b/server.c
@@ -1,4 +1,4 @@
-/* $Id: server.c,v 1.106 2009-01-17 17:42:10 nicm Exp $ */
+/* $Id: server.c,v 1.107 2009-01-18 12:09:42 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -484,7 +484,8 @@ server_fill_clients(struct pollfd **pfd)
}
(*pfd)++;
- if (c == NULL || c->tty.fd == -1 || c->session == NULL)
+ if (c == NULL || c->flags & CLIENT_SUSPENDED ||
+ c->tty.fd == -1 || c->session == NULL)
(*pfd)->fd = -1;
else {
(*pfd)->fd = c->tty.fd;
@@ -516,7 +517,8 @@ server_handle_clients(struct pollfd **pfd)
}
(*pfd)++;
- if (c != NULL && c->tty.fd != -1 && c->session != NULL) {
+ if (c != NULL && !(c->flags & CLIENT_SUSPENDED) &&
+ c->tty.fd != -1 && c->session != NULL) {
if (buffer_poll(*pfd, c->tty.in, c->tty.out) != 0)
server_lost_client(c);
else
@@ -602,7 +604,7 @@ server_handle_client(struct client *c)
if (c->session == NULL)
return;
- wp = c->session->curw->window->active; /* could die - do each loop */
+ wp = c->session->curw->window->active; /* could die */
server_clear_client_message(c);
if (c->prompt_string != NULL) {
@@ -686,7 +688,7 @@ server_lost_client(struct client *c)
ARRAY_SET(&clients, i, NULL);
}
- tty_free(&c->tty);
+ tty_free(&c->tty, c->flags & CLIENT_SUSPENDED);
if (c->title != NULL)
xfree(c->title);
diff --git a/tmux.c b/tmux.c
index 9f33d7e8..8f636c7b 100644
--- a/tmux.c
+++ b/tmux.c
@@ -1,4 +1,4 @@
-/* $Id: tmux.c,v 1.97 2009-01-15 23:42:21 nicm Exp $ */
+/* $Id: tmux.c,v 1.98 2009-01-18 12:09:42 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -45,6 +45,7 @@ const char *_malloc_options = "AJX";
volatile sig_atomic_t sigwinch;
volatile sig_atomic_t sigterm;
+volatile sig_atomic_t sigcont;
char *cfg_file;
struct options global_options;
@@ -59,7 +60,6 @@ int be_quiet;
time_t start_time;
const char *socket_path;
-void sighandler(int);
__dead void usage(void);
#ifdef NO_PROGNAME
@@ -105,6 +105,9 @@ sighandler(int sig)
case SIGCHLD:
waitpid(WAIT_ANY, NULL, WNOHANG);
break;
+ case SIGCONT:
+ sigcont = 1;
+ break;
}
errno = saved_errno;
}
diff --git a/tmux.h b/tmux.h
index 0994c322..eea4446b 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1,4 +1,4 @@
-/* $Id: tmux.h,v 1.236 2009-01-17 18:38:12 nicm Exp $ */
+/* $Id: tmux.h,v 1.237 2009-01-18 12:09:42 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -358,6 +358,8 @@ enum hdrtype {
MSG_READY,
MSG_RESIZE,
MSG_UNLOCK,
+ MSG_SUSPEND,
+ MSG_WAKEUP,
};
/* Message header structure. */
@@ -759,6 +761,7 @@ struct client {
#define CLIENT_REDRAW 0x8
#define CLIENT_STATUS 0x10
#define CLIENT_REPEAT 0x20 /* allow command to repeat within repeat time */
+#define CLIENT_SUSPENDED 0x40
int flags;
char *message_string;
@@ -959,6 +962,7 @@ char *fgetln(FILE *, size_t *);
/* tmux.c */
extern volatile sig_atomic_t sigwinch;
extern volatile sig_atomic_t sigterm;
+extern volatile sig_atomic_t sigcont;
extern struct options global_options;
extern struct options global_window_options;
extern char *cfg_file;
@@ -972,6 +976,7 @@ extern const char *socket_path;
void logfile(const char *);
void siginit(void);
void sigreset(void);
+void sighandler(int);
/* cfg.c */
int load_cfg(const char *, char **x);
@@ -1001,10 +1006,12 @@ void tty_putcode2(struct tty *, enum tty_code_code, int, int);
void tty_puts(struct tty *, const char *);
void tty_putc(struct tty *, char);
void tty_init(struct tty *, char *, char *);
+void tty_start_tty(struct tty *);
+void tty_stop_tty(struct tty *);
void tty_set_title(struct tty *, const char *);
int tty_open(struct tty *, char **);
-void tty_close(struct tty *);
-void tty_free(struct tty *);
+void tty_close(struct tty *, int);
+void tty_free(struct tty *, int);
void tty_write(struct tty *,
struct screen *, u_int, enum tty_cmd, ...);
void tty_vwrite(struct tty *,
@@ -1135,6 +1142,7 @@ extern const struct cmd_entry cmd_show_window_options_entry;
extern const struct cmd_entry cmd_source_file_entry;
extern const struct cmd_entry cmd_split_window_entry;
extern const struct cmd_entry cmd_start_server_entry;
+extern const struct cmd_entry cmd_suspend_client_entry;
extern const struct cmd_entry cmd_swap_window_entry;
extern const struct cmd_entry cmd_switch_client_entry;
extern const struct cmd_entry cmd_unbind_key_entry;
diff --git a/tty-write.c b/tty-write.c
index a776ca57..62adb8b2 100644
--- a/tty-write.c
+++ b/tty-write.c
@@ -1,4 +1,4 @@
-/* $Id: tty-write.c,v 1.6 2009-01-14 19:29:32 nicm Exp $ */
+/* $Id: tty-write.c,v 1.7 2009-01-18 12:09:42 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -45,6 +45,8 @@ tty_vwrite_window(void *ptr, enum tty_cmd cmd, va_list ap)
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
continue;
+ if (c->flags & CLIENT_SUSPENDED)
+ continue;
if (c->session->curw->window == wp->window) {
va_copy(aq, ap);
diff --git a/tty.c b/tty.c
index 79f7a616..73a7e020 100644
--- a/tty.c
+++ b/tty.c
@@ -1,4 +1,4 @@
-/* $Id: tty.c,v 1.58 2009-01-11 23:31:46 nicm Exp $ */
+/* $Id: tty.c,v 1.59 2009-01-18 12:09:42 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -98,10 +98,6 @@ tty_init(struct tty *tty, char *path, char *term)
int
tty_open(struct tty *tty, char **cause)
{
- struct termios tio;
-#ifdef TIOCFLUSH
- int what;
-#endif
int mode;
tty->fd = open(tty->path, O_RDWR|O_NONBLOCK);
@@ -120,9 +116,6 @@ tty_open(struct tty *tty, char **cause)
else
tty->log_fd = -1;
- tty->cx = UINT_MAX;
- tty->cy = UINT_MAX;
-
if ((tty->term = tty_term_find(tty->termname, tty->fd, cause)) == NULL)
goto error;
@@ -130,7 +123,29 @@ tty_open(struct tty *tty, char **cause)
tty->out = buffer_create(BUFSIZ);
tty->flags &= TTY_UTF8;
- memcpy(&tty->cell, &grid_default_cell, sizeof tty->cell);
+
+ tty_start_tty(tty);
+
+ tty_keys_init(tty);
+
+ tty_fill_acs(tty);
+
+ return (0);
+
+error:
+ close(tty->fd);
+ tty->fd = -1;
+
+ return (-1);
+}
+
+void
+tty_start_tty(struct tty *tty)
+{
+ struct termios tio;
+#ifdef TIOCFLUSH
+ int what;
+#endif
if (tcgetattr(tty->fd, &tty->tio) != 0)
fatal("tcgetattr failed");
@@ -160,17 +175,41 @@ tty_open(struct tty *tty, char **cause)
tty_putcode(tty, TTYC_ENACS);
tty_putcode(tty, TTYC_CLEAR);
- tty_keys_init(tty);
+ memcpy(&tty->cell, &grid_default_cell, sizeof tty->cell);
- tty_fill_acs(tty);
+ tty->cx = UINT_MAX;
+ tty->cy = UINT_MAX;
- return (0);
+ tty->rlower = UINT_MAX;
+ tty->rupper = UINT_MAX;
+}
-error:
- close(tty->fd);
- tty->fd = -1;
+void
+tty_stop_tty(struct tty *tty)
+{
+ struct winsize ws;
- return (-1);
+ /*
+ * Be flexible about error handling and try not kill the server just
+ * because the fd is invalid. Things like ssh -t can easily leave us
+ * with a dead tty.
+ */
+ if (ioctl(tty->fd, TIOCGWINSZ, &ws) == -1) {
+ if (errno != EBADF && errno != ENXIO && errno != ENOTTY)
+ fatal("ioctl(TIOCGWINSZ)");
+ } else if (tcsetattr(tty->fd, TCSANOW, &tty->tio) == -1) {
+ if (errno != EBADF && errno != ENXIO && errno != ENOTTY)
+ fatal("tcsetattr failed");
+ } else {
+ tty_raw(tty,
+ tty_term_string2(tty->term, TTYC_CSR, 0, ws.ws_row - 1));
+ tty_raw(tty, tty_term_string(tty->term, TTYC_RMACS));
+ tty_raw(tty, tty_term_string(tty->term, TTYC_SGR0));
+ tty_raw(tty, tty_term_string(tty->term, TTYC_CLEAR));
+ tty_raw(tty, tty_term_string(tty->term, TTYC_RMKX));
+ tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP));
+ tty_raw(tty, tty_term_string(tty->term, TTYC_CNORM));
+ }
}
void
@@ -198,10 +237,8 @@ tty_get_acs(struct tty *tty, u_char ch)
}
void
-tty_close(struct tty *tty)
+tty_close(struct tty *tty, int no_stop)
{
- struct winsize ws;
-
if (tty->fd == -1)
return;
@@ -210,27 +247,8 @@ tty_close(struct tty *tty)
tty->log_fd = -1;
}
- /*
- * Be flexible about error handling and try not kill the server just
- * because the fd is invalid. Things like ssh -t can easily leave us
- * with a dead tty.
- */
- if (ioctl(tty->fd, TIOCGWINSZ, &ws) == -1) {
- if (errno != EBADF && errno != ENXIO && errno != ENOTTY)
- fatal("ioctl(TIOCGWINSZ)");
- } else if (tcsetattr(tty->fd, TCSANOW, &tty->tio) == -1) {
- if (errno != EBADF && errno != ENXIO && errno != ENOTTY)
- fatal("tcsetattr failed");
- } else {
- tty_raw(tty,
- tty_term_string2(tty->term, TTYC_CSR, 0, ws.ws_row - 1));
- tty_raw(tty, tty_term_string(tty->term, TTYC_RMACS));
- tty_raw(tty, tty_term_string(tty->term, TTYC_SGR0));
- tty_raw(tty, tty_term_string(tty->term, TTYC_CLEAR));
- tty_raw(tty, tty_term_string(tty->term, TTYC_RMKX));
- tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP));
- tty_raw(tty, tty_term_string(tty->term, TTYC_CNORM));
- }
+ if (!no_stop)
+ tty_stop_tty(tty);
tty_term_free(tty->term);
tty_keys_free(tty);
@@ -243,9 +261,9 @@ tty_close(struct tty *tty)
}
void
-tty_free(struct tty *tty)
+tty_free(struct tty *tty, int no_stop)
{
- tty_close(tty);
+ tty_close(tty, no_stop);
if (tty->path != NULL)
xfree(tty->path);