mirror of
https://github.com/tmux/tmux.git
synced 2024-12-04 19:58:48 +00:00
Pass terminal data on socket on Cygwin platforms
On Cygwin and MSYS2 use a controlling pty for the server client handler instead of passing a file descriptor over the socket which is not possible on Cygwin platforms. Attach an event to STDIN on the client, passing data from it to the server and attach an event to the pty out_fd on the server client handler and pass data from it to the client. Signed-off-by: Rafael Kitover <rkitover@gmail.com>
This commit is contained in:
parent
8d6eb4be40
commit
80e6621298
14
client.c
14
client.c
@ -244,6 +244,9 @@ client_main(struct event_base *base, int argc, char **argv, uint64_t flags,
|
||||
char *line = NULL, **caps = NULL, *cause;
|
||||
u_int ncaps = 0;
|
||||
struct args_value *values;
|
||||
#ifdef TTY_OVER_SOCKET
|
||||
struct tty* tty = xmalloc(sizeof *tty);
|
||||
#endif
|
||||
|
||||
/* Set up the initial command. */
|
||||
if (shell_command != NULL) {
|
||||
@ -397,6 +400,10 @@ client_main(struct event_base *base, int argc, char **argv, uint64_t flags,
|
||||
} else if (msg == MSG_SHELL)
|
||||
proc_send(client_peer, msg, -1, NULL, 0);
|
||||
|
||||
#ifdef TTY_OVER_SOCKET
|
||||
tty_attach_stdin_to_socket(tty, client_peer);
|
||||
#endif
|
||||
|
||||
/* Start main loop. */
|
||||
proc_loop(client_proc, NULL);
|
||||
|
||||
@ -474,12 +481,14 @@ client_send_identify(const char *ttynam, const char *termname, char **caps,
|
||||
caps[i], strlen(caps[i]) + 1);
|
||||
}
|
||||
|
||||
#ifndef TTY_OVER_SOCKET
|
||||
if ((fd = dup(STDIN_FILENO)) == -1)
|
||||
fatal("dup failed");
|
||||
proc_send(client_peer, MSG_IDENTIFY_STDIN, fd, NULL, 0);
|
||||
if ((fd = dup(STDOUT_FILENO)) == -1)
|
||||
fatal("dup failed");
|
||||
proc_send(client_peer, MSG_IDENTIFY_STDOUT, fd, NULL, 0);
|
||||
#endif
|
||||
|
||||
pid = getpid();
|
||||
proc_send(client_peer, MSG_IDENTIFY_CLIENTPID, -1, &pid, sizeof pid);
|
||||
@ -805,5 +814,10 @@ client_dispatch_attached(struct imsg *imsg)
|
||||
system(data);
|
||||
proc_send(client_peer, MSG_UNLOCK, -1, NULL, 0);
|
||||
break;
|
||||
#ifdef TTY_OVER_SOCKET
|
||||
case MSG_TTY_READ:
|
||||
write(STDOUT_FILENO, data, datalen);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
5
compat.h
5
compat.h
@ -69,6 +69,11 @@
|
||||
#define __weak __attribute__ ((__weak__))
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MSYS__)
|
||||
#define WIN32_PLATFORM
|
||||
#define TTY_OVER_SOCKET
|
||||
#endif
|
||||
|
||||
#ifndef ECHOPRT
|
||||
#define ECHOPRT 0
|
||||
#endif
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
@ -2898,6 +2899,11 @@ server_client_dispatch(struct imsg *imsg, void *arg)
|
||||
case MSG_READ_DONE:
|
||||
file_read_done(&c->files, imsg);
|
||||
break;
|
||||
#ifdef TTY_OVER_SOCKET
|
||||
case MSG_TTY_WRITE:
|
||||
write(c->fd, imsg->data, datalen);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -3069,6 +3075,7 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
|
||||
c->cwd = xstrdup("/");
|
||||
log_debug("client %p IDENTIFY_CWD %s", c, data);
|
||||
break;
|
||||
#ifndef TTY_OVER_SOCKET
|
||||
case MSG_IDENTIFY_STDIN:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_IDENTIFY_STDIN size");
|
||||
@ -3081,6 +3088,7 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
|
||||
c->out_fd = imsg_get_fd(imsg);
|
||||
log_debug("client %p IDENTIFY_STDOUT %d", c, c->out_fd);
|
||||
break;
|
||||
#endif
|
||||
case MSG_IDENTIFY_ENVIRON:
|
||||
if (datalen == 0 || data[datalen - 1] != '\0')
|
||||
fatalx("bad MSG_IDENTIFY_ENVIRON string");
|
||||
@ -3109,8 +3117,8 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
|
||||
c->name = name;
|
||||
log_debug("client %p name is %s", c, c->name);
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
c->fd = open(c->ttyname, O_RDWR|O_NOCTTY);
|
||||
#ifdef TTY_OVER_SOCKET
|
||||
c->fd = open("/dev/ptmx", O_RDWR|O_NOCTTY);
|
||||
c->out_fd = dup(c->fd);
|
||||
#endif
|
||||
|
||||
|
@ -68,6 +68,11 @@ enum msgtype {
|
||||
MSG_WRITE_READY,
|
||||
MSG_WRITE_CLOSE,
|
||||
MSG_READ_CANCEL
|
||||
#ifdef TTY_OVER_SOCKET
|
||||
,
|
||||
MSG_TTY_READ,
|
||||
MSG_TTY_WRITE
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
|
5
tmux.h
5
tmux.h
@ -2461,6 +2461,11 @@ void tty_cmd_sixelimage(struct tty *, const struct tty_ctx *);
|
||||
void tty_cmd_syncstart(struct tty *, const struct tty_ctx *);
|
||||
void tty_default_colours(struct grid_cell *, struct window_pane *);
|
||||
|
||||
#ifdef TTY_OVER_SOCKET
|
||||
int tty_attach_stdin_to_socket(struct tty *, struct tmuxpeer *);
|
||||
int tty_attach_out_to_socket(struct tty *, struct client *);
|
||||
#endif
|
||||
|
||||
/* tty-term.c */
|
||||
extern struct tty_terms tty_terms;
|
||||
u_int tty_term_ncodes(void);
|
||||
|
39
tty.c
39
tty.c
@ -250,6 +250,11 @@ tty_write_callback(__unused int fd, __unused short events, void *data)
|
||||
struct client *c = tty->client;
|
||||
size_t size = EVBUFFER_LENGTH(tty->out);
|
||||
int nwrite;
|
||||
#ifdef TTY_OVER_SOCKET
|
||||
enum msgtype msg = MSG_TTY_READ;
|
||||
|
||||
proc_send(c->peer, msg, -1, EVBUFFER_DATA(tty->out), size);
|
||||
#endif
|
||||
|
||||
nwrite = evbuffer_write(tty->out, c->fd);
|
||||
if (nwrite == -1)
|
||||
@ -304,6 +309,40 @@ tty_open(struct tty *tty, char **cause)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef TTY_OVER_SOCKET
|
||||
static struct tmuxpeer *client_peer;
|
||||
|
||||
static void
|
||||
tty_stdin_socket_callback(int fd, __unused short events, void *data)
|
||||
{
|
||||
struct tty *tty = data;
|
||||
int nread;
|
||||
enum msgtype msg = MSG_TTY_WRITE;
|
||||
|
||||
nread = evbuffer_read(tty->in, fd, -1);
|
||||
if (nread == 0 || nread == -1) {
|
||||
event_del(&tty->event_in);
|
||||
return;
|
||||
}
|
||||
|
||||
proc_send(client_peer, msg, -1, EVBUFFER_DATA(tty->in), nread);
|
||||
}
|
||||
|
||||
int
|
||||
tty_attach_stdin_to_socket(struct tty *tty, struct tmuxpeer *peer)
|
||||
{
|
||||
client_peer = peer;
|
||||
|
||||
event_set(&tty->event_in, STDIN_FILENO, EV_PERSIST|EV_READ,
|
||||
tty_stdin_socket_callback, tty);
|
||||
tty->in = evbuffer_new();
|
||||
if (tty->in == NULL)
|
||||
fatal("out of memory");
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
tty_start_timer_callback(__unused int fd, __unused short events, void *data)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user