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 ------------------------------------------------------------------------------ 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