[Python-checkins] python/dist/src/Modules readline.c,2.70,2.71

mwh at users.sourceforge.net mwh at users.sourceforge.net
Wed Jul 7 19:44:13 CEST 2004


Update of /cvsroot/python/python/dist/src/Modules
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18275/Modules

Modified Files:
	readline.c 
Log Message:
This closes patch:

[ 960406 ] unblock signals in threads

although the changes do not correspond exactly to any patch attached to
that report.

Non-main threads no longer have all signals masked.

A different interface to readline is used.

The handling of signals inside calls to PyOS_Readline is now rather 
different.

These changes are all a bit scary!  Review and cross-platform testing
much appreciated.



Index: readline.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/readline.c,v
retrieving revision 2.70
retrieving revision 2.71
diff -C2 -d -r2.70 -r2.71
*** readline.c	24 May 2004 14:20:15 -0000	2.70
--- readline.c	7 Jul 2004 17:44:10 -0000	2.71
***************
*** 657,660 ****
--- 657,720 ----
  }
  
+ /* Wrapper around GNU readline that handles signals differently. */
+ 
+ 
+ #if defined(HAVE_RL_CALLBACK) && defined(HAVE_SELECT)
+ 
+ static	char *completed_input_string;
+ static void
+ rlhandler(char *text)
+ {
+ 	completed_input_string = text;
+ 	rl_callback_handler_remove();
+ }
+ 
+ extern PyThreadState* _PyOS_ReadlineTState;
+ 
+ static char *
+ readline_until_enter_or_signal(char *prompt, int *signal)
+ {
+ 	char * not_done_reading = "";
+ 	fd_set selectset;
+ 
+ 	*signal = 0;
+ #ifdef HAVE_RL_CATCH_SIGNAL
+ 	rl_catch_signals = 0;
+ #endif
+ 
+ 	rl_callback_handler_install (prompt, rlhandler);
+ 	FD_ZERO(&selectset);
+ 	FD_SET(fileno(rl_instream), &selectset);
+ 	
+ 	completed_input_string = not_done_reading;
+ 
+ 	while(completed_input_string == not_done_reading) {
+ 		int has_input;
+ 
+ 		has_input = select(fileno(rl_instream) + 1, &selectset,
+ 				   NULL, NULL, NULL);
+ 		if(has_input > 0) {
+ 			rl_callback_read_char();
+ 		}
+ 		else if (errno == EINTR) {
+ 			int s;
+ 			PyEval_RestoreThread(_PyOS_ReadlineTState);
+ 			s = PyErr_CheckSignals();
+ 			PyThreadState_Swap(NULL);	
+ 			if (s < 0) {
+ 				rl_free_line_state();
+ 				rl_cleanup_after_signal();
+ 				rl_callback_handler_remove();
+ 				*signal = 1;
+ 				completed_input_string = NULL;
+ 			}
+ 		}
+ 	}
+ 
+ 	return completed_input_string;
+ }
+ 
+ 
+ #else
  
  /* Interrupt handler */
***************
*** 670,681 ****
  
  
- /* Wrapper around GNU readline that handles signals differently. */
- 
  static char *
! call_readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
  {
- 	size_t n;
- 	char *p, *q;
  	PyOS_sighandler_t old_inthandler;
  
  	old_inthandler = PyOS_setsig(SIGINT, onintr);
--- 730,740 ----
  
  
  static char *
! readline_until_enter_or_signal(char *prompt, int *signal)
  {
  	PyOS_sighandler_t old_inthandler;
+ 	char *p;
+     
+ 	*signal = 0;
  
  	old_inthandler = PyOS_setsig(SIGINT, onintr);
***************
*** 686,691 ****
--- 745,766 ----
  #endif
  		PyOS_setsig(SIGINT, old_inthandler);
+ 		*signal = 1;
  		return NULL;
  	}
+ 	p = readline(prompt);
+ 	PyOS_setsig(SIGINT, old_inthandler);
+ 
+     return p;
+ }
+ #endif /*defined(HAVE_RL_CALLBACK) && defined(HAVE_SELECT) */
+ 
+ 
+ static char *
+ call_readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
+ {
+ 	size_t n;
+ 	char *p, *q;
+ 	int signal;
+ 
  	rl_event_hook = PyOS_InputHook;
  
***************
*** 698,705 ****
  	}
  
! 	p = readline(prompt);
! 	PyOS_setsig(SIGINT, old_inthandler);
  
! 	/* We must return a buffer allocated with PyMem_Malloc. */
  	if (p == NULL) {
  		p = PyMem_Malloc(1);
--- 773,784 ----
  	}
  
! 	p = readline_until_enter_or_signal(prompt, &signal);
! 	
! 	/* we got an interrupt signal */
! 	if(signal) {
! 		return NULL;
! 	}
  
! 	/* We got an EOF, return a empty string. */
  	if (p == NULL) {
  		p = PyMem_Malloc(1);
***************
*** 708,711 ****
--- 787,792 ----
  		return p;
  	}
+ 
+ 	/* we have a valid line */
  	n = strlen(p);
  	if (n > 0) {



More information about the Python-checkins mailing list