Thanks - this looks much better, we can probably do something with this.

I guess this obviously won't let other things that need file descriptor
passing work like "loadb -" or "saveb -".

A few things:

Why do you need to dup stdin in the client?

Can you replace cyg_get_identify_fd by just putting the one line under
#ifdef WIN32?

Also cyg_add_identify_info doesn't need to be a helper function for just
one line.

You should probably fail early if isatty is false (before filling in
ttyname into the identify struct).

Please rename cyg_pty_path member to ttyname[]. It'll also need to be
TTY_NAME_MAX in size. If TTY_NAME_MAX isn't defined, you should define
it in compat.h.

Likewise the resolv.h change should go into compat.h. And why do you
need to define ECHOPRT?




On Fri, May 17, 2013 at 11:18:46PM -0500, J Raynor wrote:
>    I've found a better way to get tmux working on cygwin.* There's now no
>    need to modify tty.c to have separate read and write file descriptors.*
>    I've attached the new patch.
> 
>    On Wed, May 15, 2013 at 12:59 AM, J Raynor <[1]jxray...@gmail.com> wrote:
> 
>      Below is a patch for getting tmux running on cygwin.* I only have access
>      to a 32 bit XP system, so I don't know if it works on other versions of
>      Windows.* Cygwin doesn't provide a libevent package, so you'll first
>      have to install that.* I used libevent-2.0.21-stable.* Also, for tmux I
>      had to specify CFLAGS="-I/usr/include/ncurses" to configure or ncurses.h
>      won't be found during make.
> 
>      I didn't solve the general problem of passing file descriptors over a
>      socket.* Tmux is using a library to send messages, and it looks like
>      there's only 1 message type that needed to pass a descriptor.* So, I
>      added the necessary info to msg_identify on the sending side, and the
>      info is extracted and put to use before things continue on as normal on
>      the receiving side.
> 
>      Things weren't quite that easy, though.* There are 2 HANDLEs to the pty,
>      one for input and one for output.* Cygwin hides this, setting up stuff
>      under the hood so that 1 unix file descriptor can do both.* There
>      doesn't appear to be a way to set that up on the receiving side, so
>      instead of having 1 tty file descriptor that can be used for
>      input/output, I have to have 1 for input and 1 for output.* As a result,
>      all the writes in tty.c have to be changed to use the write file
>      descriptor.*
> 
>      I don't expect this patch to be integrated into tmux.* I just want to
>      get it out there and see if other people are interested in testing it or
>      improving it.* I believe I know how to add a function to cygwin to get
>      the 2 HANDLEs combined into 1 file descriptor, but I don't know if the
>      cygwin folks would accept it.* Plus, having people patch and build tmux
>      and cygwin seems to be asking a bit much as this stage.
> 
>      *** client.c.orig*** 2013-05-14 17:44:06.535685400 -0500
>      --- client.c*** 2013-05-14 19:43:41.305473500 -0500
>      ***************
>      *** 63,68 ****
>      --- 63,69 ----
>      * int*** *** client_dispatch_attached(void);
>      * int*** *** client_dispatch_wait(void *);
>      * const char**** *client_exit_message(void);
>      + void*** *** cyg_add_identify_info(struct msg_identify_data *, int);
>      *
>      * /*
>      ** * Get server create lock. If already held then server start is
>      happening in
>      ***************
>      *** 328,335 ****
>      * *** *** strlcpy(data.term, term, sizeof data.term) >= sizeof
>      data.term)
>      * *** *** *data.term = '\0';
>      *
>      ! *** if ((fd = dup(STDIN_FILENO)) == -1)
>      ! *** *** fatal("dup failed");
>      * *** imsg_compose(&client_ibuf,
>      * *** *** MSG_IDENTIFY, PROTOCOL_VERSION, -1, fd, &data, sizeof data);
>      * *** client_update_event();
>      --- 329,335 ----
>      * *** *** strlcpy(data.term, term, sizeof data.term) >= sizeof
>      data.term)
>      * *** *** *data.term = '\0';
>      *
>      ! *** cyg_add_identify_info(&data, STDIN_FILENO);
>      * *** imsg_compose(&client_ibuf,
>      * *** *** MSG_IDENTIFY, PROTOCOL_VERSION, -1, fd, &data, sizeof data);
>      * *** client_update_event();
>      ***************
>      *** 661,663 ****
>      --- 661,708 ----
>      * *** *** imsg_free(&imsg);
>      * *** }
>      * }
>      +
>      +
>      + #include <wtypes.h>
>      + #define CW_GET_INSTKEY 39** /* see cygwin.h */
>      +
>      + struct pipe_request {
>      + *** DWORD pid;
>      + };
>      +
>      + struct pipe_reply {
>      + *** HANDLE ttyin;
>      + *** HANDLE ttyout;
>      + *** DWORD error;
>      + };
>      +
>      + void
>      + cyg_add_identify_info(struct msg_identify_data *data, int fd)
>      + {
>      +
>      + *** char pipepath[256];
>      + *** WCHAR instkey[64];
>      + *** struct pipe_request req;
>      + *** struct pipe_reply repl;
>      + *** DWORD len;
>      +
>      + *** req.pid = GetCurrentProcessId();
>      +
>      + *** snprintf(&data->cyg_pty_path, sizeof(data->cyg_pty_path), "%s",
>      ttyname(fd));
>      + *** cygwin_internal(CW_GET_INSTKEY, &instkey);
>      +
>      + *** snprintf(&pipepath, sizeof(pipepath),
>      "\\\\.\\pipe\\cygwin-%ls-%s-master-ctl",
>      + *** *** &instkey, basename(data->cyg_pty_path));
>      +
>      + *** if(!CallNamedPipe(&pipepath, &req, sizeof req, &repl, sizeof repl,
>      &len, 500))
>      + *** *** fatal("CallNamedPipe failed");
>      +
>      +******** data->cyg_handle_ttyin = repl.ttyin;
>      +******** data->cyg_handle_ttyout = repl.ttyout;
>      +******** data->cyg_pid = req.pid;
>      +
>      + }
>      +
>      +
>      +
>      +
>      *** server-client.c.orig*** 2013-05-14 18:22:54.012432600 -0500
>      --- server-client.c*** 2013-05-14 19:48:16.030508700 -0500
>      ***************
>      *** 43,48 ****
>      --- 43,49 ----
>      * void*** server_client_msg_identify(
>      * *** *** struct client *, struct msg_identify_data *, int);
>      * void*** server_client_msg_shell(struct client *);
>      + void*** cyg_get_identify_fd(struct msg_identify_data *, struct imsg
>      *);
>      *
>      * /* Create a new client. */
>      * void
>      ***************
>      *** 823,831 ****
>      * *** *** case MSG_IDENTIFY:
>      * *** *** *** if (datalen != sizeof identifydata)
>      * *** *** *** *** fatalx("bad MSG_IDENTIFY size");
>      * *** *** *** if (imsg.fd == -1)
>      * *** *** *** *** fatalx("MSG_IDENTIFY missing fd");
>      - *** *** *** memcpy(&identifydata, imsg.data, sizeof identifydata);
>      *
>      * *** *** *** server_client_msg_identify(c, &identifydata, imsg.fd);
>      * *** *** *** break;
>      --- 824,833 ----
>      * *** *** case MSG_IDENTIFY:
>      * *** *** *** if (datalen != sizeof identifydata)
>      * *** *** *** *** fatalx("bad MSG_IDENTIFY size");
>      + *** *** *** memcpy(&identifydata, imsg.data, sizeof identifydata);
>      + *** *** *** cyg_get_identify_fd(&identifydata, &imsg);
>      * *** *** *** if (imsg.fd == -1)
>      * *** *** *** *** fatalx("MSG_IDENTIFY missing fd");
>      *
>      * *** *** *** server_client_msg_identify(c, &identifydata, imsg.fd);
>      * *** *** *** break;
>      ***************
>      *** 976,981 ****
>      --- 978,984 ----
>      * *** }
>      * *** data->term[(sizeof data->term) - 1] = '\0';
>      * *** tty_init(&c->tty, c, fd, data->term);
>      + *** c->tty.wfd = data->cyg_fd_ttyout;
>      * *** if (data->flags & IDENTIFY_UTF8)
>      * *** *** c->tty.flags |= TTY_UTF8;
>      * *** if (data->flags & IDENTIFY_256COLOURS)
>      ***************
>      *** 1006,1008 ****
>      --- 1009,1057 ----
>      * *** server_write_client(c, MSG_SHELL, &data, sizeof data);
>      * *** c->flags |= CLIENT_BAD;*** /* it will die after exec */
>      * }
>      +
>      +
>      + #include <wtypes.h>
>      + void
>      + cyg_get_identify_fd(struct msg_identify_data *data, struct imsg *imsg)
>      + {
>      +
>      +******** HANDLE hSRCproc, hSRCttyin, hSRCttyout, hTGTttyin, hTGTttyout;
>      +******** DWORD pid;
>      +******** int x, y;
>      +
>      +******** hSRCttyin = data->cyg_handle_ttyin;
>      +******** hSRCttyout = data->cyg_handle_ttyout;
>      +******** pid = data->cyg_pid;
>      +
>      +******** hSRCproc = OpenProcess(PROCESS_DUP_HANDLE, 1, pid);
>      +******** if(hSRCproc == NULL)
>      +**************** fatalx("OpenProcess failed");
>      +
>      +
>      +******** if(!DuplicateHandle(hSRCproc, hSRCttyin, GetCurrentProcess(),
>      + *** *** &hTGTttyin, 0, TRUE,
>      DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS))
>      + *** *** *** fatalx("DuplicatHandle failed for ttyin");
>      +
>      +******** if(!DuplicateHandle(hSRCproc, hSRCttyout, GetCurrentProcess(),
>      + *** *** &hTGTttyout, 0, TRUE,
>      DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS))
>      + *** *** *** fatalx("DuplicatHandle failed for ttyout");
>      +
>      +
>      +
>      + *** data->cyg_fd_ttyin =
>      cygwin_attach_handle_to_fd(data->cyg_pty_path, -1, hTGTttyin, 1,
>      GENERIC_READ|GENERIC_WRITE);
>      + *** data->cyg_fd_ttyout = cygwin_attach_handle_to_fd("dummy", -1,
>      hTGTttyout, 1, GENERIC_READ|GENERIC_WRITE);
>      +
>      + *** if(data->cyg_fd_ttyin < 0)
>      + *** *** fatalx("cygwin_attach_handle_to_fd failed for ttyin");
>      +
>      + *** if(data->cyg_fd_ttyout < 0)
>      + *** *** fatalx("cygwin_attach_handle_to_fd failed for ttyout");
>      +
>      + *** imsg->fd = data->cyg_fd_ttyin;
>      +
>      +
>      + }
>      +
>      +
>      +
>      *** tmux.h.orig*** 2013-05-14 17:24:47.819533400 -0500
>      --- tmux.h*** 2013-05-14 19:44:57.304755100 -0500
>      ***************
>      *** 470,480 ****
>      --- 470,489 ----
>      * *** char*** *** argv[COMMAND_LENGTH];
>      * };
>      *
>      + typedef ulong DWORD;*** /* including wtypes.h in tmux.h causes
>      compilation problems */
>      + typedef void *HANDLE;*** /* in some files, so use typedefs here to
>      avoid that*/
>      * struct msg_identify_data {
>      * *** char*** *** cwd[MAXPATHLEN];
>      *
>      * *** char*** *** term[TERMINAL_LENGTH];
>      *
>      + *** HANDLE*** *** cyg_handle_ttyin;
>      + *** HANDLE*** *** cyg_handle_ttyout;
>      + *** DWORD*** *** cyg_pid;
>      + *** int*** *** cyg_fd_ttyin;
>      + *** int*** *** cyg_fd_ttyout;
>      + *** char*** *** cyg_pty_path[16];
>      +
>      * #define IDENTIFY_UTF8 0x1
>      * #define IDENTIFY_256COLOURS 0x2
>      * #define IDENTIFY_88COLOURS 0x4
>      ***************
>      *** 1216,1222 ****
>      --- 1225,1234 ----
>      * *** struct tty_term*** *term;
>      *
>      * *** int*** *** *fd;
>      + *** int*** *** *wfd;
>      +
>      * *** struct bufferevent *event;
>      + *** struct bufferevent *wevent;
>      *
>      * *** int*** *** *log_fd;
>      *
>      *** tty.c.orig*** 2013-05-14 17:31:28.525720600 -0500
>      --- tty.c*** 2013-05-14 17:40:35.452162200 -0500
>      ***************
>      *** 23,35 ****
>      *
>      * #include <errno.h>
>      * #include <fcntl.h>
>      ! #include <resolv.h>
>      * #include <stdlib.h>
>      * #include <string.h>
>      * #include <termios.h>
>      * #include <unistd.h>
>      *
>      * #include "tmux.h"
>      *
>      * void*** tty_read_callback(struct bufferevent *, void *);
>      * void*** tty_error_callback(struct bufferevent *, short, void *);
>      --- 23,36 ----
>      *
>      * #include <errno.h>
>      * #include <fcntl.h>
>      ! //#include <resolv.h>
>      * #include <stdlib.h>
>      * #include <string.h>
>      * #include <termios.h>
>      * #include <unistd.h>
>      *
>      * #include "tmux.h"
>      + #define ECHOPRT******** 0x00000020***** /* visual erase mode for
>      hardcopy */
>      *
>      * void*** tty_read_callback(struct bufferevent *, void *);
>      * void*** tty_error_callback(struct bufferevent *, short, void *);
>      ***************
>      *** 154,159 ****
>      --- 155,163 ----
>      * *** tty->event = bufferevent_new(
>      * *** *** tty->fd, tty_read_callback, NULL, tty_error_callback, tty);
>      *
>      + *** tty->wevent = bufferevent_new(
>      + *** *** tty->wfd, NULL, NULL, tty_error_callback, tty);
>      +
>      * *** tty_start_tty(tty);
>      *
>      * *** tty_keys_build(tty);
>      ***************
>      *** 305,310 ****
>      --- 309,315 ----
>      *
>      * *** if (tty->flags & TTY_OPENED) {
>      * *** *** bufferevent_free(tty->event);
>      + *** *** bufferevent_free(tty->wevent);
>      *
>      * *** *** tty_term_free(tty->term);
>      * *** *** tty_keys_free(tty);
>      ***************
>      *** 314,320 ****
>      --- 319,327 ----
>      *
>      * *** if (tty->fd != -1) {
>      * *** *** close(tty->fd);
>      + *** *** close(tty->wfd);
>      * *** *** tty->fd = -1;
>      + *** *** tty->wfd = -1;
>      * *** }
>      * }
>      *
>      ***************
>      *** 338,344 ****
>      *
>      * *** slen = strlen(s);
>      * *** for (i = 0; i < 5; i++) {
>      ! *** *** n = write(tty->fd, s, slen);
>      * *** *** if (n >= 0) {
>      * *** *** *** s += n;
>      * *** *** *** slen -= n;
>      --- 345,351 ----
>      *
>      * *** slen = strlen(s);
>      * *** for (i = 0; i < 5; i++) {
>      ! *** *** n = write(tty->wfd, s, slen);
>      * *** *** if (n >= 0) {
>      * *** *** *** s += n;
>      * *** *** *** slen -= n;
>      ***************
>      *** 391,397 ****
>      * {
>      * *** if (*s == '\0')
>      * *** *** return;
>      ! *** bufferevent_write(tty->event, s, strlen(s));
>      *
>      * *** if (tty->log_fd != -1)
>      * *** *** write(tty->log_fd, s, strlen(s));
>      --- 398,404 ----
>      * {
>      * *** if (*s == '\0')
>      * *** *** return;
>      ! *** bufferevent_write(tty->wevent, s, strlen(s));
>      *
>      * *** if (tty->log_fd != -1)
>      * *** *** write(tty->log_fd, s, strlen(s));
>      ***************
>      *** 406,416 ****
>      * *** if (tty->cell.attr & GRID_ATTR_CHARSET) {
>      * *** *** acs = tty_acs_get(tty, ch);
>      * *** *** if (acs != NULL)
>      ! *** *** *** bufferevent_write(tty->event, acs, strlen(acs));
>      * *** *** else
>      ! *** *** *** bufferevent_write(tty->event, &ch, 1);
>      * *** } else
>      ! *** *** bufferevent_write(tty->event, &ch, 1);
>      *
>      * *** if (ch >= 0x20 && ch != 0x7f) {
>      * *** *** sx = tty->sx;
>      --- 413,423 ----
>      * *** if (tty->cell.attr & GRID_ATTR_CHARSET) {
>      * *** *** acs = tty_acs_get(tty, ch);
>      * *** *** if (acs != NULL)
>      ! *** *** *** bufferevent_write(tty->wevent, acs, strlen(acs));
>      * *** *** else
>      ! *** *** *** bufferevent_write(tty->wevent, &ch, 1);
>      * *** } else
>      ! *** *** bufferevent_write(tty->wevent, &ch, 1);
>      *
>      * *** if (ch >= 0x20 && ch != 0x7f) {
>      * *** *** sx = tty->sx;
>      ***************
>      *** 432,438 ****
>      * void
>      * tty_putn(struct tty *tty, const void *buf, size_t len, u_int width)
>      * {
>      ! *** bufferevent_write(tty->event, buf, len);
>      * *** if (tty->log_fd != -1)
>      * *** *** write(tty->log_fd, buf, len);
>      * *** tty->cx += width;
>      --- 439,445 ----
>      * void
>      * tty_putn(struct tty *tty, const void *buf, size_t len, u_int width)
>      * {
>      ! *** bufferevent_write(tty->wevent, buf, len);
>      * *** if (tty->log_fd != -1)
>      * *** *** write(tty->log_fd, buf, len);
>      * *** tty->cx += width;
> 
> References
> 
>    Visible links
>    1. mailto:jxray...@gmail.com


> ------------------------------------------------------------------------------
> AlienVault Unified Security Management (USM) platform delivers complete
> security visibility with the essential security capabilities. Easily and
> efficiently configure, manage, and operate all of your security controls
> from a single console and one unified framework. Download a free trial.
> http://p.sf.net/sfu/alienvault_d2d

> _______________________________________________
> tmux-users mailing list
> tmux-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/tmux-users


------------------------------------------------------------------------------
AlienVault Unified Security Management (USM) platform delivers complete
security visibility with the essential security capabilities. Easily and
efficiently configure, manage, and operate all of your security controls
from a single console and one unified framework. Download a free trial.
http://p.sf.net/sfu/alienvault_d2d
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to