=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/cmd-new-session.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- src/usr.bin/tmux/cmd-new-session.c 2009/07/13 23:11:35 1.3 +++ src/usr.bin/tmux/cmd-new-session.c 2009/07/17 15:03:11 1.4 @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-new-session.c,v 1.3 2009/07/13 23:11:35 nicm Exp $ */ +/* $OpenBSD: cmd-new-session.c,v 1.4 2009/07/17 15:03:11 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -111,65 +111,80 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_new_session_data *data = self->data; - struct client *c = ctx->cmdclient; struct session *s; char *cmd, *cwd, *cause; u_int sx, sy; - if (ctx->curclient != NULL) - return (0); + if (data->newname != NULL && session_find(data->newname) != NULL) { + ctx->error(ctx, "duplicate session: %s", data->newname); + return (-1); + } - if (!data->flag_detached) { - if (c == NULL) { - ctx->error(ctx, "no client to attach to"); + /* + * There are two cases: + * + * 1. If cmdclient is non-NULL, new-session has been called from the + * command-line - cmdclient is to become a new attached, interactive + * client. Unless -d is given, the terminal must be opened and then + * the client sent MSG_READY. + * + * 2. If cmdclient is NULL, new-session has been called from an + * existing client (such as a key binding). + * + * In both cases, a new additional session needs to be created and + * (unless -d) set as the current session for the client. + */ + + /* Open the terminal if necessary. */ + if (!data->flag_detached && ctx->cmdclient != NULL) { + if (!(ctx->cmdclient->flags & CLIENT_TERMINAL)) { + ctx->error(ctx, "not a terminal"); return (-1); } - if (!(c->flags & CLIENT_TERMINAL)) { - ctx->error(ctx, "not a terminal"); + + if (tty_open(&ctx->cmdclient->tty, &cause) != 0) { + ctx->error(ctx, "open terminal failed: %s", cause); + xfree(cause); return (-1); } } - if (data->newname != NULL && session_find(data->newname) != NULL) { - ctx->error(ctx, "duplicate session: %s", data->newname); - return (-1); + /* Find new session size and options. */ + if (data->flag_detached) { + sx = 80; + sy = 25; + } else { + if (ctx->cmdclient != NULL) { + sx = ctx->cmdclient->tty.sx; + sy = ctx->cmdclient->tty.sy; + } else { + sx = ctx->curclient->tty.sx; + sy = ctx->curclient->tty.sy; + } } - - cmd = data->cmd; - if (cmd == NULL) - cmd = options_get_string(&global_s_options, "default-command"); - if (c == NULL || c->cwd == NULL) + if (sy > 0 && options_get_number(&global_s_options, "status")) + sy--; + if (sx == 0) + sx = 1; + if (sy == 0) + sy = 1; + if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL) + cwd = ctx->cmdclient->cwd; + else cwd = options_get_string(&global_s_options, "default-path"); + if (data->cmd != NULL) + cmd = data->cmd; else - cwd = c->cwd; + cmd = options_get_string(&global_s_options, "default-command"); - sx = 80; - sy = 25; - if (!data->flag_detached) { - sx = c->tty.sx; - sy = c->tty.sy; - } - - if (options_get_number(&global_s_options, "status")) { - if (sy == 0) - sy = 1; - else - sy--; - } - - if (!data->flag_detached && tty_open(&c->tty, &cause) != 0) { - ctx->error(ctx, "open terminal failed: %s", cause); - xfree(cause); - return (-1); - } - - + /* Create the new session. */ s = session_create(data->newname, cmd, cwd, sx, sy, &cause); if (s == NULL) { ctx->error(ctx, "create session failed: %s", cause); xfree(cause); return (-1); } + if (data->winname != NULL) { xfree(s->curw->window->name); s->curw->window->name = xstrdup(data->winname); @@ -177,17 +192,31 @@ &s->curw->window->options, "automatic-rename", 0); } - if (data->flag_detached) { - if (c != NULL) - server_write_client(c, MSG_EXIT, NULL, 0); - } else { - c->session = s; - server_write_client(c, MSG_READY, NULL, 0); - server_redraw_client(c); + /* + * If a command client exists, it is either taking this session (and + * needs to get MSG_READY and stay around), or -d is given and it needs + * to exit. + */ + if (ctx->cmdclient != NULL) { + if (!data->flag_detached) + server_write_client(ctx->cmdclient, MSG_READY, NULL, 0); + else + server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); } + + /* Set the client to the new session. */ + if (!data->flag_detached) { + if (ctx->cmdclient != NULL) { + ctx->cmdclient->session = s; + server_redraw_client(ctx->cmdclient); + } else { + ctx->curclient->session = s; + server_redraw_client(ctx->curclient); + } + } recalculate_sizes(); - return (1); + return (1); /* 1 means don't tell command client to exit */ } void