Merge remote-tracking branch 'vim/master'

This commit is contained in:
Kazuki Sakamoto
2016-02-14 21:30:43 -08:00
10 changed files with 338 additions and 281 deletions
+4 -2
View File
@@ -679,8 +679,10 @@ ifneq ($(CHANNEL),yes)
# Cannot use Netbeans without CHANNEL
NETBEANS=no
else
# Only allow NETBEANS for a GUI build.
ifeq (yes, $(GUI))
ifneq (yes, $(GUI))
# Cannot use Netbeans without GUI.
NETBEANS=no
else
OBJ += $(OUTDIR)/netbeans.o
LIB += -lwsock32
endif
+236 -231
View File
@@ -213,7 +213,8 @@ static int next_ch_id = 0;
channel_T *
add_channel(void)
{
channel_T *channel = (channel_T *)alloc_clear((int)sizeof(channel_T));
int which;
channel_T *channel = (channel_T *)alloc_clear((int)sizeof(channel_T));
if (channel == NULL)
return NULL;
@@ -221,24 +222,26 @@ add_channel(void)
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;
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_inputHandler = (XtInputId)NULL;
channel->ch_pfd[which].ch_inputHandler = (XtInputId)NULL;
#endif
#ifdef FEAT_GUI_GTK
channel->ch_inputHandler = 0;
channel->ch_pfd[which].ch_inputHandler = 0;
#endif
#ifdef FEAT_GUI_W32
channel->ch_inputHandler = -1;
channel->ch_pfd[which].ch_inputHandler = -1;
#endif
#ifdef FEAT_GUI_MACVIM
channel->ch_inputHandler = -1;
channel->ch_inputHandler = -1;
#endif
}
channel->ch_timeout = 2000;
@@ -293,7 +296,7 @@ channel_read_netbeans(int id)
if (channel == NULL)
ch_errorn(NULL, "Channel %d not found", id);
else
channel_read(channel, FALSE, "messageFromNetbeans");
channel_read(channel, -1, "messageFromNetbeans");
}
#endif
@@ -321,55 +324,65 @@ messageFromNetbeans(gpointer clientData,
#endif
static void
channel_gui_register(channel_T *channel)
channel_gui_register_one(channel_T *channel, int which)
{
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);
/* 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_inputHandler == 0)
channel->ch_inputHandler =
gdk_input_add((gint)channel->ch_sock, (GdkInputCondition)
/* 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);
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);
/* 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);
# else
# ifdef FEAT_GUI_MACVIM
/*
* Tell Core Foundation we are interested in being called when there
* is input on the editor connection socket
*/
if (channel->ch_inputHandler == -1) {
channel->ch_inputHandler = 0;
/* Tell Core Foundation we are interested in being called when there
* is input on the editor connection socket. */
if (channel->ch_pfd[which].ch_inputHandler == -1) {
channel->ch_pfd[which].ch_inputHandler = 0;
gui_macvim_add_channel(channel);
}
# endif
# endif
# endif
# endif
}
void
channel_gui_register(channel_T *channel)
{
if (!CH_HAS_GUI)
return;
if (channel->CH_SOCK >= 0)
channel_gui_register_one(channel, CHAN_SOCK);
# ifdef CHANNEL_PIPES
if (channel->CH_OUT >= 0)
channel_gui_register_one(channel, CHAN_OUT);
if (channel->CH_ERR >= 0)
channel_gui_register_one(channel, CHAN_ERR);
# endif
}
/*
@@ -382,46 +395,52 @@ channel_gui_register_all(void)
channel_T *channel;
for (channel = first_channel; channel != NULL; channel = channel->ch_next)
/* TODO: pipes */
if (channel->ch_sock >= 0)
channel_gui_register(channel);
channel_gui_register(channel);
}
static void
channel_gui_unregister(channel_T *channel)
{
/* TODO: pipes */
# ifdef FEAT_GUI_X11
if (channel->ch_inputHandler != (XtInputId)NULL)
int which;
#ifdef CHANNEL_PIPES
for (which = CHAN_SOCK; which < CHAN_IN; ++which)
#else
which = CHAN_SOCK;
#endif
{
XtRemoveInput(channel->ch_inputHandler);
channel->ch_inputHandler = (XtInputId)NULL;
}
# 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_inputHandler != 0)
{
gdk_input_remove(channel->ch_inputHandler);
channel->ch_inputHandler = 0;
}
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_inputHandler == 0)
{
WSAAsyncSelect(channel->ch_sock, s_hwnd, 0, 0);
channel->ch_inputHandler = -1;
}
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;
}
# else
# ifdef FEAT_GUI_MACVIM
if (channel->ch_inputHandler == 0)
{
gui_macvim_remove_channel(channel);
channel->ch_inputHandler = -1;
}
if (channel->ch_pfd[which].ch_inputHandler == 0)
{
gui_macvim_remove_channel(channel);
channel->ch_pfd[which].ch_inputHandler = -1;
}
# endif
# endif
# endif
# endif
}
}
#endif
@@ -462,6 +481,7 @@ channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void))
{
ch_error(NULL, "in socket() in channel_open().\n");
PERROR("E898: socket() in channel_open()");
channel_free(channel);
return NULL;
}
@@ -475,6 +495,7 @@ channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void))
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);
@@ -494,6 +515,7 @@ channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void))
ch_errorn(NULL, "channel_open: Connect failed with errno %d\n",
errno);
sock_close(sd);
channel_free(channel);
return NULL;
}
}
@@ -514,6 +536,7 @@ channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void))
errno);
PERROR(_("E902: Cannot connect to port"));
sock_close(sd);
channel_free(channel);
return NULL;
}
}
@@ -535,12 +558,14 @@ channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void))
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;
}
}
@@ -564,6 +589,7 @@ channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void))
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)))
@@ -597,12 +623,13 @@ channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void))
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_SOCK = sd;
channel->ch_close_cb = close_cb;
#ifdef FEAT_GUI
@@ -616,9 +643,9 @@ 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)
{
channel->ch_in = in;
channel->ch_out = out;
channel->ch_err = err;
channel->CH_IN = in;
channel->CH_OUT = out;
channel->CH_ERR = err;
}
#endif
@@ -1137,9 +1164,9 @@ may_invoke_callback(channel_T *channel)
int
channel_can_write_to(channel_T *channel)
{
return channel != NULL && (channel->ch_sock >= 0
return channel != NULL && (channel->CH_SOCK >= 0
#ifdef CHANNEL_PIPES
|| channel->ch_in >= 0
|| channel->CH_IN >= 0
#endif
);
}
@@ -1151,11 +1178,11 @@ channel_can_write_to(channel_T *channel)
int
channel_is_open(channel_T *channel)
{
return channel != NULL && (channel->ch_sock >= 0
return channel != NULL && (channel->CH_SOCK >= 0
#ifdef CHANNEL_PIPES
|| channel->ch_in >= 0
|| channel->ch_out >= 0
|| channel->ch_err >= 0
|| channel->CH_IN >= 0
|| channel->CH_OUT >= 0
|| channel->CH_ERR >= 0
#endif
);
}
@@ -1182,34 +1209,36 @@ channel_close(channel_T *channel)
{
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);
channel_gui_unregister(channel);
#endif
vim_free(channel->ch_callback);
channel->ch_callback = NULL;
if (channel->CH_SOCK >= 0)
{
sock_close(channel->CH_SOCK);
channel->CH_SOCK = -1;
}
#if defined(CHANNEL_PIPES)
if (channel->ch_in >= 0)
if (channel->CH_IN >= 0)
{
close(channel->ch_in);
channel->ch_in = -1;
close(channel->CH_IN);
channel->CH_IN = -1;
}
if (channel->ch_out >= 0)
if (channel->CH_OUT >= 0)
{
close(channel->ch_out);
channel->ch_out = -1;
close(channel->CH_OUT);
channel->CH_OUT = -1;
}
if (channel->ch_err >= 0)
if (channel->CH_ERR >= 0)
{
close(channel->ch_err);
channel->ch_err = -1;
close(channel->CH_ERR);
channel->CH_ERR = -1;
}
#endif
channel->ch_close_cb = NULL;
vim_free(channel->ch_callback);
channel->ch_callback = NULL;
channel_clear(channel);
}
@@ -1373,17 +1402,16 @@ channel_get_id(void)
/*
* Get the file descriptor to read from, either the socket or stdout.
* TODO: should have a way to read stderr.
*/
static int
get_read_fd(channel_T *channel, int use_stderr)
get_read_fd(channel_T *channel)
{
if (channel->ch_sock >= 0)
return channel->ch_sock;
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;
if (channel->CH_OUT >= 0)
return channel->CH_OUT;
#endif
ch_error(channel, "channel_read() called while socket is closed\n");
return -1;
@@ -1391,10 +1419,12 @@ get_read_fd(channel_T *channel, int use_stderr)
/*
* Read from channel "channel" for as long as there is something to read.
* "which" is CHAN_SOCK, CHAN_OUT or CHAN_ERR. When -1 use CHAN_SOCK or
* CHAN_OUT, the one that is open.
* The data is put in the read queue.
*/
void
channel_read(channel_T *channel, int use_stderr, char *func)
channel_read(channel_T *channel, int which, char *func)
{
static char_u *buf = NULL;
int len = 0;
@@ -1402,10 +1432,13 @@ channel_read(channel_T *channel, int use_stderr, char *func)
int fd;
int use_socket = FALSE;
fd = get_read_fd(channel, use_stderr);
if (which < 0)
fd = get_read_fd(channel);
else
fd = channel->ch_pfd[which].ch_fd;
if (fd < 0)
return;
use_socket = channel->ch_sock >= 0;
use_socket = fd == channel->CH_SOCK;
/* Allocate a buffer to read into. */
if (buf == NULL)
@@ -1462,19 +1495,12 @@ channel_read(channel_T *channel, int use_stderr, char *func)
ch_errors(channel, "%s(): Cannot read\n", func);
channel_save(channel, (char_u *)DETACH_MSG, (int)STRLEN(DETACH_MSG));
if (use_socket)
{
channel_close(channel);
if (channel->ch_close_cb != NULL)
(*channel->ch_close_cb)();
}
#if defined(CHANNEL_PIPES)
else
{
close(fd);
channel->ch_out = -1;
}
#endif
/* TODO: When reading from stdout is not possible, should we try to
* keep stdin and stderr open? Probably not, assume the other side
* has died. */
channel_close(channel);
if (channel->ch_close_cb != NULL)
(*channel->ch_close_cb)();
if (len < 0)
{
@@ -1502,13 +1528,14 @@ channel_read_block(channel_T *channel)
ch_log(channel, "Reading raw\n");
if (channel_peek(channel) == NULL)
{
int fd = get_read_fd(channel, FALSE);
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, FALSE, "channel_read_block");
channel_read(channel, -1, "channel_read_block");
}
/* TODO: only get the first message */
@@ -1548,11 +1575,11 @@ channel_read_json_block(channel_T *channel, int id, typval_T **rettv)
continue;
/* Wait for up to the channel timeout. */
fd = get_read_fd(channel, FALSE);
fd = get_read_fd(channel);
if (fd < 0 || channel_wait(channel, fd, channel->ch_timeout)
== FAIL)
break;
channel_read(channel, FALSE, "channel_read_json_block");
channel_read(channel, -1, "channel_read_json_block");
}
}
channel->ch_block_id = 0;
@@ -1561,24 +1588,30 @@ channel_read_json_block(channel_T *channel, int id, typval_T **rettv)
# if defined(WIN32) || defined(PROTO)
/*
* Lookup the channel from the socket.
* 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)
channel_fd2channel(sock_T fd, int *whichp)
{
channel_T *channel;
channel_T *channel;
int i;
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
{
# ifdef CHANNEL_PIPES
for (i = CHAN_SOCK; i < CHAN_IN; ++i)
# else
i = CHAN_SOCK;
# endif
)
return channel;
if (channel->ch_pfd[i].ch_fd == fd)
{
*whichp = i;
return channel;
}
}
return NULL;
}
# endif
@@ -1596,14 +1629,14 @@ channel_send(channel_T *channel, char_u *buf, char *fun)
int fd = -1;
int use_socket = FALSE;
if (channel->ch_sock >= 0)
if (channel->CH_SOCK >= 0)
{
fd = channel->ch_sock;
fd = channel->CH_SOCK;
use_socket = TRUE;
}
#if defined(CHANNEL_PIPES)
else if (channel->ch_in >= 0)
fd = channel->ch_in;
else if (channel->CH_IN >= 0)
fd = channel->CH_IN;
#endif
if (fd < 0)
{
@@ -1620,7 +1653,7 @@ channel_send(channel_T *channel, char_u *buf, char *fun)
{
ch_log_lead("SEND ", channel);
fprintf(log_fd, "'");
ignored = fwrite(buf, len, 1, log_fd);
ignored = (int)fwrite(buf, len, 1, log_fd);
fprintf(log_fd, "'\n");
fflush(log_fd);
}
@@ -1653,43 +1686,29 @@ channel_send(channel_T *channel, char_u *buf, char *fun)
int
channel_poll_setup(int nfd_in, void *fds_in)
{
int nfd = nfd_in;
channel_T *channel;
struct pollfd *fds = 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)
{
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;
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;
@@ -1701,32 +1720,27 @@ channel_poll_setup(int nfd_in, void *fds_in)
int
channel_poll_check(int ret_in, void *fds_in)
{
int ret = ret_in;
channel_T *channel;
struct pollfd *fds = 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)
{
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;
}
for (which = CHAN_SOCK; which < CH_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;
@@ -1740,32 +1754,28 @@ channel_poll_check(int ret_in, void *fds_in)
int
channel_select_setup(int maxfd_in, void *rfds_in)
{
int maxfd = maxfd_in;
channel_T *channel;
fd_set *rfds = 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)
{
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;
}
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;
@@ -1777,32 +1787,27 @@ channel_select_setup(int maxfd_in, void *rfds_in)
int
channel_select_check(int ret_in, void *rfds_in)
{
int ret = ret_in;
channel_T *channel;
fd_set *rfds = 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)
{
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;
}
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;
+1 -1
View File
@@ -9970,12 +9970,12 @@ f_ch_open(typval_T *argvars, typval_T *rettv)
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);
}
rettv->vval.v_channel = channel;
}
/*
+1 -1
View File
@@ -1276,7 +1276,7 @@
#endif
/*
* The +job feature requires +eval and Unix or MS-Widndows.
* The +job feature requires +eval and Unix or MS-Windows.
*/
#if (defined(UNIX) || defined(WIN32)) && defined(FEAT_EVAL)
# define FEAT_JOB
+3 -2
View File
@@ -1780,14 +1780,15 @@ process_message(void)
#ifdef FEAT_CHANNEL
if (msg.message == WM_NETBEANS)
{
channel_T *channel = channel_fd2channel((sock_T)msg.wParam);
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, FALSE, "process_message");
channel_read(channel, what, "process_message");
--emsg_off;
}
return;
+6 -1
View File
@@ -5065,7 +5065,7 @@ mch_start_job(char **argv, job_T *job)
int fd_in[2]; /* for stdin */
int fd_out[2]; /* for stdout */
int fd_err[2]; /* for stderr */
channel_T *channel;
channel_T *channel = NULL;
/* default is to fail */
job->jv_status = JOB_FAILED;
@@ -5138,10 +5138,15 @@ mch_start_job(char **argv, job_T *job)
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]);
+39 -14
View File
@@ -5039,12 +5039,19 @@ mch_start_job(char *cmd, job_T *job)
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;
return;
goto failed;
}
ZeroMemory(&pi, sizeof(pi));
@@ -5062,22 +5069,40 @@ mch_start_job(char *cmd, job_T *job)
{
CloseHandle(jo);
job->jv_status = JOB_FAILED;
goto failed;
}
else
if (!AssignProcessToJobObject(jo, pi.hProcess))
{
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;
/* 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 *
+3 -2
View File
@@ -2,6 +2,7 @@
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,10 +22,10 @@ char_u *channel_peek(channel_T *channel);
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);
void channel_read(channel_T *channel, int which, 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);
channel_T *channel_fd2channel(sock_T fd, int *whichp);
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);
+39 -27
View File
@@ -1301,27 +1301,51 @@ typedef enum
MODE_JS
} ch_mode_T;
/* Ordering matters, it is used in for loops: 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
#ifdef FEAT_GUI_GTK
gint ch_inputHandler; /* Cookie for input */
#endif
#ifdef WIN32
int ch_inputHandler; /* ret.value of WSAAsyncSelect() */
#endif
#ifdef FEAT_GUI_MACVIM
int ch_inputHandler; /* Cookie for input */
#endif
} chan_fd_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
chan_fd_T ch_pfd[4]; /* info for socket, out, err and in */
readq_T ch_head; /* dummy node, header for circular queue */
@@ -1330,18 +1354,6 @@ struct channel_S {
* 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
#ifdef FEAT_GUI_GTK
gint ch_inputHandler; /* Cookie for input */
#endif
#ifdef WIN32
int ch_inputHandler; /* simply ret.value of WSAAsyncSelect() */
#endif
#ifdef FEAT_GUI_MACVIM
int ch_inputHandler; /* Cookie for input */
#endif
void (*ch_close_cb)(void); /* callback for when channel is closed */
+6
View File
@@ -762,6 +762,12 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1320,
/**/
1319,
/**/
1318,
/**/
1317,
/**/