mirror of
https://github.com/tmate-io/tmate.git
synced 2024-12-23 23:29:15 +01:00
Sync OpenBSD patchset 731:
Send all three of stdin, stdout, stderr from the client to the server, so that commands can directly make use of them. This means that load-buffer and save-buffer can have "-" as the file to read from stdin or write to stdout. This is a protocol version bump so the tmux server will need to be restarted after upgrade (or an older client used).
This commit is contained in:
parent
63e76b555d
commit
e4573de97b
13
client.c
13
client.c
@ -1,4 +1,4 @@
|
||||
/* $Id: client.c,v 1.94 2010-06-06 00:30:34 tcunha Exp $ */
|
||||
/* $Id: client.c,v 1.95 2010-07-02 02:52:13 tcunha Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -100,8 +100,7 @@ server_started:
|
||||
|
||||
if (cmdflags & CMD_SENDENVIRON)
|
||||
client_send_environ();
|
||||
if (isatty(STDIN_FILENO))
|
||||
client_send_identify(flags);
|
||||
client_send_identify(flags);
|
||||
|
||||
return (&client_ibuf);
|
||||
|
||||
@ -135,6 +134,14 @@ client_send_identify(int flags)
|
||||
fatal("dup failed");
|
||||
imsg_compose(&client_ibuf,
|
||||
MSG_IDENTIFY, PROTOCOL_VERSION, -1, fd, &data, sizeof data);
|
||||
|
||||
if ((fd = dup(STDOUT_FILENO)) == -1)
|
||||
fatal("dup failed");
|
||||
imsg_compose(&client_ibuf, MSG_STDOUT, PROTOCOL_VERSION, -1, fd, NULL, 0);
|
||||
|
||||
if ((fd = dup(STDERR_FILENO)) == -1)
|
||||
fatal("dup failed");
|
||||
imsg_compose(&client_ibuf, MSG_STDERR, PROTOCOL_VERSION, -1, fd, NULL, 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: cmd-load-buffer.c,v 1.15 2010-02-26 13:30:07 tcunha Exp $ */
|
||||
/* $Id: cmd-load-buffer.c,v 1.16 2010-07-02 02:52:13 tcunha Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
|
||||
@ -16,10 +16,13 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
@ -45,7 +48,7 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||
{
|
||||
struct cmd_buffer_data *data = self->data;
|
||||
struct session *s;
|
||||
FILE *f;
|
||||
FILE *f, *close_f;
|
||||
char *pdata, *new_pdata;
|
||||
size_t psize;
|
||||
u_int limit;
|
||||
@ -54,9 +57,23 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||
if ((s = cmd_find_session(ctx, data->target)) == NULL)
|
||||
return (-1);
|
||||
|
||||
if ((f = fopen(data->arg, "rb")) == NULL) {
|
||||
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
|
||||
return (-1);
|
||||
if (strcmp(data->arg, "-") == 0 ) {
|
||||
if (ctx->cmdclient == NULL) {
|
||||
ctx->error(ctx, "%s: can't read from stdin", data->arg);
|
||||
return (-1);
|
||||
}
|
||||
f = ctx->cmdclient->stdin_file;
|
||||
if (isatty(fileno(ctx->cmdclient->stdin_file))) {
|
||||
ctx->error(ctx, "%s: stdin is a tty", data->arg);
|
||||
return (-1);
|
||||
}
|
||||
close_f = NULL;
|
||||
} else {
|
||||
if ((f = fopen(data->arg, "rb")) == NULL) {
|
||||
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
close_f = f;
|
||||
}
|
||||
|
||||
pdata = NULL;
|
||||
@ -77,7 +94,8 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||
if (pdata != NULL)
|
||||
pdata[psize] = '\0';
|
||||
|
||||
fclose(f);
|
||||
if (close_f != NULL)
|
||||
fclose(close_f);
|
||||
|
||||
limit = options_get_number(&s->options, "buffer-limit");
|
||||
if (data->buffer == -1) {
|
||||
@ -94,6 +112,7 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||
error:
|
||||
if (pdata != NULL)
|
||||
xfree(pdata);
|
||||
fclose(f);
|
||||
if (close_f != NULL)
|
||||
fclose(close_f);
|
||||
return (-1);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: cmd-save-buffer.c,v 1.10 2009-11-14 17:56:39 tcunha Exp $ */
|
||||
/* $Id: cmd-save-buffer.c,v 1.11 2010-07-02 02:52:13 tcunha Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
|
||||
@ -48,7 +48,7 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||
struct session *s;
|
||||
struct paste_buffer *pb;
|
||||
mode_t mask;
|
||||
FILE *f;
|
||||
FILE *f, *close_f;
|
||||
|
||||
if ((s = cmd_find_session(ctx, data->target)) == NULL)
|
||||
return (-1);
|
||||
@ -65,15 +65,25 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
mask = umask(S_IRWXG | S_IRWXO);
|
||||
if (cmd_check_flag(data->chflags, 'a'))
|
||||
f = fopen(data->arg, "ab");
|
||||
else
|
||||
f = fopen(data->arg, "wb");
|
||||
umask(mask);
|
||||
if (f == NULL) {
|
||||
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
|
||||
return (-1);
|
||||
if (strcmp(data->arg, "-") == 0) {
|
||||
if (ctx->cmdclient == NULL) {
|
||||
ctx->error(ctx, "%s: can't write to stdout", data->arg);
|
||||
return (-1);
|
||||
}
|
||||
f = ctx->cmdclient->stdout_file;
|
||||
close_f = NULL;
|
||||
} else {
|
||||
mask = umask(S_IRWXG | S_IRWXO);
|
||||
if (cmd_check_flag(data->chflags, 'a'))
|
||||
f = fopen(data->arg, "ab");
|
||||
else
|
||||
f = fopen(data->arg, "wb");
|
||||
umask(mask);
|
||||
if (f == NULL) {
|
||||
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
close_f = f;
|
||||
}
|
||||
|
||||
if (fwrite(pb->data, 1, pb->size, f) != pb->size) {
|
||||
@ -82,7 +92,8 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
if (close_f != NULL)
|
||||
fclose(close_f);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: server-client.c,v 1.33 2010-06-06 00:30:34 tcunha Exp $ */
|
||||
/* $Id: server-client.c,v 1.34 2010-07-02 02:52:13 tcunha Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -68,6 +68,10 @@ server_client_create(int fd)
|
||||
|
||||
ARRAY_INIT(&c->prompt_hdata);
|
||||
|
||||
c->stdin_file = NULL;
|
||||
c->stdout_file = NULL;
|
||||
c->stderr_file = NULL;
|
||||
|
||||
c->tty.fd = -1;
|
||||
c->title = NULL;
|
||||
|
||||
@ -117,6 +121,13 @@ server_client_lost(struct client *c)
|
||||
if (c->flags & CLIENT_TERMINAL)
|
||||
tty_free(&c->tty);
|
||||
|
||||
if (c->stdin_file != NULL)
|
||||
fclose(c->stdin_file);
|
||||
if (c->stdout_file != NULL)
|
||||
fclose(c->stdout_file);
|
||||
if (c->stderr_file != NULL)
|
||||
fclose(c->stderr_file);
|
||||
|
||||
screen_free(&c->status);
|
||||
job_tree_free(&c->status_jobs);
|
||||
|
||||
@ -554,8 +565,31 @@ server_client_msg_dispatch(struct client *c)
|
||||
fatalx("MSG_IDENTIFY missing fd");
|
||||
memcpy(&identifydata, imsg.data, sizeof identifydata);
|
||||
|
||||
c->stdin_file = fdopen(imsg.fd, "r");
|
||||
if (c->stdin_file == NULL)
|
||||
fatal("fdopen(stdin) failed");
|
||||
server_client_msg_identify(c, &identifydata, imsg.fd);
|
||||
break;
|
||||
case MSG_STDOUT:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_STDOUT size");
|
||||
if (imsg.fd == -1)
|
||||
fatalx("MSG_STDOUT missing fd");
|
||||
|
||||
c->stdout_file = fdopen(imsg.fd, "w");
|
||||
if (c->stdout_file == NULL)
|
||||
fatal("fdopen(stdout) failed");
|
||||
break;
|
||||
case MSG_STDERR:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_STDERR size");
|
||||
if (imsg.fd == -1)
|
||||
fatalx("MSG_STDERR missing fd");
|
||||
|
||||
c->stderr_file = fdopen(imsg.fd, "w");
|
||||
if (c->stderr_file == NULL)
|
||||
fatal("fdopen(stderr) failed");
|
||||
break;
|
||||
case MSG_RESIZE:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_RESIZE size");
|
||||
@ -621,45 +655,45 @@ server_client_msg_dispatch(struct client *c)
|
||||
void printflike2
|
||||
server_client_msg_error(struct cmd_ctx *ctx, const char *fmt, ...)
|
||||
{
|
||||
struct msg_print_data data;
|
||||
va_list ap;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
xvsnprintf(data.msg, sizeof data.msg, fmt, ap);
|
||||
vfprintf(ctx->cmdclient->stderr_file, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
server_write_client(ctx->cmdclient, MSG_ERROR, &data, sizeof data);
|
||||
fputc('\n', ctx->cmdclient->stderr_file);
|
||||
fflush(ctx->cmdclient->stderr_file);
|
||||
}
|
||||
|
||||
/* Callback to send print message to client. */
|
||||
void printflike2
|
||||
server_client_msg_print(struct cmd_ctx *ctx, const char *fmt, ...)
|
||||
{
|
||||
struct msg_print_data data;
|
||||
va_list ap;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
xvsnprintf(data.msg, sizeof data.msg, fmt, ap);
|
||||
vfprintf(ctx->cmdclient->stdout_file, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
server_write_client(ctx->cmdclient, MSG_PRINT, &data, sizeof data);
|
||||
fputc('\n', ctx->cmdclient->stdout_file);
|
||||
fflush(ctx->cmdclient->stdout_file);
|
||||
}
|
||||
|
||||
/* Callback to send print message to client, if not quiet. */
|
||||
void printflike2
|
||||
server_client_msg_info(struct cmd_ctx *ctx, const char *fmt, ...)
|
||||
{
|
||||
struct msg_print_data data;
|
||||
va_list ap;
|
||||
va_list ap;
|
||||
|
||||
if (options_get_number(&global_options, "quiet"))
|
||||
return;
|
||||
|
||||
va_start(ap, fmt);
|
||||
xvsnprintf(data.msg, sizeof data.msg, fmt, ap);
|
||||
vfprintf(ctx->cmdclient->stdout_file, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
server_write_client(ctx->cmdclient, MSG_PRINT, &data, sizeof data);
|
||||
fputc('\n', ctx->cmdclient->stderr_file);
|
||||
fflush(ctx->cmdclient->stdout_file);
|
||||
}
|
||||
|
||||
/* Handle command message. */
|
||||
@ -716,13 +750,19 @@ void
|
||||
server_client_msg_identify(
|
||||
struct client *c, struct msg_identify_data *data, int fd)
|
||||
{
|
||||
int tty_fd;
|
||||
|
||||
c->cwd = NULL;
|
||||
data->cwd[(sizeof data->cwd) - 1] = '\0';
|
||||
if (*data->cwd != '\0')
|
||||
c->cwd = xstrdup(data->cwd);
|
||||
|
||||
if (!isatty(fd))
|
||||
return;
|
||||
if ((tty_fd = dup(fd)) == -1)
|
||||
fatal("dup failed");
|
||||
data->term[(sizeof data->term) - 1] = '\0';
|
||||
tty_init(&c->tty, fd, data->term);
|
||||
tty_init(&c->tty, tty_fd, data->term);
|
||||
if (data->flags & IDENTIFY_UTF8)
|
||||
c->tty.flags |= TTY_UTF8;
|
||||
if (data->flags & IDENTIFY_256COLOURS)
|
||||
|
14
tmux.c
14
tmux.c
@ -1,4 +1,4 @@
|
||||
/* $Id: tmux.c,v 1.212 2010-07-02 02:49:19 tcunha Exp $ */
|
||||
/* $Id: tmux.c,v 1.213 2010-07-02 02:52:13 tcunha Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -613,7 +613,6 @@ main_dispatch(const char *shellcmd)
|
||||
{
|
||||
struct imsg imsg;
|
||||
ssize_t n, datalen;
|
||||
struct msg_print_data printdata;
|
||||
struct msg_shell_data shelldata;
|
||||
|
||||
if ((n = imsg_read(main_ibuf)) == -1 || n == 0)
|
||||
@ -633,17 +632,6 @@ main_dispatch(const char *shellcmd)
|
||||
fatalx("bad MSG_EXIT size");
|
||||
|
||||
exit(main_exitval);
|
||||
case MSG_ERROR:
|
||||
case MSG_PRINT:
|
||||
if (datalen != sizeof printdata)
|
||||
fatalx("bad MSG_PRINT size");
|
||||
memcpy(&printdata, imsg.data, sizeof printdata);
|
||||
printdata.msg[(sizeof printdata.msg) - 1] = '\0';
|
||||
|
||||
log_info("%s", printdata.msg);
|
||||
if (imsg.hdr.type == MSG_ERROR)
|
||||
main_exitval = 1;
|
||||
break;
|
||||
case MSG_READY:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_READY size");
|
||||
|
17
tmux.h
17
tmux.h
@ -1,4 +1,4 @@
|
||||
/* $Id: tmux.h,v 1.566 2010-07-02 02:49:19 tcunha Exp $ */
|
||||
/* $Id: tmux.h,v 1.567 2010-07-02 02:52:13 tcunha Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -21,7 +21,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define PROTOCOL_VERSION 5
|
||||
#define PROTOCOL_VERSION 6
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
@ -67,7 +67,6 @@ extern char **environ;
|
||||
*/
|
||||
#define COMMAND_LENGTH 2048 /* packed argv size */
|
||||
#define TERMINAL_LENGTH 128 /* length of TERM environment variable */
|
||||
#define PRINT_LENGTH 512 /* printed error/message size */
|
||||
#define ENVIRON_LENGTH 1024 /* environment variable length */
|
||||
|
||||
/*
|
||||
@ -372,7 +371,9 @@ enum msgtype {
|
||||
MSG_ENVIRON,
|
||||
MSG_UNLOCK,
|
||||
MSG_LOCK,
|
||||
MSG_SHELL
|
||||
MSG_SHELL,
|
||||
MSG_STDERR,
|
||||
MSG_STDOUT,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -380,10 +381,6 @@ enum msgtype {
|
||||
*
|
||||
* Don't forget to bump PROTOCOL_VERSION if any of these change!
|
||||
*/
|
||||
struct msg_print_data {
|
||||
char msg[PRINT_LENGTH];
|
||||
};
|
||||
|
||||
struct msg_command_data {
|
||||
pid_t pid; /* pid from $TMUX or -1 */
|
||||
u_int idx; /* index from $TMUX */
|
||||
@ -1079,6 +1076,10 @@ struct client {
|
||||
char *cwd;
|
||||
|
||||
struct tty tty;
|
||||
FILE *stdin_file;
|
||||
FILE *stdout_file;
|
||||
FILE *stderr_file;
|
||||
|
||||
struct event repeat_timer;
|
||||
|
||||
struct timeval status_timer;
|
||||
|
Loading…
Reference in New Issue
Block a user