Skip to content

Commit 7b3ca76

Browse files
committed
patch 7.4.1318
Problem: Channel with pipes doesn't work in GUI. Solution: Register input handlers for pipes.
1 parent 0727d36 commit 7b3ca76

9 files changed

+291
-244
lines changed

src/channel.c

+204-202
Large diffs are not rendered by default.

src/eval.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -9970,12 +9970,12 @@ f_ch_open(typval_T *argvars, typval_T *rettv)
99709970
channel = channel_open((char *)address, port, waittime, NULL);
99719971
if (channel != NULL)
99729972
{
9973+
rettv->vval.v_channel = channel;
99739974
channel_set_json_mode(channel, ch_mode);
99749975
channel_set_timeout(channel, timeout);
99759976
if (callback != NULL && *callback != NUL)
99769977
channel_set_callback(channel, callback);
99779978
}
9978-
rettv->vval.v_channel = channel;
99799979
}
99809980

99819981
/*

src/feature.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1262,7 +1262,7 @@
12621262
#endif
12631263

12641264
/*
1265-
* The +job feature requires +eval and Unix or MS-Widndows.
1265+
* The +job feature requires +eval and Unix or MS-Windows.
12661266
*/
12671267
#if (defined(UNIX) || defined(WIN32)) && defined(FEAT_EVAL)
12681268
# define FEAT_JOB

src/gui_w48.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -1780,14 +1780,15 @@ process_message(void)
17801780
#ifdef FEAT_CHANNEL
17811781
if (msg.message == WM_NETBEANS)
17821782
{
1783-
channel_T *channel = channel_fd2channel((sock_T)msg.wParam);
1783+
int what;
1784+
channel_T *channel = channel_fd2channel((sock_T)msg.wParam, &what);
17841785

17851786
if (channel != NULL)
17861787
{
17871788
/* Disable error messages, they can mess up the display and throw
17881789
* an exception. */
17891790
++emsg_off;
1790-
channel_read(channel, FALSE, "process_message");
1791+
channel_read(channel, what, "process_message");
17911792
--emsg_off;
17921793
}
17931794
return;

src/os_unix.c

+5
Original file line numberDiff line numberDiff line change
@@ -5116,10 +5116,15 @@ mch_start_job(char **argv, job_T *job)
51165116
close(fd_err[1]);
51175117
channel_set_pipes(channel, fd_in[1], fd_out[0], fd_err[0]);
51185118
channel_set_job(channel, job);
5119+
#ifdef FEAT_GUI
5120+
channel_gui_register(channel);
5121+
#endif
51195122

51205123
return;
51215124

51225125
failed:
5126+
if (channel != NULL)
5127+
channel_free(channel);
51235128
if (fd_in[0] >= 0)
51245129
{
51255130
close(fd_in[0]);

src/os_win32.c

+39-14
Original file line numberDiff line numberDiff line change
@@ -5039,12 +5039,19 @@ mch_start_job(char *cmd, job_T *job)
50395039
STARTUPINFO si;
50405040
PROCESS_INFORMATION pi;
50415041
HANDLE jo;
5042+
#ifdef FEAT_CHANNEL
5043+
channel_T *channel;
5044+
5045+
channel = add_channel();
5046+
if (channel == NULL)
5047+
return;
5048+
#endif
50425049

50435050
jo = CreateJobObject(NULL, NULL);
50445051
if (jo == NULL)
50455052
{
50465053
job->jv_status = JOB_FAILED;
5047-
return;
5054+
goto failed;
50485055
}
50495056

50505057
ZeroMemory(&pi, sizeof(pi));
@@ -5062,22 +5069,40 @@ mch_start_job(char *cmd, job_T *job)
50625069
{
50635070
CloseHandle(jo);
50645071
job->jv_status = JOB_FAILED;
5072+
goto failed;
50655073
}
5066-
else
5074+
5075+
if (!AssignProcessToJobObject(jo, pi.hProcess))
50675076
{
5068-
if (!AssignProcessToJobObject(jo, pi.hProcess))
5069-
{
5070-
/* if failing, switch the way to terminate
5071-
* process with TerminateProcess. */
5072-
CloseHandle(jo);
5073-
jo = NULL;
5074-
}
5075-
ResumeThread(pi.hThread);
5076-
CloseHandle(job->jv_proc_info.hThread);
5077-
job->jv_proc_info = pi;
5078-
job->jv_job_object = jo;
5079-
job->jv_status = JOB_STARTED;
5077+
/* if failing, switch the way to terminate
5078+
* process with TerminateProcess. */
5079+
CloseHandle(jo);
5080+
jo = NULL;
50805081
}
5082+
ResumeThread(pi.hThread);
5083+
CloseHandle(job->jv_proc_info.hThread);
5084+
job->jv_proc_info = pi;
5085+
job->jv_job_object = jo;
5086+
job->jv_status = JOB_STARTED;
5087+
5088+
#ifdef FEAT_CHANNEL
5089+
# if 0
5090+
/* TODO: connect stdin/stdout/stderr */
5091+
job->jv_channel = channel;
5092+
channel_set_pipes(channel, fd_in[1], fd_out[0], fd_err[0]);
5093+
channel_set_job(channel, job);
5094+
5095+
# ifdef FEAT_GUI
5096+
channel_gui_register(channel);
5097+
# endif
5098+
# endif
5099+
#endif
5100+
return;
5101+
5102+
failed:
5103+
#ifdef FEAT_CHANNEL
5104+
channel_free(channel);
5105+
#endif
50815106
}
50825107

50835108
char *

src/proto/channel.pro

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
void ch_logfile(FILE *file);
33
channel_T *add_channel(void);
44
void channel_free(channel_T *channel);
5+
void channel_gui_register(channel_T *channel);
56
void channel_gui_register_all(void);
67
channel_T *channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void));
78
void channel_set_pipes(channel_T *channel, int in, int out, int err);
@@ -21,10 +22,10 @@ char_u *channel_peek(channel_T *channel);
2122
void channel_clear(channel_T *channel);
2223
void channel_free_all(void);
2324
int channel_get_id(void);
24-
void channel_read(channel_T *channel, int use_stderr, char *func);
25+
void channel_read(channel_T *channel, int what, char *func);
2526
char_u *channel_read_block(channel_T *channel);
2627
int channel_read_json_block(channel_T *channel, int id, typval_T **rettv);
27-
channel_T *channel_fd2channel(sock_T fd);
28+
channel_T *channel_fd2channel(sock_T fd, int *what);
2829
int channel_send(channel_T *channel, char_u *buf, char *fun);
2930
int channel_poll_setup(int nfd_in, void *fds_in);
3031
int channel_poll_check(int ret_in, void *fds_in);

src/structs.h

+33-22
Original file line numberDiff line numberDiff line change
@@ -1301,45 +1301,56 @@ typedef enum
13011301
MODE_JS
13021302
} ch_mode_T;
13031303

1304-
struct channel_S {
1305-
channel_T *ch_next;
1306-
channel_T *ch_prev;
1307-
1308-
int ch_id; /* ID of the channel */
1304+
/* Ordering matters: IN is last, only SOCK/OUT/ERR are polled */
13091305

1310-
sock_T ch_sock; /* the socket, -1 for a closed channel */
1306+
#define CHAN_SOCK 0
1307+
#define CH_SOCK ch_pfd[CHAN_SOCK].ch_fd
13111308

13121309
#ifdef UNIX
13131310
# define CHANNEL_PIPES
1314-
int ch_in; /* stdin of the job, -1 if not used */
1315-
int ch_out; /* stdout of the job, -1 if not used */
1316-
int ch_err; /* stderr of the job, -1 if not used */
13171311

1318-
# if defined(UNIX) && !defined(HAVE_SELECT)
1319-
int ch_sock_idx; /* used by channel_poll_setup() */
1320-
int ch_in_idx; /* used by channel_poll_setup() */
1321-
int ch_out_idx; /* used by channel_poll_setup() */
1322-
int ch_err_idx; /* used by channel_poll_setup() */
1323-
# endif
1312+
# define CHAN_OUT 1
1313+
# define CHAN_ERR 2
1314+
# define CHAN_IN 3
1315+
# define CH_OUT ch_pfd[CHAN_OUT].ch_fd
1316+
# define CH_ERR ch_pfd[CHAN_ERR].ch_fd
1317+
# define CH_IN ch_pfd[CHAN_IN].ch_fd
13241318
#endif
13251319

1326-
readq_T ch_head; /* dummy node, header for circular queue */
1320+
/* The per-fd info for a channel. */
1321+
typedef struct {
1322+
sock_T ch_fd; /* socket/stdin/stdout/stderr, -1 if not used */
1323+
1324+
# if defined(UNIX) && !defined(HAVE_SELECT)
1325+
int ch_poll_idx; /* used by channel_poll_setup() */
1326+
# endif
13271327

1328-
int ch_error; /* When TRUE an error was reported. Avoids
1329-
* giving pages full of error messages when
1330-
* the other side has exited, only mention the
1331-
* first error until the connection works
1332-
* again. */
13331328
#ifdef FEAT_GUI_X11
13341329
XtInputId ch_inputHandler; /* Cookie for input */
13351330
#endif
13361331
#ifdef FEAT_GUI_GTK
13371332
gint ch_inputHandler; /* Cookie for input */
13381333
#endif
13391334
#ifdef WIN32
1340-
int ch_inputHandler; /* simply ret.value of WSAAsyncSelect() */
1335+
int ch_inputHandler; /* ret.value of WSAAsyncSelect() */
13411336
#endif
1337+
} chan_fd_T;
1338+
1339+
struct channel_S {
1340+
channel_T *ch_next;
1341+
channel_T *ch_prev;
1342+
1343+
int ch_id; /* ID of the channel */
1344+
1345+
chan_fd_T ch_pfd[4]; /* info for socket, in, out and err */
13421346

1347+
readq_T ch_head; /* dummy node, header for circular queue */
1348+
1349+
int ch_error; /* When TRUE an error was reported. Avoids
1350+
* giving pages full of error messages when
1351+
* the other side has exited, only mention the
1352+
* first error until the connection works
1353+
* again. */
13431354
void (*ch_close_cb)(void); /* callback for when channel is closed */
13441355

13451356
int ch_block_id; /* ID that channel_read_json_block() is

src/version.c

+2
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,8 @@ static char *(features[]) =
747747

748748
static int included_patches[] =
749749
{ /* Add new patch number below this line */
750+
/**/
751+
1318,
750752
/**/
751753
1317,
752754
/**/

0 commit comments

Comments
 (0)