version 1.3, 2009/07/13 23:11:35 |
version 1.4, 2009/07/17 15:03:11 |
|
|
cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx) |
cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx) |
{ |
{ |
struct cmd_new_session_data *data = self->data; |
struct cmd_new_session_data *data = self->data; |
struct client *c = ctx->cmdclient; |
|
struct session *s; |
struct session *s; |
char *cmd, *cwd, *cause; |
char *cmd, *cwd, *cause; |
u_int sx, sy; |
u_int sx, sy; |
|
|
if (ctx->curclient != NULL) |
if (data->newname != NULL && session_find(data->newname) != NULL) { |
return (0); |
ctx->error(ctx, "duplicate session: %s", data->newname); |
|
return (-1); |
|
} |
|
|
if (!data->flag_detached) { |
/* |
if (c == NULL) { |
* There are two cases: |
ctx->error(ctx, "no client to attach to"); |
* |
|
* 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); |
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); |
return (-1); |
} |
} |
} |
} |
|
|
if (data->newname != NULL && session_find(data->newname) != NULL) { |
/* Find new session size and options. */ |
ctx->error(ctx, "duplicate session: %s", data->newname); |
if (data->flag_detached) { |
return (-1); |
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; |
|
} |
} |
} |
|
if (sy > 0 && options_get_number(&global_s_options, "status")) |
cmd = data->cmd; |
sy--; |
if (cmd == NULL) |
if (sx == 0) |
cmd = options_get_string(&global_s_options, "default-command"); |
sx = 1; |
if (c == NULL || c->cwd == NULL) |
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"); |
cwd = options_get_string(&global_s_options, "default-path"); |
|
if (data->cmd != NULL) |
|
cmd = data->cmd; |
else |
else |
cwd = c->cwd; |
cmd = options_get_string(&global_s_options, "default-command"); |
|
|
sx = 80; |
/* Create the new session. */ |
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); |
|
} |
|
|
|
|
|
s = session_create(data->newname, cmd, cwd, sx, sy, &cause); |
s = session_create(data->newname, cmd, cwd, sx, sy, &cause); |
if (s == NULL) { |
if (s == NULL) { |
ctx->error(ctx, "create session failed: %s", cause); |
ctx->error(ctx, "create session failed: %s", cause); |
xfree(cause); |
xfree(cause); |
return (-1); |
return (-1); |
} |
} |
|
|
if (data->winname != NULL) { |
if (data->winname != NULL) { |
xfree(s->curw->window->name); |
xfree(s->curw->window->name); |
s->curw->window->name = xstrdup(data->winname); |
s->curw->window->name = xstrdup(data->winname); |
|
|
&s->curw->window->options, "automatic-rename", 0); |
&s->curw->window->options, "automatic-rename", 0); |
} |
} |
|
|
if (data->flag_detached) { |
/* |
if (c != NULL) |
* If a command client exists, it is either taking this session (and |
server_write_client(c, MSG_EXIT, NULL, 0); |
* needs to get MSG_READY and stay around), or -d is given and it needs |
} else { |
* to exit. |
c->session = s; |
*/ |
server_write_client(c, MSG_READY, NULL, 0); |
if (ctx->cmdclient != NULL) { |
server_redraw_client(c); |
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(); |
recalculate_sizes(); |
|
|
return (1); |
return (1); /* 1 means don't tell command client to exit */ |
} |
} |
|
|
void |
void |