Skip to content

Commit 7c9aec4

Browse files
committed
patch 8.0.0846: cannot get the name of the pty of a job
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.
1 parent d8dc179 commit 7c9aec4

9 files changed

Lines changed: 75 additions & 26 deletions

File tree

runtime/doc/eval.txt

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*eval.txt* For Vim version 8.0. Last change: 2017 Aug 01
1+
*eval.txt* For Vim version 8.0. Last change: 2017 Aug 03
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -2376,6 +2376,7 @@ term_getline({buf}, {row}) String get a line of text from a terminal
23762376
term_getsize({buf}) List get the size of a terminal
23772377
term_getstatus({buf}) String get the status of a terminal
23782378
term_gettitle({buf}) String get the title of a terminal
2379+
term_gettty({buf}) String get the tty name of a terminal
23792380
term_list() List get the list of terminal buffers
23802381
term_scrape({buf}, {row}) List get row of a terminal screen
23812382
term_sendkeys({buf}, {keys}) none send keystrokes to a terminal
@@ -5192,6 +5193,8 @@ job_info({job}) *job_info()*
51925193
Returns a Dictionary with information about {job}:
51935194
"status" what |job_status()| returns
51945195
"channel" what |job_getchannel()| returns
5196+
"process" process ID
5197+
"tty" controlling terminal name, empty when none
51955198
"exitval" only valid when "status" is "dead"
51965199
"exit_cb" function to be called on exit
51975200
"stoponexit" |job-stoponexit|
@@ -7930,6 +7933,7 @@ term_getcursor({buf}) *term_getcursor()*
79307933
term_getjob({buf}) *term_getjob()*
79317934
Get the Job associated with terminal window {buf}.
79327935
{buf} is used as with |term_getsize()|.
7936+
Returns |v:null| when there is no job.
79337937

79347938
term_getline({buf}, {row}) *term_getline()*
79357939
Get a line of text from the terminal window of {buf}.
@@ -7943,9 +7947,9 @@ term_getsize({buf}) *term_getsize()*
79437947
numbers: [rows, cols]. This is the size of the terminal, not
79447948
the window containing the terminal.
79457949

7946-
{buf} must be the buffer number of a terminal window. If the
7947-
buffer does not exist or is not a terminal window, an empty
7948-
list is returned.
7950+
{buf} must be the buffer number of a terminal window. Use an
7951+
empty string for the current buffer. If the buffer does not
7952+
exist or is not a terminal window, an empty list is returned.
79497953

79507954
term_getstatus({buf}) *term_getstatus()*
79517955
Get the status of terminal {buf}. This returns a comma
@@ -7967,6 +7971,11 @@ term_gettitle({buf}) *term_gettitle()*
79677971
buffer does not exist or is not a terminal window, an empty
79687972
string is returned.
79697973

7974+
term_gettty({buf}) *term_gettty()*
7975+
Get the name of the controlling terminal associated with
7976+
terminal window {buf}.
7977+
{buf} is used as with |term_getsize()|.
7978+
79707979
term_list() *term_list()*
79717980
Return a list with the buffer numbers of all buffers for
79727981
terminal windows.
@@ -7982,7 +7991,7 @@ term_scrape({buf}, {row}) *term_scrape()*
79827991
"chars" character(s) at the cell
79837992
"fg" foreground color as #rrggbb
79847993
"bg" background color as #rrggbb
7985-
"attr" attributes of the cell, use term_getattr()
7994+
"attr" attributes of the cell, use |term_getattr()|
79867995
to get the individual flags
79877996
"width" cell width: 1 or 2
79887997

src/channel.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,11 +1016,9 @@ ch_close_part(channel_T *channel, ch_part_T part)
10161016
{
10171017
/* When using a pty the same FD is set on multiple parts, only
10181018
* close it when the last reference is closed. */
1019-
if ((part == PART_IN || channel->ch_part[PART_IN].ch_fd != *fd)
1020-
&& (part == PART_OUT
1021-
|| channel->ch_part[PART_OUT].ch_fd != *fd)
1022-
&& (part == PART_ERR
1023-
|| channel->ch_part[PART_ERR].ch_fd != *fd))
1019+
if ((part == PART_IN || channel->CH_IN_FD != *fd)
1020+
&& (part == PART_OUT || channel->CH_OUT_FD != *fd)
1021+
&& (part == PART_ERR || channel->CH_ERR_FD != *fd))
10241022
fd_close(*fd);
10251023
}
10261024
*fd = INVALID_FD;
@@ -4592,6 +4590,7 @@ job_free_contents(job_T *job)
45924590
}
45934591
mch_clear_job(job);
45944592

4593+
vim_free(job->jv_tty_name);
45954594
vim_free(job->jv_stoponexit);
45964595
free_callback(job->jv_exit_cb, job->jv_exit_partial);
45974596
}
@@ -5164,6 +5163,8 @@ job_info(job_T *job, dict_T *dict)
51645163
nr = job->jv_proc_info.dwProcessId;
51655164
#endif
51665165
dict_add_nr_str(dict, "process", nr, NULL);
5166+
dict_add_nr_str(dict, "tty", 0L,
5167+
job->jv_tty_name != NULL ? job->jv_tty_name : (char_u *)"");
51675168

51685169
dict_add_nr_str(dict, "exitval", job->jv_exitval, NULL);
51695170
dict_add_nr_str(dict, "exit_cb", 0L, job->jv_exit_cb);

src/evalfunc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,7 @@ static struct fst
838838
{"term_getsize", 1, 1, f_term_getsize},
839839
{"term_getstatus", 1, 1, f_term_getstatus},
840840
{"term_gettitle", 1, 1, f_term_gettitle},
841+
{"term_gettty", 1, 1, f_term_gettty},
841842
{"term_list", 0, 0, f_term_list},
842843
{"term_scrape", 1, 2, f_term_scrape},
843844
{"term_sendkeys", 2, 2, f_term_sendkeys},

src/os_unix.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4170,7 +4170,7 @@ set_default_child_environment(void)
41704170
* When successful both file descriptors are stored.
41714171
*/
41724172
static void
4173-
open_pty(int *pty_master_fd, int *pty_slave_fd)
4173+
open_pty(int *pty_master_fd, int *pty_slave_fd, char_u **namep)
41744174
{
41754175
char *tty_name;
41764176

@@ -4190,6 +4190,8 @@ open_pty(int *pty_master_fd, int *pty_slave_fd)
41904190
close(*pty_master_fd);
41914191
*pty_master_fd = -1;
41924192
}
4193+
else if (namep != NULL)
4194+
*namep = vim_strsave((char_u *)tty_name);
41934195
}
41944196
}
41954197
#endif
@@ -4384,7 +4386,7 @@ mch_call_shell(
43844386
* If the slave can't be opened, close the master pty.
43854387
*/
43864388
if (p_guipty && !(options & (SHELL_READ|SHELL_WRITE)))
4387-
open_pty(&pty_master_fd, &pty_slave_fd);
4389+
open_pty(&pty_master_fd, &pty_slave_fd, NULL);
43884390
/*
43894391
* If not opening a pty or it didn't work, try using pipes.
43904392
*/
@@ -5189,9 +5191,9 @@ mch_call_shell(
51895191
mch_job_start(char **argv, job_T *job, jobopt_T *options)
51905192
{
51915193
pid_t pid;
5192-
int fd_in[2]; /* for stdin */
5193-
int fd_out[2]; /* for stdout */
5194-
int fd_err[2]; /* for stderr */
5194+
int fd_in[2] = {-1, -1}; /* for stdin */
5195+
int fd_out[2] = {-1, -1}; /* for stdout */
5196+
int fd_err[2] = {-1, -1}; /* for stderr */
51955197
int pty_master_fd = -1;
51965198
int pty_slave_fd = -1;
51975199
channel_T *channel = NULL;
@@ -5209,15 +5211,9 @@ mch_job_start(char **argv, job_T *job, jobopt_T *options)
52095211

52105212
/* default is to fail */
52115213
job->jv_status = JOB_FAILED;
5212-
fd_in[0] = -1;
5213-
fd_in[1] = -1;
5214-
fd_out[0] = -1;
5215-
fd_out[1] = -1;
5216-
fd_err[0] = -1;
5217-
fd_err[1] = -1;
52185214

52195215
if (options->jo_pty)
5220-
open_pty(&pty_master_fd, &pty_slave_fd);
5216+
open_pty(&pty_master_fd, &pty_slave_fd, &job->jv_tty_name);
52215217

52225218
/* TODO: without the channel feature connect the child to /dev/null? */
52235219
/* Open pipes for stdin, stdout, stderr. */

src/proto/terminal.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ void f_term_getline(typval_T *argvars, typval_T *rettv);
2323
void f_term_getsize(typval_T *argvars, typval_T *rettv);
2424
void f_term_getstatus(typval_T *argvars, typval_T *rettv);
2525
void f_term_gettitle(typval_T *argvars, typval_T *rettv);
26+
void f_term_gettty(typval_T *argvars, typval_T *rettv);
2627
void f_term_list(typval_T *argvars, typval_T *rettv);
2728
void f_term_scrape(typval_T *argvars, typval_T *rettv);
2829
void f_term_sendkeys(typval_T *argvars, typval_T *rettv);

src/structs.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,6 +1478,7 @@ struct jobvar_S
14781478
PROCESS_INFORMATION jv_proc_info;
14791479
HANDLE jv_job_object;
14801480
#endif
1481+
char_u *jv_tty_name; /* controlling tty, allocated */
14811482
jobstatus_T jv_status;
14821483
char_u *jv_stoponexit; /* allocated */
14831484
int jv_exitval;
@@ -1537,18 +1538,20 @@ typedef enum {
15371538
JIO_OUT
15381539
} job_io_T;
15391540

1541+
#define CH_PART_FD(part) ch_part[part].ch_fd
1542+
15401543
/* Ordering matters, it is used in for loops: IN is last, only SOCK/OUT/ERR
15411544
* are polled. */
15421545
typedef enum {
15431546
PART_SOCK = 0,
1544-
#define CH_SOCK_FD ch_part[PART_SOCK].ch_fd
1547+
#define CH_SOCK_FD CH_PART_FD(PART_SOCK)
15451548
#ifdef FEAT_JOB_CHANNEL
15461549
PART_OUT,
1547-
# define CH_OUT_FD ch_part[PART_OUT].ch_fd
1550+
# define CH_OUT_FD CH_PART_FD(PART_OUT)
15481551
PART_ERR,
1549-
# define CH_ERR_FD ch_part[PART_ERR].ch_fd
1552+
# define CH_ERR_FD CH_PART_FD(PART_ERR)
15501553
PART_IN,
1551-
# define CH_IN_FD ch_part[PART_IN].ch_fd
1554+
# define CH_IN_FD CH_PART_FD(PART_IN)
15521555
#endif
15531556
PART_COUNT
15541557
} ch_part_T;

src/terminal.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,16 @@
5757
* - add 't' to mode()
5858
* - set 'filetype' to "terminal"?
5959
* - use win_del_lines() to make scroll-up efficient.
60+
* - Make StatusLineTerm adjust UserN highlighting like StatusLineNC does, see
61+
* use of hightlight_stlnc[].
6062
* - implement term_setsize()
6163
* - add test for giving error for invalid 'termsize' value.
6264
* - support minimal size when 'termsize' is "rows*cols".
6365
* - support minimal size when 'termsize' is empty?
6466
* - implement "term" for job_start(): more job options when starting a
6567
* terminal.
68+
* - support ":term NONE" to open a terminal with a pty but not running a job
69+
* in it. The pty can be passed to gdb to run the executable in.
6670
* - if the job in the terminal does not support the mouse, we can use the
6771
* mouse in the Terminal window for copy/paste.
6872
* - when 'encoding' is not utf-8, or the job is using another encoding, setup
@@ -97,6 +101,10 @@ struct terminal_S {
97101
job_T *tl_job;
98102
buf_T *tl_buffer;
99103

104+
/* used when tl_job is NULL and only a pty was created */
105+
int tl_tty_fd;
106+
char_u *tl_tty_name;
107+
100108
int tl_terminal_mode;
101109
int tl_channel_closed;
102110

@@ -1924,6 +1932,26 @@ f_term_gettitle(typval_T *argvars, typval_T *rettv)
19241932
rettv->vval.v_string = vim_strsave(buf->b_term->tl_title);
19251933
}
19261934

1935+
/*
1936+
* "term_gettty(buf)" function
1937+
*/
1938+
void
1939+
f_term_gettty(typval_T *argvars, typval_T *rettv)
1940+
{
1941+
buf_T *buf = term_get_buf(argvars);
1942+
char_u *p;
1943+
1944+
rettv->v_type = VAR_STRING;
1945+
if (buf == NULL)
1946+
return;
1947+
if (buf->b_term->tl_job != NULL)
1948+
p = buf->b_term->tl_job->jv_tty_name;
1949+
else
1950+
p = buf->b_term->tl_tty_name;
1951+
if (p != NULL)
1952+
rettv->vval.v_string = vim_strsave(p);
1953+
}
1954+
19271955
/*
19281956
* "term_list()" function
19291957
*/
@@ -2216,6 +2244,7 @@ term_and_job_init(term_T *term, int rows, int cols, char_u *cmd)
22162244
if (term->tl_winpty == NULL)
22172245
goto failed;
22182246

2247+
/* TODO: if the command is "NONE" only create a pty. */
22192248
spawn_config = winpty_spawn_config_new(
22202249
WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN |
22212250
WINPTY_SPAWN_FLAG_EXIT_AFTER_SHUTDOWN,
@@ -2359,6 +2388,7 @@ term_and_job_init(term_T *term, int rows, int cols, char_u *cmd)
23592388

23602389
create_vterm(term, rows, cols);
23612390

2391+
/* TODO: if the command is "NONE" only create a pty. */
23622392
argvars[0].v_type = VAR_STRING;
23632393
argvars[0].vval.v_string = cmd;
23642394
setup_job_options(&opt, rows, cols);

src/testdir/test_terminal.vim

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ endfunc
3030

3131
func Test_terminal_basic()
3232
let buf = Run_shell_in_terminal()
33+
if has("unix")
34+
call assert_match("^/dev/", job_info(g:job).tty)
35+
call assert_match("^/dev/", term_gettty(''))
36+
else
37+
call assert_equal("", job_info(g:job).tty)
38+
endif
3339
call Stop_shell_in_terminal(buf)
3440
call term_wait(buf)
3541

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,8 @@ static char *(features[]) =
769769

770770
static int included_patches[] =
771771
{ /* Add new patch number below this line */
772+
/**/
773+
846,
772774
/**/
773775
845,
774776
/**/

0 commit comments

Comments
 (0)