diff options
author | Bram Moolenaar <Bram@vim.org> | 2017-08-03 13:51:25 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2017-08-03 13:51:25 +0200 |
commit | 7c9aec4ac86ccc455c0859d9393253141e3f77b6 (patch) | |
tree | e03624a977c4f3d9b040a866356dbc8245036603 /src | |
parent | d8dc1799377027be622d8571545658b20042e92e (diff) | |
download | vim-git-7c9aec4ac86ccc455c0859d9393253141e3f77b6.tar.gz |
patch 8.0.0846: cannot get the name of the pty of a jobv8.0.0846
Problem: Cannot get the name of the pty of a job.
Solution: Add the "tty" entry to the job info. (Ozaki Kiichi, closes #1920)
Add the term_gettty() function.
Diffstat (limited to 'src')
-rw-r--r-- | src/channel.c | 11 | ||||
-rw-r--r-- | src/evalfunc.c | 1 | ||||
-rw-r--r-- | src/os_unix.c | 20 | ||||
-rw-r--r-- | src/proto/terminal.pro | 1 | ||||
-rw-r--r-- | src/structs.h | 11 | ||||
-rw-r--r-- | src/terminal.c | 30 | ||||
-rw-r--r-- | src/testdir/test_terminal.vim | 6 | ||||
-rw-r--r-- | src/version.c | 2 |
8 files changed, 61 insertions, 21 deletions
diff --git a/src/channel.c b/src/channel.c index 073694ec0..be25f5ef1 100644 --- a/src/channel.c +++ b/src/channel.c @@ -1016,11 +1016,9 @@ ch_close_part(channel_T *channel, ch_part_T part) { /* When using a pty the same FD is set on multiple parts, only * close it when the last reference is closed. */ - if ((part == PART_IN || channel->ch_part[PART_IN].ch_fd != *fd) - && (part == PART_OUT - || channel->ch_part[PART_OUT].ch_fd != *fd) - && (part == PART_ERR - || channel->ch_part[PART_ERR].ch_fd != *fd)) + if ((part == PART_IN || channel->CH_IN_FD != *fd) + && (part == PART_OUT || channel->CH_OUT_FD != *fd) + && (part == PART_ERR || channel->CH_ERR_FD != *fd)) fd_close(*fd); } *fd = INVALID_FD; @@ -4592,6 +4590,7 @@ job_free_contents(job_T *job) } mch_clear_job(job); + vim_free(job->jv_tty_name); vim_free(job->jv_stoponexit); free_callback(job->jv_exit_cb, job->jv_exit_partial); } @@ -5164,6 +5163,8 @@ job_info(job_T *job, dict_T *dict) nr = job->jv_proc_info.dwProcessId; #endif dict_add_nr_str(dict, "process", nr, NULL); + dict_add_nr_str(dict, "tty", 0L, + job->jv_tty_name != NULL ? job->jv_tty_name : (char_u *)""); dict_add_nr_str(dict, "exitval", job->jv_exitval, NULL); dict_add_nr_str(dict, "exit_cb", 0L, job->jv_exit_cb); diff --git a/src/evalfunc.c b/src/evalfunc.c index fc0e05dad..aa8b140a1 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -838,6 +838,7 @@ static struct fst {"term_getsize", 1, 1, f_term_getsize}, {"term_getstatus", 1, 1, f_term_getstatus}, {"term_gettitle", 1, 1, f_term_gettitle}, + {"term_gettty", 1, 1, f_term_gettty}, {"term_list", 0, 0, f_term_list}, {"term_scrape", 1, 2, f_term_scrape}, {"term_sendkeys", 2, 2, f_term_sendkeys}, diff --git a/src/os_unix.c b/src/os_unix.c index 7c4b3180e..c90ab34f6 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4170,7 +4170,7 @@ set_default_child_environment(void) * When successful both file descriptors are stored. */ static void -open_pty(int *pty_master_fd, int *pty_slave_fd) +open_pty(int *pty_master_fd, int *pty_slave_fd, char_u **namep) { char *tty_name; @@ -4190,6 +4190,8 @@ open_pty(int *pty_master_fd, int *pty_slave_fd) close(*pty_master_fd); *pty_master_fd = -1; } + else if (namep != NULL) + *namep = vim_strsave((char_u *)tty_name); } } #endif @@ -4384,7 +4386,7 @@ mch_call_shell( * If the slave can't be opened, close the master pty. */ if (p_guipty && !(options & (SHELL_READ|SHELL_WRITE))) - open_pty(&pty_master_fd, &pty_slave_fd); + open_pty(&pty_master_fd, &pty_slave_fd, NULL); /* * If not opening a pty or it didn't work, try using pipes. */ @@ -5189,9 +5191,9 @@ error: mch_job_start(char **argv, job_T *job, jobopt_T *options) { pid_t pid; - int fd_in[2]; /* for stdin */ - int fd_out[2]; /* for stdout */ - int fd_err[2]; /* for stderr */ + int fd_in[2] = {-1, -1}; /* for stdin */ + int fd_out[2] = {-1, -1}; /* for stdout */ + int fd_err[2] = {-1, -1}; /* for stderr */ int pty_master_fd = -1; int pty_slave_fd = -1; channel_T *channel = NULL; @@ -5209,15 +5211,9 @@ mch_job_start(char **argv, job_T *job, jobopt_T *options) /* default is to fail */ job->jv_status = JOB_FAILED; - fd_in[0] = -1; - fd_in[1] = -1; - fd_out[0] = -1; - fd_out[1] = -1; - fd_err[0] = -1; - fd_err[1] = -1; if (options->jo_pty) - open_pty(&pty_master_fd, &pty_slave_fd); + open_pty(&pty_master_fd, &pty_slave_fd, &job->jv_tty_name); /* TODO: without the channel feature connect the child to /dev/null? */ /* Open pipes for stdin, stdout, stderr. */ diff --git a/src/proto/terminal.pro b/src/proto/terminal.pro index 556f9dd61..157b6aaaf 100644 --- a/src/proto/terminal.pro +++ b/src/proto/terminal.pro @@ -23,6 +23,7 @@ void f_term_getline(typval_T *argvars, typval_T *rettv); void f_term_getsize(typval_T *argvars, typval_T *rettv); void f_term_getstatus(typval_T *argvars, typval_T *rettv); void f_term_gettitle(typval_T *argvars, typval_T *rettv); +void f_term_gettty(typval_T *argvars, typval_T *rettv); void f_term_list(typval_T *argvars, typval_T *rettv); void f_term_scrape(typval_T *argvars, typval_T *rettv); void f_term_sendkeys(typval_T *argvars, typval_T *rettv); diff --git a/src/structs.h b/src/structs.h index cfe72dba8..522e15a98 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1478,6 +1478,7 @@ struct jobvar_S PROCESS_INFORMATION jv_proc_info; HANDLE jv_job_object; #endif + char_u *jv_tty_name; /* controlling tty, allocated */ jobstatus_T jv_status; char_u *jv_stoponexit; /* allocated */ int jv_exitval; @@ -1537,18 +1538,20 @@ typedef enum { JIO_OUT } job_io_T; +#define CH_PART_FD(part) ch_part[part].ch_fd + /* Ordering matters, it is used in for loops: IN is last, only SOCK/OUT/ERR * are polled. */ typedef enum { PART_SOCK = 0, -#define CH_SOCK_FD ch_part[PART_SOCK].ch_fd +#define CH_SOCK_FD CH_PART_FD(PART_SOCK) #ifdef FEAT_JOB_CHANNEL PART_OUT, -# define CH_OUT_FD ch_part[PART_OUT].ch_fd +# define CH_OUT_FD CH_PART_FD(PART_OUT) PART_ERR, -# define CH_ERR_FD ch_part[PART_ERR].ch_fd +# define CH_ERR_FD CH_PART_FD(PART_ERR) PART_IN, -# define CH_IN_FD ch_part[PART_IN].ch_fd +# define CH_IN_FD CH_PART_FD(PART_IN) #endif PART_COUNT } ch_part_T; diff --git a/src/terminal.c b/src/terminal.c index edb4b7558..c24ac9e72 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -57,12 +57,16 @@ * - add 't' to mode() * - set 'filetype' to "terminal"? * - use win_del_lines() to make scroll-up efficient. + * - Make StatusLineTerm adjust UserN highlighting like StatusLineNC does, see + * use of hightlight_stlnc[]. * - implement term_setsize() * - add test for giving error for invalid 'termsize' value. * - support minimal size when 'termsize' is "rows*cols". * - support minimal size when 'termsize' is empty? * - implement "term" for job_start(): more job options when starting a * terminal. + * - support ":term NONE" to open a terminal with a pty but not running a job + * in it. The pty can be passed to gdb to run the executable in. * - if the job in the terminal does not support the mouse, we can use the * mouse in the Terminal window for copy/paste. * - when 'encoding' is not utf-8, or the job is using another encoding, setup @@ -97,6 +101,10 @@ struct terminal_S { job_T *tl_job; buf_T *tl_buffer; + /* used when tl_job is NULL and only a pty was created */ + int tl_tty_fd; + char_u *tl_tty_name; + int tl_terminal_mode; int tl_channel_closed; @@ -1925,6 +1933,26 @@ f_term_gettitle(typval_T *argvars, typval_T *rettv) } /* + * "term_gettty(buf)" function + */ + void +f_term_gettty(typval_T *argvars, typval_T *rettv) +{ + buf_T *buf = term_get_buf(argvars); + char_u *p; + + 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 (p != NULL) + rettv->vval.v_string = vim_strsave(p); +} + +/* * "term_list()" function */ void @@ -2216,6 +2244,7 @@ term_and_job_init(term_T *term, int rows, int cols, char_u *cmd) 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, @@ -2359,6 +2388,7 @@ term_and_job_init(term_T *term, int rows, int cols, char_u *cmd) create_vterm(term, rows, cols); + /* TODO: if the command is "NONE" only create a pty. */ argvars[0].v_type = VAR_STRING; argvars[0].vval.v_string = cmd; setup_job_options(&opt, rows, cols); diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim index 48ee1c4ec..cc5afc394 100644 --- a/src/testdir/test_terminal.vim +++ b/src/testdir/test_terminal.vim @@ -30,6 +30,12 @@ endfunc func Test_terminal_basic() let buf = Run_shell_in_terminal() + if has("unix") + call assert_match("^/dev/", job_info(g:job).tty) + call assert_match("^/dev/", term_gettty('')) + else + call assert_equal("", job_info(g:job).tty) + endif call Stop_shell_in_terminal(buf) call term_wait(buf) diff --git a/src/version.c b/src/version.c index 371146130..9eb8b1a91 100644 --- a/src/version.c +++ b/src/version.c @@ -770,6 +770,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 846, +/**/ 845, /**/ 844, |