Patch 8.0.1761
Problem:    Job in terminal window with no output channel is killed.
Solution:   Keep the job running when the input is a tty. (Ozaki Kiichi,
            closes #2734)
Files:      src/channel.c, src/os_unix.c, src/testdir/test_channel.vim


*** ../vim-8.0.1760/src/channel.c       2018-04-21 23:34:38.522654097 +0200
--- src/channel.c       2018-04-24 20:47:41.251850354 +0200
***************
*** 345,350 ****
--- 345,359 ----
  }
  
  /*
+  * Return TRUE if "channel" is closeable (i.e. all readable fds are closed).
+  */
+     static int
+ channel_can_close(channel_T *channel)
+ {
+     return channel->ch_to_be_closed == 0;
+ }
+ 
+ /*
   * Close a channel and free all its resources.
   */
      static void
***************
*** 892,898 ****
      channel->ch_nb_close_cb = nb_close_cb;
      channel->ch_hostname = (char *)vim_strsave((char_u *)hostname);
      channel->ch_port = port_in;
!     channel->ch_to_be_closed |= (1 << PART_SOCK);
  
  #ifdef FEAT_GUI
      channel_gui_register_one(channel, PART_SOCK);
--- 901,907 ----
      channel->ch_nb_close_cb = nb_close_cb;
      channel->ch_hostname = (char *)vim_strsave((char_u *)hostname);
      channel->ch_port = port_in;
!     channel->ch_to_be_closed |= (1U << PART_SOCK);
  
  #ifdef FEAT_GUI
      channel_gui_register_one(channel, PART_SOCK);
***************
*** 988,994 ****
        }
        *fd = INVALID_FD;
  
!       channel->ch_to_be_closed &= ~(1 << part);
      }
  }
  
--- 997,1004 ----
        }
        *fd = INVALID_FD;
  
!       /* channel is closed, may want to end the job if it was the last */
!       channel->ch_to_be_closed &= ~(1U << part);
      }
  }
  
***************
*** 999,1004 ****
--- 1009,1020 ----
      {
        ch_close_part(channel, PART_IN);
        channel->CH_IN_FD = in;
+ # if defined(UNIX)
+       /* Do not end the job when all output channels are closed, wait until
+        * the job ended. */
+       if (isatty(in))
+           channel->ch_to_be_closed |= (1U << PART_IN);
+ # endif
      }
      if (out != INVALID_FD)
      {
***************
*** 1007,1013 ****
  # endif
        ch_close_part(channel, PART_OUT);
        channel->CH_OUT_FD = out;
!       channel->ch_to_be_closed |= (1 << PART_OUT);
  # if defined(FEAT_GUI)
        channel_gui_register_one(channel, PART_OUT);
  # endif
--- 1023,1029 ----
  # endif
        ch_close_part(channel, PART_OUT);
        channel->CH_OUT_FD = out;
!       channel->ch_to_be_closed |= (1U << PART_OUT);
  # if defined(FEAT_GUI)
        channel_gui_register_one(channel, PART_OUT);
  # endif
***************
*** 1019,1025 ****
  # endif
        ch_close_part(channel, PART_ERR);
        channel->CH_ERR_FD = err;
!       channel->ch_to_be_closed |= (1 << PART_ERR);
  # if defined(FEAT_GUI)
        channel_gui_register_one(channel, PART_ERR);
  # endif
--- 1035,1041 ----
  # endif
        ch_close_part(channel, PART_ERR);
        channel->CH_ERR_FD = err;
!       channel->ch_to_be_closed |= (1U << PART_ERR);
  # if defined(FEAT_GUI)
        channel_gui_register_one(channel, PART_ERR);
  # endif
***************
*** 4200,4208 ****
      }
      while (channel != NULL)
      {
!       if (channel->ch_to_be_closed == 0)
        {
!           channel->ch_to_be_closed = (1 << PART_COUNT);
            channel_close_now(channel);
            /* channel may have been freed, start over */
            channel = first_channel;
--- 4216,4224 ----
      }
      while (channel != NULL)
      {
!       if (channel_can_close(channel))
        {
!           channel->ch_to_be_closed = (1U << PART_COUNT);
            channel_close_now(channel);
            /* channel may have been freed, start over */
            channel = first_channel;
***************
*** 5080,5085 ****
--- 5096,5110 ----
  }
  
  /*
+  * Return TRUE if the channel of "job" is closeable.
+  */
+     static int
+ job_channel_can_close(job_T *job)
+ {
+     return job->jv_channel != NULL && channel_can_close(job->jv_channel);
+ }
+ 
+ /*
   * Return TRUE if the job should not be freed yet.  Do not free the job when
   * it has not ended yet and there is a "stoponexit" flag, an exit callback
   * or when the associated channel will do something with the job output.
***************
*** 5209,5214 ****
--- 5234,5243 ----
      /* Ready to cleanup the job. */
      job->jv_status = JOB_FINISHED;
  
+     /* When only channel-in is kept open, close explicitly. */
+     if (job->jv_channel != NULL)
+       ch_close_part(job->jv_channel, PART_IN);
+ 
      if (job->jv_exit_cb != NULL)
      {
        typval_T        argv[3];
***************
*** 5413,5420 ****
      for (job = first_job; job != NULL; job = job->jv_next)
        /* Only should check if the channel has been closed, if the channel is
         * open the job won't exit. */
!       if (job->jv_status == JOB_STARTED && job->jv_exit_cb != NULL
!                                           && !job_channel_still_useful(job))
            return TRUE;
      return FALSE;
  }
--- 5442,5450 ----
      for (job = first_job; job != NULL; job = job->jv_next)
        /* Only should check if the channel has been closed, if the channel is
         * open the job won't exit. */
!       if ((job->jv_status == JOB_STARTED && !job_channel_still_useful(job))
!                   || (job->jv_status == JOB_FINISHED
!                                             && job_channel_can_close(job)))
            return TRUE;
      return FALSE;
  }
*** ../vim-8.0.1760/src/os_unix.c       2018-04-24 15:19:00.507068755 +0200
--- src/os_unix.c       2018-04-24 20:42:04.561485179 +0200
***************
*** 5638,5650 ****
        close(fd_err[1]);
      if (channel != NULL)
      {
!       channel_set_pipes(channel,
!               use_file_for_in || use_null_for_in
!                       ? INVALID_FD : fd_in[1] < 0 ? pty_master_fd : fd_in[1],
!               use_file_for_out || use_null_for_out
!                     ? INVALID_FD : fd_out[0] < 0 ? pty_master_fd : fd_out[0],
!               use_out_for_err || use_file_for_err || use_null_for_err
!                    ? INVALID_FD : fd_err[0] < 0 ? pty_master_fd : fd_err[0]);
        channel_set_job(channel, job, options);
      }
      else
--- 5638,5651 ----
        close(fd_err[1]);
      if (channel != NULL)
      {
!       int in_fd = use_file_for_in || use_null_for_in
!                       ? INVALID_FD : fd_in[1] < 0 ? pty_master_fd : fd_in[1];
!       int out_fd = use_file_for_out || use_null_for_out
!                     ? INVALID_FD : fd_out[0] < 0 ? pty_master_fd : fd_out[0];
!       int err_fd = use_out_for_err || use_file_for_err || use_null_for_err
!                     ? INVALID_FD : fd_err[0] < 0 ? pty_master_fd : fd_err[0];
! 
!       channel_set_pipes(channel, in_fd, out_fd, err_fd);
        channel_set_job(channel, job, options);
      }
      else
*** ../vim-8.0.1760/src/testdir/test_channel.vim        2018-04-21 
19:49:02.528104537 +0200
--- src/testdir/test_channel.vim        2018-04-24 20:42:04.565485223 +0200
***************
*** 1848,1850 ****
--- 1848,1861 ----
    call assert_match("%s%s", text[2])
    call delete('Xlog')
  endfunc
+ 
+ func Test_keep_pty_open()
+   if !has('unix')
+     return
+   endif
+ 
+   let job = job_start(s:python . ' -c "import time;time.sleep(0.2)"', 
{'out_io': 'null', 'err_io': 'null', 'pty': 1})
+   let elapsed = WaitFor({-> job_status(job) ==# 'dead'})
+   call assert_inrange(200, 1000, elapsed)
+   call job_stop(job)
+ endfunc
*** ../vim-8.0.1760/src/version.c       2018-04-24 20:27:22.912114599 +0200
--- src/version.c       2018-04-24 20:49:27.656178358 +0200
***************
*** 763,764 ****
--- 763,766 ----
  {   /* Add new patch number below this line */
+ /**/
+     1761,
  /**/

-- 
       We're knights of the Round Table
       Our shows are formidable
       But many times
       We're given rhymes
       That are quite unsingable
       We're opera mad in Camelot
       We sing from the diaphragm a lot.
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui