]> granicus.if.org Git - vim/commitdiff
patch 8.0.0846: cannot get the name of the pty of a job v8.0.0846
authorBram Moolenaar <Bram@vim.org>
Thu, 3 Aug 2017 11:51:25 +0000 (13:51 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 3 Aug 2017 11:51:25 +0000 (13:51 +0200)
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.

runtime/doc/eval.txt
src/channel.c
src/evalfunc.c
src/os_unix.c
src/proto/terminal.pro
src/structs.h
src/terminal.c
src/testdir/test_terminal.vim
src/version.c

index cbe5565c7f97ba49d16ca3816ec825cfcc1e1c4f..ff9dac2789aa143a7cbc862289f8eb278f1762de 100644 (file)
@@ -1,4 +1,4 @@
-*eval.txt*     For Vim version 8.0.  Last change: 2017 Aug 01
+*eval.txt*     For Vim version 8.0.  Last change: 2017 Aug 03
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -2376,6 +2376,7 @@ term_getline({buf}, {row})        String  get a line of text from a terminal
 term_getsize({buf})            List    get the size of a terminal
 term_getstatus({buf})          String  get the status of a terminal
 term_gettitle({buf})           String  get the title of a terminal
+term_gettty({buf})             String  get the tty name of a terminal
 term_list()                    List    get the list of terminal buffers
 term_scrape({buf}, {row})      List    get row of a terminal screen
 term_sendkeys({buf}, {keys})   none    send keystrokes to a terminal
@@ -5192,6 +5193,8 @@ job_info({job})                                           *job_info()*
                Returns a Dictionary with information about {job}:
                   "status"     what |job_status()| returns
                   "channel"    what |job_getchannel()| returns
+                  "process"    process ID
+                  "tty"        controlling terminal name, empty when none
                   "exitval"    only valid when "status" is "dead"
                   "exit_cb"    function to be called on exit
                   "stoponexit" |job-stoponexit|
@@ -7930,6 +7933,7 @@ term_getcursor({buf})                                     *term_getcursor()*
 term_getjob({buf})                                     *term_getjob()*
                Get the Job associated with terminal window {buf}.
                {buf} is used as with |term_getsize()|.
+               Returns |v:null| when there is no job.
 
 term_getline({buf}, {row})                             *term_getline()*
                Get a line of text from the terminal window of {buf}.
@@ -7943,9 +7947,9 @@ term_getsize({buf})                                       *term_getsize()*
                numbers: [rows, cols].  This is the size of the terminal, not
                the window containing the terminal.
 
-               {buf} must be the buffer number of a terminal window. If the
-               buffer does not exist or is not a terminal window, an empty
-               list is returned.
+               {buf} must be the buffer number of a terminal window.  Use an
+               empty string for the current buffer.  If the buffer does not
+               exist or is not a terminal window, an empty list is returned.
 
 term_getstatus({buf})                                  *term_getstatus()*
                Get the status of terminal {buf}. This returns a comma
@@ -7967,6 +7971,11 @@ term_gettitle({buf})                                     *term_gettitle()*
                buffer does not exist or is not a terminal window, an empty
                string is returned.
 
+term_gettty({buf})                                     *term_gettty()*
+               Get the name of the controlling terminal associated with
+               terminal window {buf}.
+               {buf} is used as with |term_getsize()|.
+
 term_list()                                            *term_list()*
                Return a list with the buffer numbers of all buffers for
                terminal windows.
@@ -7982,7 +7991,7 @@ term_scrape({buf}, {row})                         *term_scrape()*
                    "chars"     character(s) at the cell
                    "fg"        foreground color as #rrggbb
                    "bg"        background color as #rrggbb
-                   "attr"      attributes of the cell, use term_getattr()
+                   "attr"      attributes of the cell, use |term_getattr()|
                                to get the individual flags
                    "width"     cell width: 1 or 2
 
index 073694ec0e15582e56e3c91392c66dbda84f90ca..be25f5ef1d44a9fc63cb6a07ebb16e390b8f6a93 100644 (file)
@@ -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);
index fc0e05dad61748c2ce3f02c6513126066b40b722..aa8b140a1a1df6a1466206a8e13667936f382108 100644 (file)
@@ -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},
index 7c4b3180e59338f214364eba6a43d04dd4fc2cf8..c90ab34f621eba26282ee5f3aec530fc75f4acab 100644 (file)
@@ -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. */
index 556f9dd61fda6046fb5fe99647f7219ef0b34679..157b6aaafbffd34ecb987b9372f55b6188677004 100644 (file)
@@ -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);
index cfe72dba8553e78a29050867971557006acee0df..522e15a98981372dedf085bc5507044279695d4a 100644 (file)
@@ -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;
index edb4b75583d1860f3f806b76f27b09c629455848..c24ac9e72e390fb12ecc9dc031af92c912957fdf 100644 (file)
  * - 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;
 
@@ -1924,6 +1932,26 @@ f_term_gettitle(typval_T *argvars, typval_T *rettv)
        rettv->vval.v_string = vim_strsave(buf->b_term->tl_title);
 }
 
+/*
+ * "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
  */
@@ -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);
index 48ee1c4eca7a93c1d420df8e6a8f4873931a01f2..cc5afc3940f298b21bcce5bfac8c106e03e6044a 100644 (file)
@@ -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)
 
index 3711461302d6d8251f09885714c6241b37ce067f..9eb8b1a91929109b37aa30179cf29335f9421df0 100644 (file)
@@ -769,6 +769,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    846,
 /**/
     845,
 /**/