mirror of
https://github.com/tmux/tmux.git
synced 2024-12-12 17:38:48 +00:00
Zombie windows, requested by Will Maier.
This commit is contained in:
parent
09a4f6a62d
commit
d90d646ca8
17
CHANGES
17
CHANGES
@ -1,3 +1,18 @@
|
||||
29 June 2008
|
||||
|
||||
* Zombie windows. These are not closed when the child process dies. May be
|
||||
set for a window with the new "remain-on-exit" option; the default setting
|
||||
of this flag for new windows may be set with the "remain-by-default" session
|
||||
option.
|
||||
|
||||
A window may be restarted with the respawn-window command:
|
||||
|
||||
respawn-window [-k] [command]
|
||||
|
||||
If -k is given, any existing process running in the window is killed;
|
||||
if command is omitted, the same command as when the window was first
|
||||
created is used.
|
||||
|
||||
27 June 2008
|
||||
|
||||
* Handle nonexistent session or client to -t properly.
|
||||
@ -577,4 +592,4 @@
|
||||
(including mutt, emacs). No status bar yet and no key remapping or other
|
||||
customisation.
|
||||
|
||||
$Id: CHANGES,v 1.145 2008-06-27 17:10:01 nicm Exp $
|
||||
$Id: CHANGES,v 1.146 2008-06-29 07:04:28 nicm Exp $
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: GNUmakefile,v 1.35 2008-06-25 20:43:13 nicm Exp $
|
||||
# $Id: GNUmakefile,v 1.36 2008-06-29 07:04:29 nicm Exp $
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
@ -29,6 +29,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
|
||||
cmd-show-window-options.c cmd-command-prompt.c cmd-set-buffer.c \
|
||||
cmd-show-buffer.c cmd-list-buffers.c cmd-delete-buffer.c \
|
||||
cmd-list-commands.c cmd-move-window.c cmd-select-prompt.c \
|
||||
cmd-respawn-window.c \
|
||||
window-scroll.c window-more.c window-copy.c options.c paste.c \
|
||||
tty.c tty-keys.c tty-write.c screen-write.c screen-redraw.c
|
||||
|
||||
|
3
Makefile
3
Makefile
@ -1,4 +1,4 @@
|
||||
# $Id: Makefile,v 1.68 2008-06-25 20:43:13 nicm Exp $
|
||||
# $Id: Makefile,v 1.69 2008-06-29 07:04:29 nicm Exp $
|
||||
|
||||
.SUFFIXES: .c .o .y .h
|
||||
.PHONY: clean update-index.html upload-index.html
|
||||
@ -33,6 +33,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
|
||||
cmd-show-window-options.c cmd-command-prompt.c cmd-set-buffer.c \
|
||||
cmd-show-buffer.c cmd-list-buffers.c cmd-delete-buffer.c \
|
||||
cmd-list-commands.c cmd-move-window.c cmd-select-prompt.c \
|
||||
cmd-respawn-window.c \
|
||||
window-scroll.c window-more.c window-copy.c options.c paste.c \
|
||||
tty.c tty-keys.c tty-write.c screen-write.c screen-redraw.c
|
||||
|
||||
|
4
TODO
4
TODO
@ -49,12 +49,13 @@
|
||||
|
||||
-- For 0.4 --------------------------------------------------------------------
|
||||
|
||||
- document zombie windows
|
||||
- document buffer stuff
|
||||
- document next/prev word
|
||||
- commands: save-buffer -b number filename
|
||||
load-buffer -b number filename
|
||||
copy-buffer -s src-session -t dst-session -a src-index -b dst-index
|
||||
(from other session)
|
||||
(from other session)
|
||||
|
||||
-- For 0.5 --------------------------------------------------------------------
|
||||
|
||||
@ -73,3 +74,4 @@
|
||||
have a "edit-mode" option select which keymap
|
||||
- zombie windows: don't disappear when the command dies. new command
|
||||
respawn-window [command] to restart; ommitting commands uses previous
|
||||
- many more info displays for various things
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: cmd-generic.c,v 1.11 2008-06-20 08:36:20 nicm Exp $ */
|
||||
/* $Id: cmd-generic.c,v 1.12 2008-06-29 07:04:30 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -73,6 +73,13 @@ cmd_target_parse(struct cmd *self, int argc, char **argv, char **cause)
|
||||
if (argc != 1)
|
||||
goto usage;
|
||||
data->arg = xstrdup(argv[0]);
|
||||
} else if (self->entry->flags & CMD_ZEROONEARG) {
|
||||
if (argc == 0)
|
||||
data->arg = NULL;
|
||||
else if (argc == 1)
|
||||
data->arg = xstrdup(argv[0]);
|
||||
else
|
||||
goto usage;
|
||||
} else {
|
||||
if (argc != 0)
|
||||
goto usage;
|
||||
@ -192,6 +199,13 @@ cmd_srcdst_parse(struct cmd *self, int argc, char **argv, char **cause)
|
||||
if (argc != 1)
|
||||
goto usage;
|
||||
data->arg = xstrdup(argv[0]);
|
||||
} else if (self->entry->flags & CMD_ZEROONEARG) {
|
||||
if (argc == 0)
|
||||
data->arg = NULL;
|
||||
else if (argc == 1)
|
||||
data->arg = xstrdup(argv[0]);
|
||||
else
|
||||
goto usage;
|
||||
} else {
|
||||
if (argc != 0)
|
||||
goto usage;
|
||||
@ -325,6 +339,13 @@ cmd_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
|
||||
if (argc != 1)
|
||||
goto usage;
|
||||
data->arg = xstrdup(argv[0]);
|
||||
} else if (self->entry->flags & CMD_ZEROONEARG) {
|
||||
if (argc == 0)
|
||||
data->arg = NULL;
|
||||
else if (argc == 1)
|
||||
data->arg = xstrdup(argv[0]);
|
||||
else
|
||||
goto usage;
|
||||
} else {
|
||||
if (argc != 0)
|
||||
goto usage;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: cmd-list-windows.c,v 1.20 2008-06-05 21:25:00 nicm Exp $ */
|
||||
/* $Id: cmd-list-windows.c,v 1.21 2008-06-29 07:04:30 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -50,6 +50,7 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||
struct window *w;
|
||||
u_int i;
|
||||
unsigned long long size;
|
||||
const char *name;
|
||||
|
||||
if ((s = cmd_find_session(ctx, data->target)) == NULL)
|
||||
return;
|
||||
@ -65,9 +66,13 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||
size += w->base.hsize * (sizeof *w->base.grid_colr);
|
||||
size += w->base.hsize * (sizeof *w->base.grid_size);
|
||||
|
||||
if (w->fd != -1)
|
||||
name = ttyname(w->fd);
|
||||
else
|
||||
name = "";
|
||||
ctx->print(ctx,
|
||||
"%d: %s \"%s\" (%s) [%ux%u] [history %u/%u, %llu bytes]",
|
||||
wl->idx, w->name, w->base.title, ttyname(w->fd),
|
||||
wl->idx, w->name, w->base.title, name,
|
||||
screen_size_x(&w->base), screen_size_y(&w->base),
|
||||
w->base.hsize, w->base.hlimit, size);
|
||||
}
|
||||
|
74
cmd-respawn-window.c
Normal file
74
cmd-respawn-window.c
Normal file
@ -0,0 +1,74 @@
|
||||
/* $Id: cmd-respawn-window.c,v 1.1 2008-06-29 07:04:30 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 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 "tmux.h"
|
||||
|
||||
/*
|
||||
* Respawn a window (restart the command). Kill existing if -k given.
|
||||
*/
|
||||
|
||||
void cmd_respawn_window_exec(struct cmd *, struct cmd_ctx *);
|
||||
|
||||
const struct cmd_entry cmd_respawn_window_entry = {
|
||||
"respawn-window", "respawnw",
|
||||
"[-k] " CMD_TARGET_WINDOW_USAGE " [command]",
|
||||
CMD_ZEROONEARG|CMD_KFLAG,
|
||||
cmd_target_init,
|
||||
cmd_target_parse,
|
||||
cmd_respawn_window_exec,
|
||||
cmd_target_send,
|
||||
cmd_target_recv,
|
||||
cmd_target_free,
|
||||
cmd_target_print
|
||||
};
|
||||
|
||||
void
|
||||
cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||
{
|
||||
struct cmd_target_data *data = self->data;
|
||||
struct winlink *wl;
|
||||
struct session *s;
|
||||
const char *env[] = { NULL, "TERM=screen", NULL };
|
||||
char *cmd;
|
||||
|
||||
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
|
||||
return;
|
||||
|
||||
if (wl->window->fd != -1 && !(data->flags & CMD_KFLAG)) {
|
||||
ctx->error(ctx, "window still active: %s:%d", s->name, wl->idx);
|
||||
return;
|
||||
}
|
||||
|
||||
cmd = data->arg;
|
||||
if (cmd == NULL)
|
||||
cmd = options_get_string(&s->options, "default-command");
|
||||
|
||||
if (window_spawn(wl->window, cmd, env) != 0) {
|
||||
ctx->error(ctx, "respawn failed: %s:%d", s->name, wl->idx);
|
||||
return;
|
||||
}
|
||||
screen_reset(&wl->window->base);
|
||||
|
||||
recalculate_sizes();
|
||||
server_redraw_window(wl->window);
|
||||
|
||||
if (ctx->cmdclient != NULL)
|
||||
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* $Id: cmd-set-option.c,v 1.36 2008-06-23 22:12:29 nicm Exp $ */
|
||||
/* $Id: cmd-set-option.c,v 1.37 2008-06-29 07:04:30 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -64,6 +64,7 @@ const struct set_option_entry set_option_table[NSETOPTION] = {
|
||||
{ "display-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
|
||||
{ "history-limit", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
|
||||
{ "prefix", SET_OPTION_KEY, 0, 0, NULL },
|
||||
{ "remain-by-default", SET_OPTION_FLAG, 0, 0, NULL },
|
||||
{ "set-titles", SET_OPTION_FLAG, 0, 0, NULL },
|
||||
{ "status", SET_OPTION_FLAG, 0, 0, NULL },
|
||||
{ "status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: cmd-set-window-option.c,v 1.10 2008-06-18 22:21:51 nicm Exp $ */
|
||||
/* $Id: cmd-set-window-option.c,v 1.11 2008-06-29 07:04:30 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -218,6 +218,20 @@ cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||
s->name, wl->idx, number);
|
||||
|
||||
recalculate_sizes();
|
||||
} else if (strcmp(data->option, "remain-on-exit") == 0) {
|
||||
if (flag == -1) {
|
||||
ctx->error(ctx, "bad value: %s", data->value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (flag == -2)
|
||||
wl->window->flags ^= WINDOW_ZOMBIFY;
|
||||
else {
|
||||
if (flag)
|
||||
wl->window->flags |= WINDOW_ZOMBIFY;
|
||||
else
|
||||
wl->window->flags &= ~WINDOW_ZOMBIFY;
|
||||
}
|
||||
} else {
|
||||
ctx->error(ctx, "unknown option: %s", data->option);
|
||||
return;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: cmd-show-window-options.c,v 1.1 2008-06-16 06:10:02 nicm Exp $ */
|
||||
/* $Id: cmd-show-window-options.c,v 1.2 2008-06-29 07:04:30 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -60,6 +60,8 @@ cmd_show_window_options_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||
ctx->print(ctx, "force-height %u", wl->window->limity);
|
||||
if (wl->window->flags & WINDOW_MONITOR)
|
||||
ctx->print(ctx, "monitor-activity");
|
||||
if (wl->window->flags & WINDOW_ZOMBIFY)
|
||||
ctx->print(ctx, "remain-on-exit");
|
||||
|
||||
if (ctx->cmdclient != NULL)
|
||||
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
|
||||
|
3
cmd.c
3
cmd.c
@ -1,4 +1,4 @@
|
||||
/* $Id: cmd.c,v 1.59 2008-06-27 17:10:01 nicm Exp $ */
|
||||
/* $Id: cmd.c,v 1.60 2008-06-29 07:04:30 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -54,6 +54,7 @@ const struct cmd_entry *cmd_table[] = {
|
||||
&cmd_refresh_client_entry,
|
||||
&cmd_rename_session_entry,
|
||||
&cmd_rename_window_entry,
|
||||
&cmd_respawn_window_entry,
|
||||
&cmd_scroll_mode_entry,
|
||||
&cmd_select_prompt_entry,
|
||||
&cmd_select_window_entry,
|
||||
|
23
screen.c
23
screen.c
@ -1,4 +1,4 @@
|
||||
/* $Id: screen.c,v 1.62 2008-06-18 22:21:51 nicm Exp $ */
|
||||
/* $Id: screen.c,v 1.63 2008-06-29 07:04:30 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -156,6 +156,27 @@ screen_create(struct screen *s, u_int dx, u_int dy, u_int hlimit)
|
||||
screen_clear_selection(s);
|
||||
}
|
||||
|
||||
/* Reinitialise screen. */
|
||||
void
|
||||
screen_reset(struct screen *s)
|
||||
{
|
||||
s->cx = 0;
|
||||
s->cy = 0;
|
||||
|
||||
s->rupper = 0;
|
||||
s->rlower = s->dy - 1;
|
||||
|
||||
s->attr = SCREEN_DEFATTR;
|
||||
s->colr = SCREEN_DEFCOLR;
|
||||
|
||||
s->mode = MODE_CURSOR|MODE_KCURSOR|MODE_KKEYPAD;
|
||||
|
||||
screen_display_fill_area(s, 0, 0,
|
||||
screen_size_x(s), screen_size_y(s), ' ', 0, 0x88);
|
||||
|
||||
screen_clear_selection(s);
|
||||
}
|
||||
|
||||
/* Resize screen. */
|
||||
void
|
||||
screen_resize(struct screen *s, u_int sx, u_int sy)
|
||||
|
11
server.c
11
server.c
@ -1,4 +1,4 @@
|
||||
/* $Id: server.c,v 1.76 2008-06-23 07:41:21 nicm Exp $ */
|
||||
/* $Id: server.c,v 1.77 2008-06-29 07:04:30 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -263,7 +263,7 @@ server_fill_windows(struct pollfd **pfd)
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
|
||||
if ((w = ARRAY_ITEM(&windows, i)) == NULL)
|
||||
if ((w = ARRAY_ITEM(&windows, i)) == NULL || w->fd == -1)
|
||||
(*pfd)->fd = -1;
|
||||
else {
|
||||
(*pfd)->fd = w->fd;
|
||||
@ -284,7 +284,7 @@ server_handle_windows(struct pollfd **pfd)
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
|
||||
if ((w = ARRAY_ITEM(&windows, i)) != NULL) {
|
||||
if ((w = ARRAY_ITEM(&windows, i)) != NULL && w->fd != -1) {
|
||||
log_debug("testing window %d (%d)", (*pfd)->fd, w->fd);
|
||||
if (buffer_poll(*pfd, w->in, w->out) != 0)
|
||||
server_lost_window(w);
|
||||
@ -629,6 +629,11 @@ server_lost_window(struct window *w)
|
||||
|
||||
log_debug("lost window %d", w->fd);
|
||||
|
||||
if (w->flags & WINDOW_ZOMBIFY) {
|
||||
w->fd = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
|
||||
s = ARRAY_ITEM(&sessions, i);
|
||||
if (s == NULL)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: session.c,v 1.39 2008-06-20 08:36:20 nicm Exp $ */
|
||||
/* $Id: session.c,v 1.40 2008-06-29 07:04:30 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -203,6 +203,10 @@ session_new(struct session *s, const char *name, const char *cmd, int idx)
|
||||
hlimit = options_get_number(&s->options, "history-limit");
|
||||
if ((w = window_create(name, cmd, env, s->sx, s->sy, hlimit)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (options_get_number(&s->options, "remain-by-default"))
|
||||
w->flags |= WINDOW_ZOMBIFY;
|
||||
|
||||
return (session_attach(s, w, idx));
|
||||
}
|
||||
|
||||
|
3
tmux.c
3
tmux.c
@ -1,4 +1,4 @@
|
||||
/* $Id: tmux.c,v 1.69 2008-06-23 22:12:29 nicm Exp $ */
|
||||
/* $Id: tmux.c,v 1.70 2008-06-29 07:04:30 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -222,6 +222,7 @@ main(int argc, char **argv)
|
||||
options_set_number(&global_options, "status-interval", 15);
|
||||
options_set_number(&global_options, "set-titles", 1);
|
||||
options_set_number(&global_options, "buffer-limit", 9);
|
||||
options_set_number(&global_options, "remain-by-default", 0);
|
||||
|
||||
if (cfg_file == NULL) {
|
||||
home = getenv("HOME");
|
||||
|
12
tmux.h
12
tmux.h
@ -1,4 +1,4 @@
|
||||
/* $Id: tmux.h,v 1.170 2008-06-25 20:43:14 nicm Exp $ */
|
||||
/* $Id: tmux.h,v 1.171 2008-06-29 07:04:31 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -549,6 +549,7 @@ struct window_mode {
|
||||
/* Window structure. */
|
||||
struct window {
|
||||
char *name;
|
||||
char *cmd;
|
||||
|
||||
int fd;
|
||||
struct buffer *in;
|
||||
@ -562,6 +563,7 @@ struct window {
|
||||
#define WINDOW_ACTIVITY 0x4
|
||||
#define WINDOW_MONITOR 0x8
|
||||
#define WINDOW_AGGRESSIVE 0x10
|
||||
#define WINDOW_ZOMBIFY 0x20
|
||||
|
||||
u_int limitx;
|
||||
u_int limity;
|
||||
@ -764,6 +766,7 @@ struct cmd_entry {
|
||||
#define CMD_KFLAG 0x4
|
||||
#define CMD_DFLAG 0x8
|
||||
#define CMD_ONEARG 0x10
|
||||
#define CMD_ZEROONEARG 0x20
|
||||
int flags;
|
||||
|
||||
void (*init)(struct cmd *, int);
|
||||
@ -821,7 +824,7 @@ struct set_option_entry {
|
||||
const char **choices;
|
||||
};
|
||||
extern const struct set_option_entry set_option_table[];
|
||||
#define NSETOPTION 13
|
||||
#define NSETOPTION 14
|
||||
|
||||
#ifdef NO_STRTONUM
|
||||
/* strtonum.c */
|
||||
@ -967,6 +970,7 @@ extern const struct cmd_entry cmd_previous_window_entry;
|
||||
extern const struct cmd_entry cmd_refresh_client_entry;
|
||||
extern const struct cmd_entry cmd_rename_session_entry;
|
||||
extern const struct cmd_entry cmd_rename_window_entry;
|
||||
extern const struct cmd_entry cmd_respawn_window_entry;
|
||||
extern const struct cmd_entry cmd_scroll_mode_entry;
|
||||
extern const struct cmd_entry cmd_select_window_entry;
|
||||
extern const struct cmd_entry cmd_send_keys_entry;
|
||||
@ -1171,6 +1175,7 @@ void screen_redraw_columns(struct screen_redraw_ctx *, u_int, u_int);
|
||||
const char *screen_colourstring(u_char);
|
||||
u_char screen_stringcolour(const char *);
|
||||
void screen_create(struct screen *, u_int, u_int, u_int);
|
||||
void screen_reset(struct screen *);
|
||||
void screen_destroy(struct screen *);
|
||||
void screen_resize(struct screen *, u_int, u_int);
|
||||
void screen_expand_line(struct screen *, u_int, u_int);
|
||||
@ -1201,7 +1206,8 @@ void winlink_remove(struct winlinks *, struct winlink *);
|
||||
struct winlink *winlink_next(struct winlinks *, struct winlink *);
|
||||
struct winlink *winlink_previous(struct winlinks *, struct winlink *);
|
||||
struct window *window_create(const char *,
|
||||
const char *, const char **, u_int, u_int, u_int);
|
||||
const char *, const char **, u_int, u_int, u_int);
|
||||
int window_spawn(struct window *, const char *, const char **);
|
||||
void window_destroy(struct window *);
|
||||
int window_resize(struct window *, u_int, u_int);
|
||||
int window_set_mode(struct window *, const struct window_mode *);
|
||||
|
95
window.c
95
window.c
@ -1,4 +1,4 @@
|
||||
/* $Id: window.c,v 1.45 2008-06-20 17:31:48 nicm Exp $ */
|
||||
/* $Id: window.c,v 1.46 2008-06-29 07:04:31 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -166,50 +166,25 @@ winlink_previous(unused struct winlinks *wwl, struct winlink *wl)
|
||||
|
||||
struct window *
|
||||
window_create(const char *name,
|
||||
const char *cmd, const char **env, u_int sx, u_int sy, u_int hlimit)
|
||||
const char *cmd, const char **envp, u_int sx, u_int sy, u_int hlimit)
|
||||
{
|
||||
struct window *w;
|
||||
struct winsize ws;
|
||||
int fd, mode;
|
||||
char *ptr, *copy;
|
||||
const char **entry;
|
||||
|
||||
memset(&ws, 0, sizeof ws);
|
||||
ws.ws_col = sx;
|
||||
ws.ws_row = sy;
|
||||
|
||||
switch (forkpty(&fd, NULL, NULL, &ws)) {
|
||||
case -1:
|
||||
return (NULL);
|
||||
case 0:
|
||||
for (entry = env; *entry != NULL; entry++) {
|
||||
if (putenv(*entry) != 0)
|
||||
fatal("putenv failed");
|
||||
}
|
||||
sigreset();
|
||||
log_debug("started child: cmd=%s; pid=%d", cmd, (int) getpid());
|
||||
log_close();
|
||||
|
||||
execl(_PATH_BSHELL, "sh", "-c", cmd, (char *) NULL);
|
||||
fatal("execl failed");
|
||||
}
|
||||
|
||||
if ((mode = fcntl(fd, F_GETFL)) == -1)
|
||||
fatal("fcntl failed");
|
||||
if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1)
|
||||
fatal("fcntl failed");
|
||||
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
|
||||
fatal("fcntl failed");
|
||||
|
||||
w = xmalloc(sizeof *w);
|
||||
w->fd = fd;
|
||||
w->cmd = NULL;
|
||||
|
||||
w->fd = -1;
|
||||
w->in = buffer_create(BUFSIZ);
|
||||
w->out = buffer_create(BUFSIZ);
|
||||
|
||||
w->mode = NULL;
|
||||
w->flags = 0;
|
||||
|
||||
w->limitx = w->limity = UINT_MAX;
|
||||
screen_create(&w->base, sx, sy, hlimit);
|
||||
w->screen = &w->base;
|
||||
|
||||
input_init(w);
|
||||
|
||||
if (name == NULL) {
|
||||
@ -238,9 +213,58 @@ window_create(const char *name,
|
||||
ARRAY_ADD(&windows, w);
|
||||
w->references = 0;
|
||||
|
||||
if (window_spawn(w, cmd, envp) != 0) {
|
||||
window_destroy(w);
|
||||
return (NULL);
|
||||
}
|
||||
return (w);
|
||||
}
|
||||
|
||||
int
|
||||
window_spawn(struct window *w, const char *cmd, const char **envp)
|
||||
{
|
||||
struct winsize ws;
|
||||
int mode;
|
||||
const char **envq;
|
||||
|
||||
if (w->fd != -1)
|
||||
close(w->fd);
|
||||
if (cmd != NULL) {
|
||||
if (w->cmd != NULL)
|
||||
xfree(w->cmd);
|
||||
w->cmd = xstrdup(cmd);
|
||||
}
|
||||
|
||||
memset(&ws, 0, sizeof ws);
|
||||
ws.ws_col = screen_size_x(&w->base);
|
||||
ws.ws_row = screen_size_y(&w->base);
|
||||
|
||||
switch (forkpty(&w->fd, NULL, NULL, &ws)) {
|
||||
case -1:
|
||||
return (1);
|
||||
case 0:
|
||||
for (envq = envp; *envq != NULL; envq++) {
|
||||
if (putenv(*envq) != 0)
|
||||
fatal("putenv failed");
|
||||
}
|
||||
sigreset();
|
||||
log_debug("new child: cmd=%s; pid=%d", w->cmd, (int) getpid());
|
||||
log_close();
|
||||
|
||||
execl(_PATH_BSHELL, "sh", "-c", w->cmd, (char *) NULL);
|
||||
fatal("execl failed");
|
||||
}
|
||||
|
||||
if ((mode = fcntl(w->fd, F_GETFL)) == -1)
|
||||
fatal("fcntl failed");
|
||||
if (fcntl(w->fd, F_SETFL, mode|O_NONBLOCK) == -1)
|
||||
fatal("fcntl failed");
|
||||
if (fcntl(w->fd, F_SETFD, FD_CLOEXEC) == -1)
|
||||
fatal("fcntl failed");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
window_destroy(struct window *w)
|
||||
{
|
||||
@ -252,7 +276,8 @@ window_destroy(struct window *w)
|
||||
}
|
||||
ARRAY_REMOVE(&windows, i);
|
||||
|
||||
close(w->fd);
|
||||
if (w->fd != -1)
|
||||
close(w->fd);
|
||||
|
||||
input_free(w);
|
||||
|
||||
@ -282,7 +307,7 @@ window_resize(struct window *w, u_int sx, u_int sy)
|
||||
if (w->mode != NULL)
|
||||
w->mode->resize(w, sx, sy);
|
||||
|
||||
if (ioctl(w->fd, TIOCSWINSZ, &ws) == -1)
|
||||
if (w->fd != -1 && ioctl(w->fd, TIOCSWINSZ, &ws) == -1)
|
||||
fatal("ioctl failed");
|
||||
return (0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user