I've added the patch as an attachment since it seems it was garbled the first time.
On Wed, May 15, 2013 at 1:32 AM, Nicholas Marriott < nicholas.marri...@gmail.com> wrote: > Hi > > Your mailer has mangled the patch, can you attach it? > > > On Wed, May 15, 2013 at 12:59:56AM -0500, J Raynor 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; > > > > ------------------------------------------------------------------------------ > > 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 > >
tmux-cygwin.patch
Description: Binary data
------------------------------------------------------------------------------ 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