mirror of
https://github.com/tmate-io/tmate.git
synced 2025-08-09 05:54:47 +02:00
Sync OpenBSD patchset 350:
Support -c like sh(1) to execute a command, useful when tmux is a login shell. Suggested by halex@. This includes another protocol version increase (the last for now) so again restart the tmux server before upgrading.
This commit is contained in:
68
tmux.c
68
tmux.c
@ -1,4 +1,4 @@
|
||||
/* $Id: tmux.c,v 1.174 2009-09-23 15:00:09 tcunha Exp $ */
|
||||
/* $Id: tmux.c,v 1.175 2009-09-23 15:18:56 tcunha Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -62,7 +62,8 @@ int login_shell;
|
||||
__dead void usage(void);
|
||||
char *makesockpath(const char *);
|
||||
int prepare_cmd(enum msgtype *, void **, size_t *, int, char **);
|
||||
int dispatch_imsg(struct client_ctx *, int *);
|
||||
int dispatch_imsg(struct client_ctx *, const char *, int *);
|
||||
__dead void shell_exec(const char *, const char *);
|
||||
|
||||
#ifndef HAVE_PROGNAME
|
||||
char *__progname = (char *) "tmux";
|
||||
@ -72,7 +73,7 @@ __dead void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: %s [-28dlquv] [-f file] [-L socket-name]\n"
|
||||
"usage: %s [-28dlquv] [-c shell-command] [-f file] [-L socket-name]\n"
|
||||
" [-S socket-path] [command [flags]]\n",
|
||||
__progname);
|
||||
exit(1);
|
||||
@ -284,17 +285,17 @@ main(int argc, char **argv)
|
||||
struct passwd *pw;
|
||||
struct options *so, *wo;
|
||||
struct keylist *keylist;
|
||||
char *s, *path, *label, *home, *cause, **var;
|
||||
char cwd[MAXPATHLEN];
|
||||
char *s, *shellcmd, *path, *label, *home, *cause;
|
||||
char cwd[MAXPATHLEN], **var;
|
||||
void *buf;
|
||||
size_t len;
|
||||
int retcode, opt, flags, cmdflags = 0;
|
||||
int nfds;
|
||||
|
||||
flags = 0;
|
||||
label = path = NULL;
|
||||
shellcmd = label = path = NULL;
|
||||
login_shell = (**argv == '-');
|
||||
while ((opt = getopt(argc, argv, "28df:lL:qS:uUv")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "28c:df:lL:qS:uUv")) != -1) {
|
||||
switch (opt) {
|
||||
case '2':
|
||||
flags |= IDENTIFY_256COLOURS;
|
||||
@ -304,6 +305,11 @@ main(int argc, char **argv)
|
||||
flags |= IDENTIFY_88COLOURS;
|
||||
flags &= ~IDENTIFY_256COLOURS;
|
||||
break;
|
||||
case 'c':
|
||||
if (shellcmd != NULL)
|
||||
xfree(shellcmd);
|
||||
shellcmd = xstrdup(optarg);
|
||||
break;
|
||||
case 'd':
|
||||
flags |= IDENTIFY_HASDEFAULTS;
|
||||
break;
|
||||
@ -341,6 +347,9 @@ main(int argc, char **argv)
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (shellcmd != NULL && argc != 0)
|
||||
usage();
|
||||
|
||||
log_open_tty(debug_level);
|
||||
siginit();
|
||||
|
||||
@ -486,10 +495,16 @@ main(int argc, char **argv)
|
||||
}
|
||||
xfree(label);
|
||||
|
||||
if (prepare_cmd(&msg, &buf, &len, argc, argv) != 0)
|
||||
if (shellcmd != NULL) {
|
||||
msg = MSG_SHELL;
|
||||
buf = NULL;
|
||||
len = 0;
|
||||
} else if (prepare_cmd(&msg, &buf, &len, argc, argv) != 0)
|
||||
exit(1);
|
||||
|
||||
if (argc == 0) /* new-session is the default */
|
||||
if (shellcmd != NULL)
|
||||
cmdflags |= CMD_STARTSERVER;
|
||||
else if (argc == 0) /* new-session is the default */
|
||||
cmdflags |= CMD_STARTSERVER|CMD_SENDENVIRON;
|
||||
else {
|
||||
/*
|
||||
@ -538,7 +553,7 @@ main(int argc, char **argv)
|
||||
fatalx("socket error");
|
||||
|
||||
if (pfd.revents & POLLIN) {
|
||||
if (dispatch_imsg(&cctx, &retcode) != 0)
|
||||
if (dispatch_imsg(&cctx, shellcmd, &retcode) != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
@ -555,11 +570,12 @@ main(int argc, char **argv)
|
||||
}
|
||||
|
||||
int
|
||||
dispatch_imsg(struct client_ctx *cctx, int *retcode)
|
||||
dispatch_imsg(struct client_ctx *cctx, const char *shellcmd, int *retcode)
|
||||
{
|
||||
struct imsg imsg;
|
||||
ssize_t n, datalen;
|
||||
struct msg_print_data printdata;
|
||||
struct msg_shell_data shelldata;
|
||||
|
||||
if ((n = imsg_read(&cctx->ibuf)) == -1 || n == 0)
|
||||
fatalx("imsg_read failed");
|
||||
@ -603,6 +619,13 @@ dispatch_imsg(struct client_ctx *cctx, int *retcode)
|
||||
"server %u)", PROTOCOL_VERSION, imsg.hdr.peerid);
|
||||
*retcode = 1;
|
||||
return (-1);
|
||||
case MSG_SHELL:
|
||||
if (datalen != sizeof shelldata)
|
||||
fatalx("bad MSG_SHELL size");
|
||||
memcpy(&shelldata, imsg.data, sizeof shelldata);
|
||||
shelldata.shell[(sizeof shelldata.shell) - 1] = '\0';
|
||||
|
||||
shell_exec(shelldata.shell, shellcmd);
|
||||
default:
|
||||
fatalx("unexpected message");
|
||||
}
|
||||
@ -610,3 +633,26 @@ dispatch_imsg(struct client_ctx *cctx, int *retcode)
|
||||
imsg_free(&imsg);
|
||||
}
|
||||
}
|
||||
|
||||
__dead void
|
||||
shell_exec(const char *shell, const char *shellcmd)
|
||||
{
|
||||
const char *shellname, *ptr;
|
||||
char *argv0;
|
||||
|
||||
sigreset();
|
||||
|
||||
ptr = strrchr(shell, '/');
|
||||
if (ptr != NULL && *(ptr + 1) != '\0')
|
||||
shellname = ptr + 1;
|
||||
else
|
||||
shellname = shell;
|
||||
if (login_shell)
|
||||
xasprintf(&argv0, "-%s", shellname);
|
||||
else
|
||||
xasprintf(&argv0, "%s", shellname);
|
||||
setenv("SHELL", shell, 1);
|
||||
|
||||
execl(shell, argv0, "-c", shellcmd, (char *) NULL);
|
||||
fatal("execl failed");
|
||||
}
|
||||
|
Reference in New Issue
Block a user