summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@openbsd.org>2009-09-16 12:35:04 +0000
committerNicholas Marriott <nicm@openbsd.org>2009-09-16 12:35:04 +0000
commit5c60162e3c4f8ac9deede6c0fb5a21930d92e3b4 (patch)
tree16e91d61eed65cf74d3987cf9b7cd08ffea48288
parenta6dd9e8e7eb0d7734b0905a97f6e8b0087a2e09c (diff)
Rather than constructing an entire termios struct from ttydefaults.h, just let
forkpty do it and then alter the bits that should be changed after fork. A little neater and more portable.
-rw-r--r--cmd-new-session.c21
-rw-r--r--cmd-respawn-window.c2
-rw-r--r--cmd-split-window.c2
-rw-r--r--session.c12
-rw-r--r--tmux.h2
-rw-r--r--window.c11
6 files changed, 29 insertions, 21 deletions
diff --git a/cmd-new-session.c b/cmd-new-session.c
index df1ec45c..467fa879 100644
--- a/cmd-new-session.c
+++ b/cmd-new-session.c
@@ -21,9 +21,6 @@
#include <string.h>
#include <termios.h>
-#define TTYDEFCHARS
-#include <sys/ttydefaults.h>
-
#include "tmux.h"
/*
@@ -116,7 +113,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
struct session *s;
struct window *w;
struct environ env;
- struct termios tio;
+ struct termios tio, *tiop;
const char *update;
char *overrides, *cmd, *cwd, *cause;
int detached, idx;
@@ -151,8 +148,8 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
detached = 1;
/*
- * Fill in the termios settings used for new windows in this session;
- * if there is a command client, use the control characters from it.
+ * Save the termios settings, part of which is used for new windows in
+ * this session.
*
* This is read again with tcgetattr() rather than using tty.tio as if
* detached, tty_open won't be called. Because of this, it must be done
@@ -162,15 +159,9 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
if (ctx->cmdclient != NULL && ctx->cmdclient->tty.fd != -1) {
if (tcgetattr(ctx->cmdclient->tty.fd, &tio) != 0)
fatal("tcgetattr failed");
+ tiop = &tio;
} else
- memcpy(tio.c_cc, ttydefchars, sizeof tio.c_cc);
- tio.c_cc[VERASE] = '\177';
- tio.c_iflag = TTYDEF_IFLAG;
- tio.c_oflag = TTYDEF_OFLAG;
- tio.c_lflag = TTYDEF_LFLAG;
- tio.c_cflag = TTYDEF_CFLAG;
- cfsetispeed(&tio, TTYDEF_SPEED);
- cfsetospeed(&tio, TTYDEF_SPEED);
+ tiop = NULL;
/* Open the terminal if necessary. */
if (!detached && ctx->cmdclient != NULL) {
@@ -227,7 +218,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
/* Create the new session. */
idx = -1 - options_get_number(&global_s_options, "base-index");
s = session_create(
- data->newname, cmd, cwd, &env, &tio, idx, sx, sy, &cause);
+ data->newname, cmd, cwd, &env, tiop, idx, sx, sy, &cause);
if (s == NULL) {
ctx->error(ctx, "create session failed: %s", cause);
xfree(cause);
diff --git a/cmd-respawn-window.c b/cmd-respawn-window.c
index cd96f50b..540931aa 100644
--- a/cmd-respawn-window.c
+++ b/cmd-respawn-window.c
@@ -76,7 +76,7 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
TAILQ_INSERT_HEAD(&w->panes, wp, entry);
window_pane_resize(wp, w->sx, w->sy);
if (window_pane_spawn(
- wp, data->arg, NULL, NULL, &env, &s->tio, &cause) != 0) {
+ wp, data->arg, NULL, NULL, &env, s->tio, &cause) != 0) {
ctx->error(ctx, "respawn window failed: %s", cause);
xfree(cause);
environ_free(&env);
diff --git a/cmd-split-window.c b/cmd-split-window.c
index d6fc3f78..1604d9e2 100644
--- a/cmd-split-window.c
+++ b/cmd-split-window.c
@@ -190,7 +190,7 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
shell = _PATH_BSHELL;
wp = window_add_pane(w, hlimit);
- if (window_pane_spawn(wp, cmd, shell, cwd, &env, &s->tio, &cause) != 0)
+ if (window_pane_spawn(wp, cmd, shell, cwd, &env, s->tio, &cause) != 0)
goto error;
if (layout_split_pane(w->active, type, size, wp) != 0) {
cause = xstrdup("pane too small");
diff --git a/session.c b/session.c
index 4e5ac83e..fd2345b3 100644
--- a/session.c
+++ b/session.c
@@ -139,7 +139,12 @@ session_create(const char *name, const char *cmd, const char *cwd,
environ_init(&s->environ);
if (env != NULL)
environ_copy(env, &s->environ);
- memcpy(&s->tio, tio, sizeof s->tio);
+
+ s->tio = NULL;
+ if (tio != NULL) {
+ s->tio = xmalloc(sizeof *s->tio);
+ memcpy(s->tio, tio, sizeof *s->tio);
+ }
s->sx = sx;
s->sy = sy;
@@ -182,6 +187,9 @@ session_destroy(struct session *s)
while (!ARRAY_EMPTY(&sessions) && ARRAY_LAST(&sessions) == NULL)
ARRAY_TRUNC(&sessions, 1);
+ if (s->tio != NULL)
+ xfree(s->tio);
+
session_alert_cancel(s, NULL);
environ_free(&s->environ);
options_free(&s->options);
@@ -237,7 +245,7 @@ session_new(struct session *s,
hlimit = options_get_number(&s->options, "history-limit");
w = window_create(
- name, cmd, shell, cwd, &env, &s->tio, s->sx, s->sy, hlimit, cause);
+ name, cmd, shell, cwd, &env, s->tio, s->sx, s->sy, hlimit, cause);
if (w == NULL) {
environ_free(&env);
return (NULL);
diff --git a/tmux.h b/tmux.h
index 63f75577..0c5d2686 100644
--- a/tmux.h
+++ b/tmux.h
@@ -815,7 +815,7 @@ struct session {
#define SESSION_DEAD 0x2
int flags;
- struct termios tio;
+ struct termios *tio;
struct environ environ;
diff --git a/window.c b/window.c
index 62b1f487..5683f174 100644
--- a/window.c
+++ b/window.c
@@ -454,6 +454,7 @@ window_pane_spawn(struct window_pane *wp, const char *cmd, const char *shell,
struct environ_entry *envent;
const char *ptr;
struct timeval tv;
+ struct termios tio2;
u_int i;
if (wp->fd != -1)
@@ -484,7 +485,7 @@ window_pane_spawn(struct window_pane *wp, const char *cmd, const char *shell,
tv.tv_usec = NAME_INTERVAL * 1000L;
timeradd(&wp->window->name_timer, &tv, &wp->window->name_timer);
- switch (wp->pid = forkpty(&wp->fd, wp->tty, tio, &ws)) {
+ switch (wp->pid = forkpty(&wp->fd, wp->tty, NULL, &ws)) {
case -1:
wp->fd = -1;
xasprintf(cause, "%s: %s", cmd, strerror(errno));
@@ -493,6 +494,14 @@ window_pane_spawn(struct window_pane *wp, const char *cmd, const char *shell,
if (chdir(wp->cwd) != 0)
chdir("/");
+ if (tcgetattr(STDIN_FILENO, &tio2) != 0)
+ fatal("tcgetattr failed");
+ if (tio != NULL)
+ memcpy(tio2.c_cc, tio->c_cc, sizeof tio2.c_cc);
+ tio2.c_cc[VERASE] = '\177';
+ if (tcsetattr(STDIN_FILENO, TCSANOW, &tio2) != 0)
+ fatal("tcgetattr failed");
+
ARRAY_INIT(&varlist);
for (varp = environ; *varp != NULL; varp++) {
var = xstrdup(*varp);