Cygwin: pty: Fix the behaviour of Ctrl-C in the pseudo console mode.
- When the I/O pipe is switched to the pseudo console side, the behaviour of Ctrl-C was unstable. This rarely happens, however, for example, shell sometimes crashes by Ctrl-C in that situation. Furthermore, Ctrl-C was ignored if output of non-cygwin program is redirected to pipe. This patch fixes these issues.
This commit is contained in:
		| @@ -2187,10 +2187,6 @@ class fhandler_pty_slave: public fhandler_pty_common | ||||
|     get_ttyp ()->mask_switch_to_pcon = mask; | ||||
|   } | ||||
|   void fixup_after_attach (bool native_maybe); | ||||
|   pid_t get_pcon_pid (void) | ||||
|   { | ||||
|     return get_ttyp ()->pcon_pid; | ||||
|   } | ||||
|   bool is_line_input (void) | ||||
|   { | ||||
|     return get_ttyp ()->ti.c_lflag & ICANON; | ||||
|   | ||||
| @@ -895,6 +895,7 @@ fhandler_pty_slave::close () | ||||
|     termios_printf ("CloseHandle (output_mutex<%p>), %E", output_mutex); | ||||
|   if (pcon_attached_to == get_minor ()) | ||||
|     get_ttyp ()->num_pcon_attached_slaves --; | ||||
|   get_ttyp ()->mask_switch_to_pcon = false; | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| @@ -1026,20 +1027,26 @@ fhandler_pty_slave::reset_switch_to_pcon (void) | ||||
|       get_ttyp ()->need_clear_screen = false; | ||||
|     } | ||||
|  | ||||
|   if (ALWAYS_USE_PCON) | ||||
|     return; | ||||
|   if (isHybrid) | ||||
|     { | ||||
|       this->set_switch_to_pcon (); | ||||
|       return; | ||||
|     } | ||||
|     this->set_switch_to_pcon (); | ||||
|   if (get_ttyp ()->pcon_pid && | ||||
|       get_ttyp ()->pcon_pid != myself->pid && | ||||
|       kill (get_ttyp ()->pcon_pid, 0) == 0) | ||||
|     /* There is a process which is grabbing pseudo console. */ | ||||
|     return; | ||||
|   if (get_ttyp ()->switch_to_pcon && | ||||
|       get_ttyp ()->pcon_pid != myself->pid) | ||||
|   if (isHybrid) | ||||
|     { | ||||
|       if (ALWAYS_USE_PCON) | ||||
| 	{ | ||||
| 	  DWORD mode; | ||||
| 	  GetConsoleMode (get_handle (), &mode); | ||||
| 	  SetConsoleMode (get_handle (), mode & ~ENABLE_PROCESSED_INPUT); | ||||
| 	} | ||||
|       get_ttyp ()->pcon_pid = 0; | ||||
|       init_console_handler (true); | ||||
|       return; | ||||
|     } | ||||
|   if (get_ttyp ()->switch_to_pcon) | ||||
|     { | ||||
|       DWORD mode; | ||||
|       GetConsoleMode (get_handle (), &mode); | ||||
| @@ -1048,6 +1055,7 @@ fhandler_pty_slave::reset_switch_to_pcon (void) | ||||
|     } | ||||
|   get_ttyp ()->pcon_pid = 0; | ||||
|   get_ttyp ()->switch_to_pcon = false; | ||||
|   init_console_handler (true); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -1307,8 +1315,7 @@ fhandler_pty_slave::read (void *ptr, size_t& len) | ||||
|   if (ptr) /* Indicating not tcflush(). */ | ||||
|     { | ||||
|       reset_switch_to_pcon (); | ||||
|       if (get_ttyp ()->pcon_pid != myself->pid) | ||||
| 	mask_switch_to_pcon (true); | ||||
|       mask_switch_to_pcon (true); | ||||
|     } | ||||
|  | ||||
|   if (is_nonblocking () || !ptr) /* Indicating tcflush(). */ | ||||
| @@ -1428,7 +1435,7 @@ fhandler_pty_slave::read (void *ptr, size_t& len) | ||||
| 	    flags &= ~ENABLE_ECHO_INPUT; | ||||
| 	  if ((get_ttyp ()->ti.c_lflag & ISIG) && | ||||
| 	      !(get_ttyp ()->ti.c_iflag & IGNBRK)) | ||||
| 	    flags |= ENABLE_PROCESSED_INPUT; | ||||
| 	    flags |= ALWAYS_USE_PCON ? 0 : ENABLE_PROCESSED_INPUT; | ||||
| 	  if (dwMode != flags) | ||||
| 	    SetConsoleMode (get_handle (), flags); | ||||
| 	  /* Read get_handle() instad of get_handle_cyg() */ | ||||
| @@ -2222,6 +2229,16 @@ fhandler_pty_master::write (const void *ptr, size_t len) | ||||
|       return len; | ||||
|     } | ||||
|  | ||||
|   if (get_ttyp ()->switch_to_pcon && | ||||
|       (ti.c_lflag & ISIG) && | ||||
|       memchr (p, ti.c_cc[VINTR], len) && | ||||
|       get_ttyp ()->getpgid () == get_ttyp ()->pcon_pid) | ||||
|     { | ||||
|       DWORD n; | ||||
|       /* Send ^C to pseudo console as well */ | ||||
|       WriteFile (to_slave, "\003", 1, &n, 0); | ||||
|     } | ||||
|  | ||||
|   line_edit_status status = line_edit (p++, len, ti, &ret); | ||||
|   if (status > line_edit_signalled && status != line_edit_pipe_full) | ||||
|     ret = -1; | ||||
| @@ -2875,8 +2892,10 @@ fhandler_pty_slave::fixup_after_attach (bool native_maybe) | ||||
| 	      get_ttyp ()->num_pcon_attached_slaves ++; | ||||
| 	    } | ||||
| 	} | ||||
|       if (ALWAYS_USE_PCON && pcon_attached_to == get_minor ()) | ||||
| 	set_ishybrid_and_switch_to_pcon (get_output_handle ()); | ||||
|     } | ||||
|   if (pcon_attached_to == get_minor () && (native_maybe || ALWAYS_USE_PCON)) | ||||
|   if (pcon_attached_to == get_minor () && native_maybe) | ||||
|     { | ||||
|       FlushConsoleInputBuffer (get_handle ()); | ||||
|       DWORD mode; | ||||
| @@ -2891,6 +2910,7 @@ fhandler_pty_slave::fixup_after_attach (bool native_maybe) | ||||
| 	  kill (get_ttyp ()->pcon_pid, 0) != 0) | ||||
| 	get_ttyp ()->pcon_pid = myself->pid; | ||||
|       get_ttyp ()->switch_to_pcon = true; | ||||
|       init_console_handler(false); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1294,7 +1294,7 @@ pty_slave_startup (select_record *me, select_stuff *stuff) | ||||
| { | ||||
|   fhandler_base *fh = (fhandler_base *) me->fh; | ||||
|   fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh; | ||||
|   if (me->read_selected && ptys->get_pcon_pid () != myself->pid) | ||||
|   if (me->read_selected) | ||||
|     ptys->mask_switch_to_pcon (true); | ||||
|  | ||||
|   select_pipe_info *pi = stuff->device_specific_ptys; | ||||
|   | ||||
| @@ -261,6 +261,21 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, | ||||
|   int res = -1; | ||||
|   DWORD pidRestore = 0; | ||||
|   bool attach_to_pcon = false; | ||||
|   pid_t ctty_pgid = 0; | ||||
|  | ||||
|   /* Search for CTTY and retrieve its PGID */ | ||||
|   cygheap_fdenum cfd (false); | ||||
|   while (cfd.next () >= 0) | ||||
|     if (cfd->get_major () == DEV_PTYS_MAJOR || | ||||
| 	cfd->get_major () == DEV_CONS_MAJOR) | ||||
|       { | ||||
| 	fhandler_termios *fh = (fhandler_termios *) (fhandler_base *) cfd; | ||||
| 	if (fh->tc ()->ntty == myself->ctty) | ||||
| 	  { | ||||
| 	    ctty_pgid = fh->tc ()->getpgid (); | ||||
| 	    break; | ||||
| 	  } | ||||
|       } | ||||
|  | ||||
|   /* Check if we have been called from exec{lv}p or spawn{lv}p and mask | ||||
|      mode to keep only the spawn mode. */ | ||||
| @@ -539,8 +554,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, | ||||
| 	 in a console will break native processes running in the background, | ||||
| 	 because the Ctrl-C event is sent to all processes in the console, unless | ||||
| 	 they ignore it explicitely.  CREATE_NEW_PROCESS_GROUP does that for us. */ | ||||
|       if (!iscygwin () && fhandler_console::exists () | ||||
| 	  && fhandler_console::tc_getpgid () != myself->pgid) | ||||
|       if (!iscygwin () && ctty_pgid && ctty_pgid != myself->pgid) | ||||
| 	c_flags |= CREATE_NEW_PROCESS_GROUP; | ||||
|       refresh_cygheap (); | ||||
|  | ||||
| @@ -606,33 +620,11 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, | ||||
| 			  attach_to_pcon = true; | ||||
| 			  break; | ||||
| 			} | ||||
| 		      else | ||||
| 			{ | ||||
| 			  /* Fallback */ | ||||
| 			  DWORD target[3] = { | ||||
| 			    STD_INPUT_HANDLE, | ||||
| 			    STD_OUTPUT_HANDLE, | ||||
| 			    STD_ERROR_HANDLE | ||||
| 			  }; | ||||
| 			  if (fd == 0) | ||||
| 			    { | ||||
| 			      ptys->set_handle (ptys->get_handle_cyg ()); | ||||
| 			      SetStdHandle (target[fd], | ||||
| 					    ptys->get_handle ()); | ||||
| 			    } | ||||
| 			  else if (fd < 3) | ||||
| 			    { | ||||
| 			      ptys->set_output_handle ( | ||||
| 					   ptys->get_output_handle_cyg ()); | ||||
| 			      SetStdHandle (target[fd], | ||||
| 					    ptys->get_output_handle ()); | ||||
| 			    } | ||||
| 			} | ||||
| 		    } | ||||
| 		} | ||||
| 	    } | ||||
| 	} | ||||
|       if (ptys) | ||||
|       if (ptys && attach_to_pcon) | ||||
| 	ptys->fixup_after_attach (!iscygwin ()); | ||||
|  | ||||
|       if (!iscygwin ()) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user