1
0
forked from aniani/vim

patch 8.0.1074: ":term NONE" does not work on MS-Windows

Problem:    ":term NONE" does not work on MS-Windows.
Solution:   Make it work.  Split "pty" into "pty_in" and "pty_out". (Yasuhiro
            Matsumoto, closes #2058, closes #2045)
This commit is contained in:
Bram Moolenaar
2017-09-08 14:39:30 +02:00
parent ba2929b6af
commit 2dc9d26c14
8 changed files with 177 additions and 43 deletions

View File

@@ -38,8 +38,7 @@
* in tl_scrollback are no longer used.
*
* TODO:
* - ":term NONE" does not work on MS-Windows.
* https://github.com/vim/vim/pull/2056
* - patch to use GUI or cterm colors for vterm. Yasuhiro, #2067
* - Redirecting output does not work on MS-Windows.
* - implement term_setsize()
* - add test for giving error for invalid 'termsize' value.
@@ -97,7 +96,8 @@ struct terminal_S {
/* used when tl_job is NULL and only a pty was created */
int tl_tty_fd;
char_u *tl_tty_name;
char_u *tl_tty_in;
char_u *tl_tty_out;
int tl_normal_mode; /* TRUE: Terminal-Normal mode */
int tl_channel_closed;
@@ -2666,14 +2666,32 @@ f_term_gettty(typval_T *argvars, typval_T *rettv)
{
buf_T *buf = term_get_buf(argvars);
char_u *p;
int num = 0;
rettv->v_type = VAR_STRING;
if (buf == NULL)
return;
if (buf->b_term->tl_job != NULL)
p = buf->b_term->tl_job->jv_tty_name;
else
p = buf->b_term->tl_tty_name;
if (argvars[1].v_type != VAR_UNKNOWN)
num = get_tv_number(&argvars[1]);
switch (num)
{
case 0:
if (buf->b_term->tl_job != NULL)
p = buf->b_term->tl_job->jv_tty_out;
else
p = buf->b_term->tl_tty_out;
break;
case 1:
if (buf->b_term->tl_job != NULL)
p = buf->b_term->tl_job->jv_tty_in;
else
p = buf->b_term->tl_tty_in;
break;
default:
EMSG2(_(e_invarg2), get_tv_string(&argvars[1]));
return;
}
if (p != NULL)
rettv->vval.v_string = vim_strsave(p);
}
@@ -3055,7 +3073,6 @@ term_and_job_init(
HANDLE child_thread_handle;
void *winpty_err;
void *spawn_config = NULL;
char buf[MAX_PATH];
garray_T ga;
char_u *cmd;
@@ -3094,7 +3111,6 @@ term_and_job_init(
if (term->tl_winpty == NULL)
goto failed;
/* TODO: if the command is "NONE" only create a pty. */
spawn_config = winpty_spawn_config_new(
WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN |
WINPTY_SPAWN_FLAG_EXIT_AFTER_SHUTDOWN,
@@ -3162,9 +3178,10 @@ term_and_job_init(
job->jv_proc_info.dwProcessId = GetProcessId(child_process_handle);
job->jv_job_object = jo;
job->jv_status = JOB_STARTED;
sprintf(buf, "winpty://%lu",
GetProcessId(winpty_agent_process(term->tl_winpty)));
job->jv_tty_name = vim_strsave((char_u*)buf);
job->jv_tty_in = utf16_to_enc(
(short_u*)winpty_conin_name(term->tl_winpty), NULL);
job->jv_tty_out = utf16_to_enc(
(short_u*)winpty_conout_name(term->tl_winpty), NULL);
++job->jv_refcount;
term->tl_job = job;
@@ -3205,9 +3222,68 @@ failed:
}
static int
create_pty_only(term_T *term, jobopt_T *opt)
create_pty_only(term_T *term, jobopt_T *options)
{
/* TODO: implement this */
HANDLE hPipeIn = INVALID_HANDLE_VALUE;
HANDLE hPipeOut = INVALID_HANDLE_VALUE;
char in_name[80], out_name[80];
channel_T *channel = NULL;
create_vterm(term, term->tl_rows, term->tl_cols);
vim_snprintf(in_name, sizeof(in_name), "\\\\.\\pipe\\vim-%d-in-%d",
GetCurrentProcessId(),
curbuf->b_fnum);
hPipeIn = CreateNamedPipe(in_name, PIPE_ACCESS_OUTBOUND,
PIPE_TYPE_MESSAGE | PIPE_NOWAIT,
PIPE_UNLIMITED_INSTANCES,
0, 0, NMPWAIT_NOWAIT, NULL);
if (hPipeIn == INVALID_HANDLE_VALUE)
goto failed;
vim_snprintf(out_name, sizeof(out_name), "\\\\.\\pipe\\vim-%d-out-%d",
GetCurrentProcessId(),
curbuf->b_fnum);
hPipeOut = CreateNamedPipe(out_name, PIPE_ACCESS_INBOUND,
PIPE_TYPE_MESSAGE | PIPE_NOWAIT,
PIPE_UNLIMITED_INSTANCES,
0, 0, 0, NULL);
if (hPipeOut == INVALID_HANDLE_VALUE)
goto failed;
ConnectNamedPipe(hPipeIn, NULL);
ConnectNamedPipe(hPipeOut, NULL);
term->tl_job = job_alloc();
if (term->tl_job == NULL)
goto failed;
++term->tl_job->jv_refcount;
/* behave like the job is already finished */
term->tl_job->jv_status = JOB_FINISHED;
channel = add_channel();
if (channel == NULL)
goto failed;
term->tl_job->jv_channel = channel;
channel->ch_keep_open = TRUE;
channel->ch_named_pipe = TRUE;
channel_set_pipes(channel,
(sock_T)hPipeIn,
(sock_T)hPipeOut,
(sock_T)hPipeOut);
channel_set_job(channel, term->tl_job, options);
term->tl_job->jv_tty_in = vim_strsave((char_u*)in_name);
term->tl_job->jv_tty_out = vim_strsave((char_u*)out_name);
return OK;
failed:
if (hPipeIn != NULL)
CloseHandle(hPipeIn);
if (hPipeOut != NULL)
CloseHandle(hPipeOut);
return FAIL;
}
@@ -3234,7 +3310,8 @@ term_free_vterm(term_T *term)
static void
term_report_winsize(term_T *term, int rows, int cols)
{
winpty_set_size(term->tl_winpty, cols, rows, NULL);
if (term->tl_winpty)
winpty_set_size(term->tl_winpty, cols, rows, NULL);
}
int