summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/tmux/client.c13
-rw-r--r--usr.bin/tmux/cmd-load-buffer.c33
-rw-r--r--usr.bin/tmux/cmd-save-buffer.c35
-rw-r--r--usr.bin/tmux/server-client.c68
-rw-r--r--usr.bin/tmux/tmux.c14
-rw-r--r--usr.bin/tmux/tmux.h17
6 files changed, 123 insertions, 57 deletions
diff --git a/usr.bin/tmux/client.c b/usr.bin/tmux/client.c
index 66a85dcd8f8..943f5bbac61 100644
--- a/usr.bin/tmux/client.c
+++ b/usr.bin/tmux/client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: client.c,v 1.41 2010/06/05 16:47:11 nicm Exp $ */
+/* $OpenBSD: client.c,v 1.42 2010/06/28 22:10:42 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -96,8 +96,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);
@@ -131,6 +130,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
diff --git a/usr.bin/tmux/cmd-load-buffer.c b/usr.bin/tmux/cmd-load-buffer.c
index 47f7d441886..745ebbe5ce2 100644
--- a/usr.bin/tmux/cmd-load-buffer.c
+++ b/usr.bin/tmux/cmd-load-buffer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-load-buffer.c,v 1.11 2010/02/22 20:33:12 nicm Exp $ */
+/* $OpenBSD: cmd-load-buffer.c,v 1.12 2010/06/28 22:10:42 nicm 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);
}
diff --git a/usr.bin/tmux/cmd-save-buffer.c b/usr.bin/tmux/cmd-save-buffer.c
index 3d6fbbedc5d..d25f1402f12 100644
--- a/usr.bin/tmux/cmd-save-buffer.c
+++ b/usr.bin/tmux/cmd-save-buffer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-save-buffer.c,v 1.6 2009/11/13 19:53:29 nicm Exp $ */
+/* $OpenBSD: cmd-save-buffer.c,v 1.7 2010/06/28 22:10:42 nicm 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);
}
diff --git a/usr.bin/tmux/server-client.c b/usr.bin/tmux/server-client.c
index 3271d9f37bb..d1abbf5dad8 100644
--- a/usr.bin/tmux/server-client.c
+++ b/usr.bin/tmux/server-client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server-client.c,v 1.32 2010/06/05 16:47:11 nicm Exp $ */
+/* $OpenBSD: server-client.c,v 1.33 2010/06/28 22:10:42 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -69,6 +69,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;
@@ -118,6 +122,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);
@@ -555,8 +566,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");
@@ -622,45 +656,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. */
@@ -717,13 +751,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)
diff --git a/usr.bin/tmux/tmux.c b/usr.bin/tmux/tmux.c
index c72be02927b..9f80e5a0b7d 100644
--- a/usr.bin/tmux/tmux.c
+++ b/usr.bin/tmux/tmux.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.c,v 1.82 2010/06/27 02:56:59 nicm Exp $ */
+/* $OpenBSD: tmux.c,v 1.83 2010/06/28 22:10:42 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -596,7 +596,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)
@@ -616,17 +615,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");
diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h
index 0767b4acf6d..fae4023fe27 100644
--- a/usr.bin/tmux/tmux.h
+++ b/usr.bin/tmux/tmux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.230 2010/06/27 02:56:59 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.231 2010/06/28 22:10:42 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -19,7 +19,7 @@
#ifndef TMUX_H
#define TMUX_H
-#define PROTOCOL_VERSION 5
+#define PROTOCOL_VERSION 6
#include <sys/param.h>
#include <sys/time.h>
@@ -68,7 +68,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 */
/*
@@ -373,7 +372,9 @@ enum msgtype {
MSG_ENVIRON,
MSG_UNLOCK,
MSG_LOCK,
- MSG_SHELL
+ MSG_SHELL,
+ MSG_STDERR,
+ MSG_STDOUT,
};
/*
@@ -381,10 +382,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 */
@@ -1080,6 +1077,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;