Patch 7.4.1318
Problem: Channel with pipes doesn't work in GUI.
Solution: Register input handlers for pipes.
Files: src/structs.h, src/feature.h, src/channel.c, src/eval.c,
src/os_unix.c, src/os_win32.c, src/gui_w48.c, src/proto/channel.pro
*** ../vim-7.4.1317/src/structs.h 2016-02-13 23:22:35.077363718 +0100
--- src/structs.h 2016-02-14 19:05:06.792167742 +0100
***************
*** 1301,1335 ****
MODE_JS
} ch_mode_T;
! struct channel_S {
! channel_T *ch_next;
! channel_T *ch_prev;
!
! int ch_id; /* ID of the channel */
! sock_T ch_sock; /* the socket, -1 for a closed channel */
#ifdef UNIX
# define CHANNEL_PIPES
- int ch_in; /* stdin of the job, -1 if not used */
- int ch_out; /* stdout of the job, -1 if not used */
- int ch_err; /* stderr of the job, -1 if not used */
! # if defined(UNIX) && !defined(HAVE_SELECT)
! int ch_sock_idx; /* used by channel_poll_setup() */
! int ch_in_idx; /* used by channel_poll_setup() */
! int ch_out_idx; /* used by channel_poll_setup() */
! int ch_err_idx; /* used by channel_poll_setup() */
! # endif
#endif
! readq_T ch_head; /* dummy node, header for circular queue */
- int ch_error; /* When TRUE an error was reported.
Avoids
- * giving pages full of error messages when
- * the other side has exited, only mention the
- * first error until the connection works
- * again. */
#ifdef FEAT_GUI_X11
XtInputId ch_inputHandler; /* Cookie for input */
#endif
--- 1301,1330 ----
MODE_JS
} ch_mode_T;
! /* Ordering matters: IN is last, only SOCK/OUT/ERR are polled */
! #define CHAN_SOCK 0
! #define CH_SOCK ch_pfd[CHAN_SOCK].ch_fd
#ifdef UNIX
# define CHANNEL_PIPES
! # define CHAN_OUT 1
! # define CHAN_ERR 2
! # define CHAN_IN 3
! # define CH_OUT ch_pfd[CHAN_OUT].ch_fd
! # define CH_ERR ch_pfd[CHAN_ERR].ch_fd
! # define CH_IN ch_pfd[CHAN_IN].ch_fd
#endif
! /* The per-fd info for a channel. */
! typedef struct {
! sock_T ch_fd; /* socket/stdin/stdout/stderr, -1 if not used */
!
! # if defined(UNIX) && !defined(HAVE_SELECT)
! int ch_poll_idx; /* used by channel_poll_setup() */
! # endif
#ifdef FEAT_GUI_X11
XtInputId ch_inputHandler; /* Cookie for input */
#endif
***************
*** 1337,1345 ****
gint ch_inputHandler; /* Cookie for input */
#endif
#ifdef WIN32
! int ch_inputHandler; /* simply ret.value of
WSAAsyncSelect() */
#endif
void (*ch_close_cb)(void); /* callback for when channel is closed */
int ch_block_id; /* ID that channel_read_json_block() is
--- 1332,1356 ----
gint ch_inputHandler; /* Cookie for input */
#endif
#ifdef WIN32
! int ch_inputHandler; /* ret.value of WSAAsyncSelect() */
#endif
+ } chan_fd_T;
+
+ struct channel_S {
+ channel_T *ch_next;
+ channel_T *ch_prev;
+
+ int ch_id; /* ID of the channel */
+
+ chan_fd_T ch_pfd[4]; /* info for socket, in, out and err */
+ readq_T ch_head; /* dummy node, header for circular queue */
+
+ int ch_error; /* When TRUE an error was reported.
Avoids
+ * giving pages full of error messages when
+ * the other side has exited, only mention the
+ * first error until the connection works
+ * again. */
void (*ch_close_cb)(void); /* callback for when channel is closed */
int ch_block_id; /* ID that channel_read_json_block() is
*** ../vim-7.4.1317/src/feature.h 2016-02-07 19:57:12.192788494 +0100
--- src/feature.h 2016-02-13 23:45:26.674898639 +0100
***************
*** 1262,1268 ****
#endif
/*
! * The +job feature requires +eval and Unix or MS-Widndows.
*/
#if (defined(UNIX) || defined(WIN32)) && defined(FEAT_EVAL)
# define FEAT_JOB
--- 1262,1268 ----
#endif
/*
! * The +job feature requires +eval and Unix or MS-Windows.
*/
#if (defined(UNIX) || defined(WIN32)) && defined(FEAT_EVAL)
# define FEAT_JOB
*** ../vim-7.4.1317/src/channel.c 2016-02-13 23:22:35.085363634 +0100
--- src/channel.c 2016-02-14 19:04:42.060425893 +0100
***************
*** 213,219 ****
channel_T *
add_channel(void)
{
! channel_T *channel = (channel_T *)alloc_clear((int)sizeof(channel_T));
if (channel == NULL)
return NULL;
--- 213,220 ----
channel_T *
add_channel(void)
{
! int which;
! channel_T *channel = (channel_T *)alloc_clear((int)sizeof(channel_T));
if (channel == NULL)
return NULL;
***************
*** 221,241 ****
channel->ch_id = next_ch_id++;
ch_log(channel, "Opening channel\n");
- channel->ch_sock = (sock_T)-1;
#ifdef CHANNEL_PIPES
! channel->ch_in = -1;
! channel->ch_out = -1;
! channel->ch_err = -1;
#endif
#ifdef FEAT_GUI_X11
! channel->ch_inputHandler = (XtInputId)NULL;
#endif
#ifdef FEAT_GUI_GTK
! channel->ch_inputHandler = 0;
#endif
#ifdef FEAT_GUI_W32
! channel->ch_inputHandler = -1;
#endif
channel->ch_timeout = 2000;
--- 222,244 ----
channel->ch_id = next_ch_id++;
ch_log(channel, "Opening channel\n");
#ifdef CHANNEL_PIPES
! for (which = CHAN_SOCK; which <= CHAN_IN; ++which)
! #else
! which = CHAN_SOCK;
#endif
+ {
+ channel->ch_pfd[which].ch_fd = (sock_T)-1;
#ifdef FEAT_GUI_X11
! channel->ch_pfd[which].ch_inputHandler = (XtInputId)NULL;
#endif
#ifdef FEAT_GUI_GTK
! channel->ch_pfd[which].ch_inputHandler = 0;
#endif
#ifdef FEAT_GUI_W32
! channel->ch_pfd[which].ch_inputHandler = -1;
#endif
+ }
channel->ch_timeout = 2000;
***************
*** 290,296 ****
if (channel == NULL)
ch_errorn(NULL, "Channel %d not found", id);
else
! channel_read(channel, FALSE, "messageFromNetbeans");
}
#endif
--- 293,299 ----
if (channel == NULL)
ch_errorn(NULL, "Channel %d not found", id);
else
! channel_read(channel, -1, "messageFromNetbeans");
}
#endif
***************
*** 318,363 ****
#endif
static void
! channel_gui_register(channel_T *channel)
{
- if (!CH_HAS_GUI)
- return;
-
- /* TODO: pipes */
# ifdef FEAT_GUI_X11
! /* tell notifier we are interested in being called
! * when there is input on the editor connection socket
! */
! if (channel->ch_inputHandler == (XtInputId)NULL)
! channel->ch_inputHandler =
! XtAppAddInput((XtAppContext)app_context, channel->ch_sock,
! (XtPointer)(XtInputReadMask + XtInputExceptMask),
! messageFromNetbeans, (XtPointer)(long)channel->ch_id);
# else
# ifdef FEAT_GUI_GTK
! /*
! * Tell gdk we are interested in being called when there
! * is input on the editor connection socket
! */
! if (channel->ch_inputHandler == 0)
! channel->ch_inputHandler =
! gdk_input_add((gint)channel->ch_sock, (GdkInputCondition)
! ((int)GDK_INPUT_READ + (int)GDK_INPUT_EXCEPTION),
! messageFromNetbeans, (gpointer)(long)channel->ch_id);
# else
# ifdef FEAT_GUI_W32
! /*
! * Tell Windows we are interested in receiving message when there
! * is input on the editor connection socket.
! */
! if (channel->ch_inputHandler == -1)
! channel->ch_inputHandler =
! WSAAsyncSelect(channel->ch_sock, s_hwnd, WM_NETBEANS, FD_READ);
# endif
# endif
# endif
}
/*
* Register any of our file descriptors with the GUI event handling system.
* Called when the GUI has started.
--- 321,377 ----
#endif
static void
! channel_gui_register_one(channel_T *channel, int which)
{
# ifdef FEAT_GUI_X11
! /* Tell notifier we are interested in being called
! * when there is input on the editor connection socket. */
! if (channel->ch_pfd[which].ch_inputHandler == (XtInputId)NULL)
! channel->ch_pfd[which].ch_inputHandler = XtAppAddInput(
! (XtAppContext)app_context,
! channel->ch_pfd[which].ch_fd,
! (XtPointer)(XtInputReadMask + XtInputExceptMask),
! messageFromNetbeans,
! (XtPointer)(long)channel->ch_id);
# else
# ifdef FEAT_GUI_GTK
! /* Tell gdk we are interested in being called when there
! * is input on the editor connection socket. */
! if (channel->ch_pfd[which].ch_inputHandler == 0)
! channel->ch_pfd[which].ch_inputHandler = gdk_input_add(
! (gint)channel->ch_pfd[which].ch_fd, (GdkInputCondition)
! ((int)GDK_INPUT_READ + (int)GDK_INPUT_EXCEPTION),
! messageFromNetbeans,
! (gpointer)(long)channel->ch_id);
# else
# ifdef FEAT_GUI_W32
! /* Tell Windows we are interested in receiving message when there
! * is input on the editor connection socket. */
! if (channel->ch_pfd[which].ch_inputHandler == -1)
! channel->ch_pfd[which].ch_inputHandler = WSAAsyncSelect(
! channel->ch_pfd[which].ch_fd,
! s_hwnd, WM_NETBEANS, FD_READ);
# endif
# endif
# endif
}
+ void
+ channel_gui_register(channel_T *channel)
+ {
+ if (!CH_HAS_GUI)
+ return;
+
+ if (channel->ch_pfd[CHAN_SOCK].ch_fd >= 0)
+ channel_gui_register_one(channel, CHAN_SOCK);
+ # ifdef CHANNEL_PIPES
+ if (channel->ch_pfd[CHAN_OUT].ch_fd >= 0)
+ channel_gui_register_one(channel, CHAN_OUT);
+ if (channel->ch_pfd[CHAN_ERR].ch_fd >= 0)
+ channel_gui_register_one(channel, CHAN_ERR);
+ # endif
+ }
+
/*
* Register any of our file descriptors with the GUI event handling system.
* Called when the GUI has started.
***************
*** 368,407 ****
channel_T *channel;
for (channel = first_channel; channel != NULL; channel = channel->ch_next)
! /* TODO: pipes */
! if (channel->ch_sock >= 0)
! channel_gui_register(channel);
}
static void
! channel_gui_unregister(channel_T *channel)
{
- /* TODO: pipes */
# ifdef FEAT_GUI_X11
! if (channel->ch_inputHandler != (XtInputId)NULL)
{
! XtRemoveInput(channel->ch_inputHandler);
! channel->ch_inputHandler = (XtInputId)NULL;
}
# else
# ifdef FEAT_GUI_GTK
! if (channel->ch_inputHandler != 0)
{
! gdk_input_remove(channel->ch_inputHandler);
! channel->ch_inputHandler = 0;
}
# else
# ifdef FEAT_GUI_W32
! if (channel->ch_inputHandler == 0)
{
! WSAAsyncSelect(channel->ch_sock, s_hwnd, 0, 0);
! channel->ch_inputHandler = -1;
}
# endif
# endif
# endif
}
#endif
/*
--- 382,431 ----
channel_T *channel;
for (channel = first_channel; channel != NULL; channel = channel->ch_next)
! channel_gui_register(channel);
}
static void
! channel_gui_unregister_one(channel_T *channel, int which)
{
# ifdef FEAT_GUI_X11
! if (channel->ch_pfd[which].ch_inputHandler != (XtInputId)NULL)
{
! XtRemoveInput(channel->ch_pfd[which].ch_inputHandler);
! channel->ch_pfd[which].ch_inputHandler = (XtInputId)NULL;
}
# else
# ifdef FEAT_GUI_GTK
! if (channel->ch_pfd[which].ch_inputHandler != 0)
{
! gdk_input_remove(channel->ch_pfd[which].ch_inputHandler);
! channel->ch_pfd[which].ch_inputHandler = 0;
}
# else
# ifdef FEAT_GUI_W32
! if (channel->ch_pfd[which].ch_inputHandler == 0)
{
! WSAAsyncSelect(channel->ch_pfd[which].ch_fd, s_hwnd, 0, 0);
! channel->ch_pfd[which].ch_inputHandler = -1;
}
# endif
# endif
# endif
}
+ static void
+ channel_gui_unregister(channel_T *channel)
+ {
+ if (channel->ch_pfd[CHAN_SOCK].ch_fd >= 0)
+ channel_gui_unregister_one(channel, CHAN_SOCK);
+ # ifdef CHANNEL_PIPES
+ if (channel->ch_pfd[CHAN_OUT].ch_fd >= 0)
+ channel_gui_unregister_one(channel, CHAN_OUT);
+ if (channel->ch_pfd[CHAN_ERR].ch_fd >= 0)
+ channel_gui_unregister_one(channel, CHAN_ERR);
+ # endif
+ }
+
#endif
/*
***************
*** 440,445 ****
--- 464,470 ----
{
ch_error(NULL, "in socket() in channel_open().\n");
PERROR("E898: socket() in channel_open()");
+ channel_free(channel);
return NULL;
}
***************
*** 453,458 ****
--- 478,484 ----
ch_error(NULL, "in gethostbyname() in channel_open()\n");
PERROR("E901: gethostbyname() in channel_open()");
sock_close(sd);
+ channel_free(channel);
return NULL;
}
memcpy((char *)&server.sin_addr, host->h_addr, host->h_length);
***************
*** 472,477 ****
--- 498,504 ----
ch_errorn(NULL, "channel_open: Connect failed with errno %d\n",
errno);
sock_close(sd);
+ channel_free(channel);
return NULL;
}
}
***************
*** 492,497 ****
--- 519,525 ----
errno);
PERROR(_("E902: Cannot connect to port"));
sock_close(sd);
+ channel_free(channel);
return NULL;
}
}
***************
*** 513,524 ****
--- 541,554 ----
errno);
PERROR(_("E902: Cannot connect to port"));
sock_close(sd);
+ channel_free(channel);
return NULL;
}
if (!FD_ISSET(sd, &wfds))
{
/* don't give an error, we just timed out. */
sock_close(sd);
+ channel_free(channel);
return NULL;
}
}
***************
*** 542,547 ****
--- 572,578 ----
SOCK_ERRNO;
ch_log(NULL, "socket() retry in channel_open()\n");
PERROR("E900: socket() retry in channel_open()");
+ channel_free(channel);
return NULL;
}
if (connect(sd, (struct sockaddr *)&server, sizeof(server)))
***************
*** 575,586 ****
ch_error(NULL, "Cannot connect to port after retry\n");
PERROR(_("E899: Cannot connect to port after retry2"));
sock_close(sd);
return NULL;
}
}
}
! channel->ch_sock = sd;
channel->ch_close_cb = close_cb;
#ifdef FEAT_GUI
--- 606,618 ----
ch_error(NULL, "Cannot connect to port after retry\n");
PERROR(_("E899: Cannot connect to port after retry2"));
sock_close(sd);
+ channel_free(channel);
return NULL;
}
}
}
! channel->CH_SOCK = sd;
channel->ch_close_cb = close_cb;
#ifdef FEAT_GUI
***************
*** 594,602 ****
void
channel_set_pipes(channel_T *channel, int in, int out, int err)
{
! channel->ch_in = in;
! channel->ch_out = out;
! channel->ch_err = err;
}
#endif
--- 626,634 ----
void
channel_set_pipes(channel_T *channel, int in, int out, int err)
{
! channel->CH_IN = in;
! channel->CH_OUT = out;
! channel->CH_ERR = err;
}
#endif
***************
*** 1115,1123 ****
int
channel_can_write_to(channel_T *channel)
{
! return channel != NULL && (channel->ch_sock >= 0
#ifdef CHANNEL_PIPES
! || channel->ch_in >= 0
#endif
);
}
--- 1147,1155 ----
int
channel_can_write_to(channel_T *channel)
{
! return channel != NULL && (channel->CH_SOCK >= 0
#ifdef CHANNEL_PIPES
! || channel->CH_IN >= 0
#endif
);
}
***************
*** 1129,1139 ****
int
channel_is_open(channel_T *channel)
{
! return channel != NULL && (channel->ch_sock >= 0
#ifdef CHANNEL_PIPES
! || channel->ch_in >= 0
! || channel->ch_out >= 0
! || channel->ch_err >= 0
#endif
);
}
--- 1161,1171 ----
int
channel_is_open(channel_T *channel)
{
! return channel != NULL && (channel->CH_SOCK >= 0
#ifdef CHANNEL_PIPES
! || channel->CH_IN >= 0
! || channel->CH_OUT >= 0
! || channel->CH_ERR >= 0
#endif
);
}
***************
*** 1160,1169 ****
{
ch_log(channel, "Closing channel");
! if (channel->ch_sock >= 0)
{
! sock_close(channel->ch_sock);
! channel->ch_sock = -1;
channel->ch_close_cb = NULL;
#ifdef FEAT_GUI
channel_gui_unregister(channel);
--- 1192,1201 ----
{
ch_log(channel, "Closing channel");
! if (channel->CH_SOCK >= 0)
{
! sock_close(channel->CH_SOCK);
! channel->CH_SOCK = -1;
channel->ch_close_cb = NULL;
#ifdef FEAT_GUI
channel_gui_unregister(channel);
***************
*** 1172,1191 ****
channel->ch_callback = NULL;
}
#if defined(CHANNEL_PIPES)
! if (channel->ch_in >= 0)
{
! close(channel->ch_in);
! channel->ch_in = -1;
}
! if (channel->ch_out >= 0)
{
! close(channel->ch_out);
! channel->ch_out = -1;
}
! if (channel->ch_err >= 0)
{
! close(channel->ch_err);
! channel->ch_err = -1;
}
#endif
channel_clear(channel);
--- 1204,1223 ----
channel->ch_callback = NULL;
}
#if defined(CHANNEL_PIPES)
! if (channel->CH_IN >= 0)
{
! close(channel->CH_IN);
! channel->CH_IN = -1;
}
! if (channel->CH_OUT >= 0)
{
! close(channel->CH_OUT);
! channel->CH_OUT = -1;
}
! if (channel->CH_ERR >= 0)
{
! close(channel->CH_ERR);
! channel->CH_ERR = -1;
}
#endif
channel_clear(channel);
***************
*** 1351,1367 ****
/*
* Get the file descriptor to read from, either the socket or stdout.
*/
static int
! get_read_fd(channel_T *channel, int use_stderr)
{
! if (channel->ch_sock >= 0)
! return channel->ch_sock;
#if defined(CHANNEL_PIPES)
! if (!use_stderr && channel->ch_out >= 0)
! return channel->ch_out;
! if (use_stderr && channel->ch_err >= 0)
! return channel->ch_err;
#endif
ch_error(channel, "channel_read() called while socket is closed\n");
return -1;
--- 1383,1398 ----
/*
* Get the file descriptor to read from, either the socket or stdout.
+ * TODO: never gets stderr.
*/
static int
! get_read_fd(channel_T *channel)
{
! if (channel->CH_SOCK >= 0)
! return channel->CH_SOCK;
#if defined(CHANNEL_PIPES)
! if (channel->CH_OUT >= 0)
! return channel->CH_OUT;
#endif
ch_error(channel, "channel_read() called while socket is closed\n");
return -1;
***************
*** 1369,1378 ****
/*
* Read from channel "channel" for as long as there is something to read.
* The data is put in the read queue.
*/
void
! channel_read(channel_T *channel, int use_stderr, char *func)
{
static char_u *buf = NULL;
int len = 0;
--- 1400,1410 ----
/*
* Read from channel "channel" for as long as there is something to read.
+ * "which" is CHAN_SOCK, CHAN_OUT or CHAN_ERR. When -1 guess.
* The data is put in the read queue.
*/
void
! channel_read(channel_T *channel, int which, char *func)
{
static char_u *buf = NULL;
int len = 0;
***************
*** 1380,1389 ****
int fd;
int use_socket = FALSE;
! fd = get_read_fd(channel, use_stderr);
if (fd < 0)
return;
! use_socket = channel->ch_sock >= 0;
/* Allocate a buffer to read into. */
if (buf == NULL)
--- 1412,1424 ----
int fd;
int use_socket = FALSE;
! if (which < 0)
! fd = get_read_fd(channel);
! else
! fd = channel->ch_pfd[which].ch_fd;
if (fd < 0)
return;
! use_socket = fd == channel->CH_SOCK;
/* Allocate a buffer to read into. */
if (buf == NULL)
***************
*** 1450,1456 ****
else
{
close(fd);
! channel->ch_out = -1;
}
#endif
--- 1485,1491 ----
else
{
close(fd);
! channel->CH_OUT = -1;
}
#endif
***************
*** 1480,1492 ****
ch_log(channel, "Reading raw\n");
if (channel_peek(channel) == NULL)
{
! int fd = get_read_fd(channel, FALSE);
ch_log(channel, "No readahead\n");
/* Wait for up to the channel timeout. */
if (fd < 0 || channel_wait(channel, fd, channel->ch_timeout) == FAIL)
return NULL;
! channel_read(channel, FALSE, "channel_read_block");
}
/* TODO: only get the first message */
--- 1515,1528 ----
ch_log(channel, "Reading raw\n");
if (channel_peek(channel) == NULL)
{
! int fd = get_read_fd(channel);
+ /* TODO: read both out and err if they are different */
ch_log(channel, "No readahead\n");
/* Wait for up to the channel timeout. */
if (fd < 0 || channel_wait(channel, fd, channel->ch_timeout) == FAIL)
return NULL;
! channel_read(channel, -1, "channel_read_block");
}
/* TODO: only get the first message */
***************
*** 1526,1536 ****
continue;
/* Wait for up to the channel timeout. */
! fd = get_read_fd(channel, FALSE);
if (fd < 0 || channel_wait(channel, fd, channel->ch_timeout)
== FAIL)
break;
! channel_read(channel, FALSE, "channel_read_json_block");
}
}
channel->ch_block_id = 0;
--- 1562,1572 ----
continue;
/* Wait for up to the channel timeout. */
! fd = get_read_fd(channel);
if (fd < 0 || channel_wait(channel, fd, channel->ch_timeout)
== FAIL)
break;
! channel_read(channel, -1, "channel_read_json_block");
}
}
channel->ch_block_id = 0;
***************
*** 1539,1562 ****
# if defined(WIN32) || defined(PROTO)
/*
! * Lookup the channel from the socket.
* Returns NULL when the socket isn't found.
*/
channel_T *
! channel_fd2channel(sock_T fd)
{
! channel_T *channel;
if (fd >= 0)
for (channel = first_channel; channel != NULL;
channel = channel->ch_next)
! if (channel->ch_sock == fd
! # if defined(CHANNEL_PIPES)
! || channel->ch_out == fd
! || channel->ch_err == fd
# endif
! )
! return channel;
return NULL;
}
# endif
--- 1575,1602 ----
# if defined(WIN32) || defined(PROTO)
/*
! * Lookup the channel from the socket. Set "which" to the fd index.
* Returns NULL when the socket isn't found.
*/
channel_T *
! channel_fd2channel(sock_T fd, int *whichp)
{
! channel_T *channel;
! int i;
if (fd >= 0)
for (channel = first_channel; channel != NULL;
channel = channel->ch_next)
! # ifdef CHANNEL_PIPES
! for (i = CHAN_SOCK; i < CHAN_IN; ++i)
! # else
! i = CHAN_SOCK;
# endif
! if (channel->ch_pfd[i].ch_fd == fd)
! {
! *whichp = i;
! return channel
! }
return NULL;
}
# endif
***************
*** 1574,1587 ****
int fd = -1;
int use_socket = FALSE;
! if (channel->ch_sock >= 0)
{
! fd = channel->ch_sock;
use_socket = TRUE;
}
#if defined(CHANNEL_PIPES)
! else if (channel->ch_in >= 0)
! fd = channel->ch_in;
#endif
if (fd < 0)
{
--- 1614,1627 ----
int fd = -1;
int use_socket = FALSE;
! if (channel->CH_SOCK >= 0)
{
! fd = channel->CH_SOCK;
use_socket = TRUE;
}
#if defined(CHANNEL_PIPES)
! else if (channel->CH_IN >= 0)
! fd = channel->CH_IN;
#endif
if (fd < 0)
{
***************
*** 1631,1674 ****
int
channel_poll_setup(int nfd_in, void *fds_in)
{
! int nfd = nfd_in;
! channel_T *channel;
! struct pollfd *fds = fds_in;
for (channel = first_channel; channel != NULL; channel = channel->ch_next)
- {
- if (channel->ch_sock >= 0)
- {
- channel->ch_sock_idx = nfd;
- fds[nfd].fd = channel->ch_sock;
- fds[nfd].events = POLLIN;
- nfd++;
- }
- else
- channel->ch_sock_idx = -1;
-
# ifdef CHANNEL_PIPES
! if (channel->ch_out >= 0)
! {
! channel->ch_out_idx = nfd;
! fds[nfd].fd = channel->ch_out;
! fds[nfd].events = POLLIN;
! nfd++;
! }
! else
! channel->ch_out_idx = -1;
!
! if (channel->ch_err >= 0)
! {
! channel->ch_err_idx = nfd;
! fds[nfd].fd = channel->ch_err;
! fds[nfd].events = POLLIN;
! nfd++;
! }
! else
! channel->ch_err_idx = -1;
# endif
! }
return nfd;
}
--- 1671,1696 ----
int
channel_poll_setup(int nfd_in, void *fds_in)
{
! int nfd = nfd_in;
! channel_T *channel;
! struct pollfd *fds = fds_in;
! int which;
for (channel = first_channel; channel != NULL; channel = channel->ch_next)
# ifdef CHANNEL_PIPES
! for (which = CHAN_SOCK; which < CHAN_IN; ++which)
! # else
! which = CHAN_SOCK;
# endif
! if (channel->ch_pfd[which].ch_fd >= 0)
! {
! channel->ch_pfd[which].ch_poll_idx = nfd;
! fds[nfd].fd = channel->ch_pfd[which].ch_fd;
! fds[nfd].events = POLLIN;
! nfd++;
! }
! else
! channel->ch_pfd[which].ch_poll_idx = -1;
return nfd;
}
***************
*** 1679,1711 ****
int
channel_poll_check(int ret_in, void *fds_in)
{
! int ret = ret_in;
! channel_T *channel;
! struct pollfd *fds = fds_in;
for (channel = first_channel; channel != NULL; channel = channel->ch_next)
- {
- if (ret > 0 && channel->ch_sock_idx != -1
- && fds[channel->ch_sock_idx].revents & POLLIN)
- {
- channel_read(channel, FALSE, "channel_poll_check");
- --ret;
- }
# ifdef CHANNEL_PIPES
! if (ret > 0 && channel->ch_out_idx != -1
! && fds[channel->ch_out_idx].revents & POLLIN)
! {
! channel_read(channel, FALSE, "channel_poll_check");
! --ret;
! }
! if (ret > 0 && channel->ch_err_idx != -1
! && fds[channel->ch_err_idx].revents & POLLIN)
{
! channel_read(channel, TRUE, "channel_poll_check");
! --ret;
}
- # endif
- }
return ret;
}
--- 1701,1726 ----
int
channel_poll_check(int ret_in, void *fds_in)
{
! int ret = ret_in;
! channel_T *channel;
! struct pollfd *fds = fds_in;
! int which;
for (channel = first_channel; channel != NULL; channel = channel->ch_next)
# ifdef CHANNEL_PIPES
! for (which = CHAN_SOCK; which < CHAN_IN; ++which)
! # else
! which = CHAN_SOCK;
! # endif
{
! int idx = channel->ch_pfd[which].ch_poll_idx;
!
! if (ret > 0 && idx != -1 && fds[idx].revents & POLLIN)
! {
! channel_read(channel, which, "channel_poll_check");
! --ret;
! }
}
return ret;
}
***************
*** 1718,1750 ****
int
channel_select_setup(int maxfd_in, void *rfds_in)
{
! int maxfd = maxfd_in;
! channel_T *channel;
! fd_set *rfds = rfds_in;
for (channel = first_channel; channel != NULL; channel = channel->ch_next)
- {
- if (channel->ch_sock >= 0)
- {
- FD_SET(channel->ch_sock, rfds);
- if (maxfd < channel->ch_sock)
- maxfd = channel->ch_sock;
- }
# ifdef CHANNEL_PIPES
! if (channel->ch_out >= 0)
! {
! FD_SET(channel->ch_out, rfds);
! if (maxfd < channel->ch_out)
! maxfd = channel->ch_out;
! }
! if (channel->ch_err >= 0)
{
! FD_SET(channel->ch_err, rfds);
! if (maxfd < channel->ch_err)
! maxfd = channel->ch_err;
}
- # endif
- }
return maxfd;
}
--- 1733,1759 ----
int
channel_select_setup(int maxfd_in, void *rfds_in)
{
! int maxfd = maxfd_in;
! channel_T *channel;
! fd_set *rfds = rfds_in;
! int which;
for (channel = first_channel; channel != NULL; channel = channel->ch_next)
# ifdef CHANNEL_PIPES
! for (which = CHAN_SOCK; which < CHAN_IN; ++which)
! # else
! which = CHAN_SOCK;
! # endif
{
! sock_T fd = channel->ch_pfd[which].ch_fd;
!
! if (fd >= 0)
! {
! FD_SET(fd, rfds);
! if (maxfd < fd)
! maxfd = fd;
! }
}
return maxfd;
}
***************
*** 1755,1787 ****
int
channel_select_check(int ret_in, void *rfds_in)
{
! int ret = ret_in;
! channel_T *channel;
! fd_set *rfds = rfds_in;
for (channel = first_channel; channel != NULL; channel = channel->ch_next)
- {
- if (ret > 0 && channel->ch_sock >= 0
- && FD_ISSET(channel->ch_sock, rfds))
- {
- channel_read(channel, FALSE, "channel_select_check");
- --ret;
- }
# ifdef CHANNEL_PIPES
! if (ret > 0 && channel->ch_out >= 0
! && FD_ISSET(channel->ch_out, rfds))
! {
! channel_read(channel, FALSE, "channel_select_check");
! --ret;
! }
! if (ret > 0 && channel->ch_err >= 0
! && FD_ISSET(channel->ch_err, rfds))
{
! channel_read(channel, TRUE, "channel_select_check");
! --ret;
}
- # endif
- }
return ret;
}
--- 1764,1789 ----
int
channel_select_check(int ret_in, void *rfds_in)
{
! int ret = ret_in;
! channel_T *channel;
! fd_set *rfds = rfds_in;
! int which;
for (channel = first_channel; channel != NULL; channel = channel->ch_next)
# ifdef CHANNEL_PIPES
! for (which = CHAN_SOCK; which < CHAN_IN; ++which)
! # else
! which = CHAN_SOCK;
! # endif
{
! sock_T fd = channel->ch_pfd[which].ch_fd;
!
! if (ret > 0 && fd >= 0 && FD_ISSET(fd, rfds))
! {
! channel_read(channel, which, "channel_select_check");
! --ret;
! }
}
return ret;
}
*** ../vim-7.4.1317/src/eval.c 2016-02-13 23:50:03.743961279 +0100
--- src/eval.c 2016-02-14 00:11:04.998605012 +0100
***************
*** 9970,9981 ****
channel = channel_open((char *)address, port, waittime, NULL);
if (channel != NULL)
{
channel_set_json_mode(channel, ch_mode);
channel_set_timeout(channel, timeout);
if (callback != NULL && *callback != NUL)
channel_set_callback(channel, callback);
}
- rettv->vval.v_channel = channel;
}
/*
--- 9970,9981 ----
channel = channel_open((char *)address, port, waittime, NULL);
if (channel != NULL)
{
+ rettv->vval.v_channel = channel;
channel_set_json_mode(channel, ch_mode);
channel_set_timeout(channel, timeout);
if (callback != NULL && *callback != NUL)
channel_set_callback(channel, callback);
}
}
/*
*** ../vim-7.4.1317/src/os_unix.c 2016-02-13 23:28:17.637753771 +0100
--- src/os_unix.c 2016-02-14 13:42:05.002296825 +0100
***************
*** 5116,5125 ****
--- 5116,5130 ----
close(fd_err[1]);
channel_set_pipes(channel, fd_in[1], fd_out[0], fd_err[0]);
channel_set_job(channel, job);
+ #ifdef FEAT_GUI
+ channel_gui_register(channel);
+ #endif
return;
failed:
+ if (channel != NULL)
+ channel_free(channel);
if (fd_in[0] >= 0)
{
close(fd_in[0]);
*** ../vim-7.4.1317/src/os_win32.c 2016-02-12 19:30:20.353885756 +0100
--- src/os_win32.c 2016-02-14 13:44:21.720867994 +0100
***************
*** 5039,5050 ****
STARTUPINFO si;
PROCESS_INFORMATION pi;
HANDLE jo;
jo = CreateJobObject(NULL, NULL);
if (jo == NULL)
{
job->jv_status = JOB_FAILED;
! return;
}
ZeroMemory(&pi, sizeof(pi));
--- 5039,5057 ----
STARTUPINFO si;
PROCESS_INFORMATION pi;
HANDLE jo;
+ #ifdef FEAT_CHANNEL
+ channel_T *channel;
+
+ channel = add_channel();
+ if (channel == NULL)
+ return;
+ #endif
jo = CreateJobObject(NULL, NULL);
if (jo == NULL)
{
job->jv_status = JOB_FAILED;
! goto failed;
}
ZeroMemory(&pi, sizeof(pi));
***************
*** 5062,5083 ****
{
CloseHandle(jo);
job->jv_status = JOB_FAILED;
}
! else
{
! if (!AssignProcessToJobObject(jo, pi.hProcess))
! {
! /* if failing, switch the way to terminate
! * process with TerminateProcess. */
! CloseHandle(jo);
! jo = NULL;
! }
! ResumeThread(pi.hThread);
! CloseHandle(job->jv_proc_info.hThread);
! job->jv_proc_info = pi;
! job->jv_job_object = jo;
! job->jv_status = JOB_STARTED;
}
}
char *
--- 5069,5108 ----
{
CloseHandle(jo);
job->jv_status = JOB_FAILED;
+ goto failed;
}
!
! if (!AssignProcessToJobObject(jo, pi.hProcess))
{
! /* if failing, switch the way to terminate
! * process with TerminateProcess. */
! CloseHandle(jo);
! jo = NULL;
}
+ ResumeThread(pi.hThread);
+ CloseHandle(job->jv_proc_info.hThread);
+ job->jv_proc_info = pi;
+ job->jv_job_object = jo;
+ job->jv_status = JOB_STARTED;
+
+ #ifdef FEAT_CHANNEL
+ # if 0
+ /* TODO: connect stdin/stdout/stderr */
+ job->jv_channel = channel;
+ channel_set_pipes(channel, fd_in[1], fd_out[0], fd_err[0]);
+ channel_set_job(channel, job);
+
+ # ifdef FEAT_GUI
+ channel_gui_register(channel);
+ # endif
+ # endif
+ #endif
+ return;
+
+ failed:
+ #ifdef FEAT_CHANNEL
+ channel_free(channel);
+ #endif
}
char *
*** ../vim-7.4.1317/src/gui_w48.c 2016-02-13 23:22:35.093363549 +0100
--- src/gui_w48.c 2016-02-14 14:07:47.998167014 +0100
***************
*** 1780,1793 ****
#ifdef FEAT_CHANNEL
if (msg.message == WM_NETBEANS)
{
! channel_T *channel = channel_fd2channel((sock_T)msg.wParam);
if (channel != NULL)
{
/* Disable error messages, they can mess up the display and throw
* an exception. */
++emsg_off;
! channel_read(channel, FALSE, "process_message");
--emsg_off;
}
return;
--- 1780,1794 ----
#ifdef FEAT_CHANNEL
if (msg.message == WM_NETBEANS)
{
! int what;
! channel_T *channel = channel_fd2channel((sock_T)msg.wParam, &what);
if (channel != NULL)
{
/* Disable error messages, they can mess up the display and throw
* an exception. */
++emsg_off;
! channel_read(channel, what, "process_message");
--emsg_off;
}
return;
*** ../vim-7.4.1317/src/proto/channel.pro 2016-02-13 23:22:35.093363549
+0100
--- src/proto/channel.pro 2016-02-14 14:29:38.320487534 +0100
***************
*** 2,7 ****
--- 2,8 ----
void ch_logfile(FILE *file);
channel_T *add_channel(void);
void channel_free(channel_T *channel);
+ void channel_gui_register(channel_T *channel);
void channel_gui_register_all(void);
channel_T *channel_open(char *hostname, int port_in, int waittime, void
(*close_cb)(void));
void channel_set_pipes(channel_T *channel, int in, int out, int err);
***************
*** 21,30 ****
void channel_clear(channel_T *channel);
void channel_free_all(void);
int channel_get_id(void);
! void channel_read(channel_T *channel, int use_stderr, char *func);
char_u *channel_read_block(channel_T *channel);
int channel_read_json_block(channel_T *channel, int id, typval_T **rettv);
! channel_T *channel_fd2channel(sock_T fd);
int channel_send(channel_T *channel, char_u *buf, char *fun);
int channel_poll_setup(int nfd_in, void *fds_in);
int channel_poll_check(int ret_in, void *fds_in);
--- 22,31 ----
void channel_clear(channel_T *channel);
void channel_free_all(void);
int channel_get_id(void);
! void channel_read(channel_T *channel, int what, char *func);
char_u *channel_read_block(channel_T *channel);
int channel_read_json_block(channel_T *channel, int id, typval_T **rettv);
! channel_T *channel_fd2channel(sock_T fd, int *what);
int channel_send(channel_T *channel, char_u *buf, char *fun);
int channel_poll_setup(int nfd_in, void *fds_in);
int channel_poll_check(int ret_in, void *fds_in);
*** ../vim-7.4.1317/src/version.c 2016-02-14 00:19:55.088992301 +0100
--- src/version.c 2016-02-14 19:06:22.015378080 +0100
***************
*** 749,750 ****
--- 749,752 ----
{ /* Add new patch number below this line */
+ /**/
+ 1318,
/**/
--
Emacs is a nice OS - but it lacks a good text editor.
That's why I am using Vim. --Anonymous
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.