version 1.53, 2013/10/10 12:09:34 |
version 1.54, 2013/10/10 12:26:35 |
|
|
|
|
#include <sys/types.h> |
#include <sys/types.h> |
|
|
|
#include <errno.h> |
|
#include <fcntl.h> |
#include <pwd.h> |
#include <pwd.h> |
#include <stdlib.h> |
#include <stdlib.h> |
#include <string.h> |
#include <string.h> |
|
|
cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) |
cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) |
{ |
{ |
struct args *args = self->args; |
struct args *args = self->args; |
struct client *c = cmdq->client; |
struct client *c = cmdq->client, *c0; |
struct session *s, *groupwith; |
struct session *s, *groupwith; |
struct window *w; |
struct window *w; |
struct environ env; |
struct environ env; |
struct termios tio, *tiop; |
struct termios tio, *tiop; |
struct passwd *pw; |
const char *newname, *target, *update, *errstr, *template; |
const char *newname, *target, *update, *base, *cwd; |
|
const char *errstr, *template; |
|
char *cmd, *cause, *cp; |
char *cmd, *cause, *cp; |
int detached, idx; |
int detached, already_attached, idx, cwd, fd = -1; |
u_int sx, sy; |
u_int sx, sy; |
int already_attached; |
|
struct format_tree *ft; |
struct format_tree *ft; |
|
|
if (args_has(args, 't') && (args->argc != 0 || args_has(args, 'n'))) { |
if (args_has(args, 't') && (args->argc != 0 || args_has(args, 'n'))) { |
|
|
if (session_find(newname) != NULL) { |
if (session_find(newname) != NULL) { |
if (args_has(args, 'A')) { |
if (args_has(args, 'A')) { |
return (cmd_attach_session(cmdq, newname, |
return (cmd_attach_session(cmdq, newname, |
args_has(args, 'D'), 0)); |
args_has(args, 'D'), 0, NULL)); |
} |
} |
cmdq_error(cmdq, "duplicate session: %s", newname); |
cmdq_error(cmdq, "duplicate session: %s", newname); |
return (CMD_RETURN_ERROR); |
return (CMD_RETURN_ERROR); |
|
|
if (c != NULL && c->session != NULL) |
if (c != NULL && c->session != NULL) |
already_attached = 1; |
already_attached = 1; |
|
|
|
/* Get the new session working directory. */ |
|
if (args_has(args, 'c')) { |
|
ft = format_create(); |
|
if ((c0 = cmd_find_client(cmdq, NULL, 1)) != NULL) |
|
format_client(ft, c0); |
|
cp = format_expand(ft, args_get(args, 'c')); |
|
format_free(ft); |
|
|
|
fd = open(cp, O_RDONLY|O_DIRECTORY); |
|
free(cp); |
|
if (fd == -1) { |
|
cmdq_error(cmdq, "bad working directory: %s", |
|
strerror(errno)); |
|
return (CMD_RETURN_ERROR); |
|
} |
|
cwd = fd; |
|
} else if (c->session == NULL) |
|
cwd = c->cwd; |
|
else if ((c0 = cmd_current_client(cmdq)) != NULL) |
|
cwd = c0->session->cwd; |
|
else { |
|
fd = open(".", O_RDONLY); |
|
cwd = fd; |
|
} |
|
|
/* |
/* |
* Save the termios settings, part of which is used for new windows in |
* Save the termios settings, part of which is used for new windows in |
* this session. |
* this session. |
|
|
if (server_client_open(c, NULL, &cause) != 0) { |
if (server_client_open(c, NULL, &cause) != 0) { |
cmdq_error(cmdq, "open terminal failed: %s", cause); |
cmdq_error(cmdq, "open terminal failed: %s", cause); |
free(cause); |
free(cause); |
return (CMD_RETURN_ERROR); |
goto error; |
} |
} |
} |
} |
|
|
/* Get the new session working directory. */ |
|
if (c != NULL && c->cwd != NULL) |
|
base = c->cwd; |
|
else { |
|
pw = getpwuid(getuid()); |
|
if (pw->pw_dir != NULL && *pw->pw_dir != '\0') |
|
base = pw->pw_dir; |
|
else |
|
base = "/"; |
|
} |
|
if (args_has(args, 'c')) |
|
cwd = args_get(args, 'c'); |
|
else |
|
cwd = options_get_string(&global_s_options, "default-path"); |
|
cwd = cmd_default_path(base, base, cwd); |
|
|
|
/* Find new session size. */ |
/* Find new session size. */ |
if (c != NULL) { |
if (c != NULL) { |
sx = c->tty.sx; |
sx = c->tty.sx; |
|
|
sx = strtonum(args_get(args, 'x'), 1, USHRT_MAX, &errstr); |
sx = strtonum(args_get(args, 'x'), 1, USHRT_MAX, &errstr); |
if (errstr != NULL) { |
if (errstr != NULL) { |
cmdq_error(cmdq, "width %s", errstr); |
cmdq_error(cmdq, "width %s", errstr); |
return (CMD_RETURN_ERROR); |
goto error; |
} |
} |
} |
} |
if (detached && args_has(args, 'y')) { |
if (detached && args_has(args, 'y')) { |
sy = strtonum(args_get(args, 'y'), 1, USHRT_MAX, &errstr); |
sy = strtonum(args_get(args, 'y'), 1, USHRT_MAX, &errstr); |
if (errstr != NULL) { |
if (errstr != NULL) { |
cmdq_error(cmdq, "height %s", errstr); |
cmdq_error(cmdq, "height %s", errstr); |
return (CMD_RETURN_ERROR); |
goto error; |
} |
} |
} |
} |
if (sy > 0 && options_get_number(&global_s_options, "status")) |
if (sy > 0 && options_get_number(&global_s_options, "status")) |
|
|
if (s == NULL) { |
if (s == NULL) { |
cmdq_error(cmdq, "create session failed: %s", cause); |
cmdq_error(cmdq, "create session failed: %s", cause); |
free(cause); |
free(cause); |
return (CMD_RETURN_ERROR); |
goto error; |
} |
} |
environ_free(&env); |
environ_free(&env); |
|
|
|
|
template = NEW_SESSION_TEMPLATE; |
template = NEW_SESSION_TEMPLATE; |
|
|
ft = format_create(); |
ft = format_create(); |
if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL) |
if ((c0 = cmd_find_client(cmdq, NULL, 1)) != NULL) |
format_client(ft, c); |
format_client(ft, c0); |
format_session(ft, s); |
format_session(ft, s); |
|
|
cp = format_expand(ft, template); |
cp = format_expand(ft, template); |
|
|
|
|
if (!detached) |
if (!detached) |
cmdq->client_exit = 0; |
cmdq->client_exit = 0; |
|
|
|
if (fd != -1) |
|
close(fd); |
return (CMD_RETURN_NORMAL); |
return (CMD_RETURN_NORMAL); |
|
|
|
error: |
|
if (fd != -1) |
|
close(fd); |
|
return (CMD_RETURN_ERROR); |
} |
} |