mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									e3c330b42a
								
							
						
					
					
						commit
						30ea2f223f
					
				
					 10 changed files with 1576 additions and 3095 deletions
				
			
		| 
						 | 
					@ -327,6 +327,7 @@ Hannu Krosing
 | 
				
			||||||
Andrew Kuchling
 | 
					Andrew Kuchling
 | 
				
			||||||
Vladimir Kushnir
 | 
					Vladimir Kushnir
 | 
				
			||||||
Cameron Laird
 | 
					Cameron Laird
 | 
				
			||||||
 | 
					Andrew Langmead
 | 
				
			||||||
Detlef Lannert
 | 
					Detlef Lannert
 | 
				
			||||||
Soren Larsen
 | 
					Soren Larsen
 | 
				
			||||||
Piers Lauder
 | 
					Piers Lauder
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -656,6 +656,66 @@ setup_readline(void)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 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 */
 | 
					/* Interrupt handler */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -669,14 +729,13 @@ onintr(int sig)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Wrapper around GNU readline that handles signals differently. */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static char *
 | 
					static char *
 | 
				
			||||||
call_readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
 | 
					readline_until_enter_or_signal(char *prompt, int *signal)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	size_t n;
 | 
					 | 
				
			||||||
	char *p, *q;
 | 
					 | 
				
			||||||
	PyOS_sighandler_t old_inthandler;
 | 
						PyOS_sighandler_t old_inthandler;
 | 
				
			||||||
 | 
						char *p;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
						*signal = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	old_inthandler = PyOS_setsig(SIGINT, onintr);
 | 
						old_inthandler = PyOS_setsig(SIGINT, onintr);
 | 
				
			||||||
	if (setjmp(jbuf)) {
 | 
						if (setjmp(jbuf)) {
 | 
				
			||||||
| 
						 | 
					@ -685,8 +744,24 @@ call_readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
 | 
				
			||||||
		sigrelse(SIGINT);
 | 
							sigrelse(SIGINT);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
		PyOS_setsig(SIGINT, old_inthandler);
 | 
							PyOS_setsig(SIGINT, old_inthandler);
 | 
				
			||||||
 | 
							*signal = 1;
 | 
				
			||||||
		return NULL;
 | 
							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;
 | 
						rl_event_hook = PyOS_InputHook;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sys_stdin != rl_instream || sys_stdout != rl_outstream) {
 | 
						if (sys_stdin != rl_instream || sys_stdout != rl_outstream) {
 | 
				
			||||||
| 
						 | 
					@ -697,16 +772,22 @@ call_readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p = readline(prompt);
 | 
						p = readline_until_enter_or_signal(prompt, &signal);
 | 
				
			||||||
	PyOS_setsig(SIGINT, old_inthandler);
 | 
					 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	/* We must return a buffer allocated with PyMem_Malloc. */
 | 
						/* we got an interrupt signal */
 | 
				
			||||||
 | 
						if(signal) {
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* We got an EOF, return a empty string. */
 | 
				
			||||||
	if (p == NULL) {
 | 
						if (p == NULL) {
 | 
				
			||||||
		p = PyMem_Malloc(1);
 | 
							p = PyMem_Malloc(1);
 | 
				
			||||||
		if (p != NULL)
 | 
							if (p != NULL)
 | 
				
			||||||
			*p = '\0';
 | 
								*p = '\0';
 | 
				
			||||||
		return p;
 | 
							return p;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* we have a valid line */
 | 
				
			||||||
	n = strlen(p);
 | 
						n = strlen(p);
 | 
				
			||||||
	if (n > 0) {
 | 
						if (n > 0) {
 | 
				
			||||||
		char *line;
 | 
							char *line;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,6 +19,14 @@
 | 
				
			||||||
extern char* vms__StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt);
 | 
					extern char* vms__StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PyThreadState* _PyOS_ReadlineTState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if WITH_THREAD
 | 
				
			||||||
 | 
					#include "pythread.h"
 | 
				
			||||||
 | 
					static PyThread_type_lock _PyOS_ReadlineLock = NULL;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int (*PyOS_InputHook)(void) = NULL;
 | 
					int (*PyOS_InputHook)(void) = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef RISCOS
 | 
					#ifdef RISCOS
 | 
				
			||||||
| 
						 | 
					@ -73,10 +81,13 @@ my_fgets(char *buf, int len, FILE *fp)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
#ifdef EINTR
 | 
					#ifdef EINTR
 | 
				
			||||||
		if (errno == EINTR) {
 | 
							if (errno == EINTR) {
 | 
				
			||||||
			if (PyOS_InterruptOccurred()) {
 | 
								int s;
 | 
				
			||||||
				return 1; /* Interrupt */
 | 
								PyEval_RestoreThread(_PyOS_ReadlineTState);
 | 
				
			||||||
 | 
								s = PyErr_CheckSignals();
 | 
				
			||||||
 | 
								PyThreadState_Swap(NULL);
 | 
				
			||||||
 | 
								if (s < 0) {
 | 
				
			||||||
 | 
									return 1;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
		if (PyOS_InterruptOccurred()) {
 | 
							if (PyOS_InterruptOccurred()) {
 | 
				
			||||||
| 
						 | 
					@ -155,6 +166,13 @@ PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char *rv;
 | 
						char *rv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (_PyOS_ReadlineTState == PyThreadState_GET()) {
 | 
				
			||||||
 | 
							PyErr_SetString(PyExc_RuntimeError,
 | 
				
			||||||
 | 
									"can't re-enter readline");
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (PyOS_ReadlineFunctionPointer == NULL) {
 | 
						if (PyOS_ReadlineFunctionPointer == NULL) {
 | 
				
			||||||
#ifdef __VMS
 | 
					#ifdef __VMS
 | 
				
			||||||
                PyOS_ReadlineFunctionPointer = vms__StdioReadline;
 | 
					                PyOS_ReadlineFunctionPointer = vms__StdioReadline;
 | 
				
			||||||
| 
						 | 
					@ -163,7 +181,17 @@ PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
					#if WITH_THREAD
 | 
				
			||||||
 | 
						if (_PyOS_ReadlineLock == NULL) {
 | 
				
			||||||
 | 
							_PyOS_ReadlineLock = PyThread_allocate_lock();		
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_PyOS_ReadlineTState = PyThreadState_GET();
 | 
				
			||||||
	Py_BEGIN_ALLOW_THREADS
 | 
						Py_BEGIN_ALLOW_THREADS
 | 
				
			||||||
 | 
					#if WITH_THREAD
 | 
				
			||||||
 | 
						PyThread_acquire_lock(_PyOS_ReadlineLock, 1);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* This is needed to handle the unlikely case that the
 | 
					        /* This is needed to handle the unlikely case that the
 | 
				
			||||||
         * interpreter is in interactive mode *and* stdin/out are not
 | 
					         * interpreter is in interactive mode *and* stdin/out are not
 | 
				
			||||||
| 
						 | 
					@ -176,5 +204,12 @@ PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
 | 
				
			||||||
                rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout,
 | 
					                rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout,
 | 
				
			||||||
                                                     prompt);
 | 
					                                                     prompt);
 | 
				
			||||||
	Py_END_ALLOW_THREADS
 | 
						Py_END_ALLOW_THREADS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if WITH_THREAD
 | 
				
			||||||
 | 
						PyThread_release_lock(_PyOS_ReadlineLock);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_PyOS_ReadlineTState = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return rv;
 | 
						return rv;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1589,6 +1589,7 @@ builtin_raw_input(PyObject *self, PyObject *args)
 | 
				
			||||||
                                  prompt);
 | 
					                                  prompt);
 | 
				
			||||||
		Py_XDECREF(po);
 | 
							Py_XDECREF(po);
 | 
				
			||||||
		if (s == NULL) {
 | 
							if (s == NULL) {
 | 
				
			||||||
 | 
								if (!PyErr_Occurred())
 | 
				
			||||||
				PyErr_SetNone(PyExc_KeyboardInterrupt);
 | 
									PyErr_SetNone(PyExc_KeyboardInterrupt);
 | 
				
			||||||
			return NULL;
 | 
								return NULL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -318,7 +318,7 @@ static volatile int things_to_do = 0;
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
Py_AddPendingCall(int (*func)(void *), void *arg)
 | 
					Py_AddPendingCall(int (*func)(void *), void *arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static int busy = 0;
 | 
						static volatile int busy = 0;
 | 
				
			||||||
	int i, j;
 | 
						int i, j;
 | 
				
			||||||
	/* XXX Begin critical section */
 | 
						/* XXX Begin critical section */
 | 
				
			||||||
	/* XXX If you want this to be safe against nested
 | 
						/* XXX If you want this to be safe against nested
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1435,6 +1435,7 @@ err_input(perrdetail *err)
 | 
				
			||||||
		msg = "EOL while scanning single-quoted string";
 | 
							msg = "EOL while scanning single-quoted string";
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case E_INTR:
 | 
						case E_INTR:
 | 
				
			||||||
 | 
							if (!PyErr_Occurred())
 | 
				
			||||||
			PyErr_SetNone(PyExc_KeyboardInterrupt);
 | 
								PyErr_SetNone(PyExc_KeyboardInterrupt);
 | 
				
			||||||
		Py_XDECREF(v);
 | 
							Py_XDECREF(v);
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -119,7 +119,6 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	pthread_t th;
 | 
						pthread_t th;
 | 
				
			||||||
	int status;
 | 
						int status;
 | 
				
			||||||
 	sigset_t oldmask, newmask;
 | 
					 | 
				
			||||||
#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
 | 
					#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
 | 
				
			||||||
	pthread_attr_t attrs;
 | 
						pthread_attr_t attrs;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -137,13 +136,6 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
 | 
				
			||||||
        pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
 | 
					        pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Mask all signals in the current thread before creating the new
 | 
					 | 
				
			||||||
	 * thread.  This causes the new thread to start with all signals
 | 
					 | 
				
			||||||
	 * blocked.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	sigfillset(&newmask);
 | 
					 | 
				
			||||||
	SET_THREAD_SIGMASK(SIG_BLOCK, &newmask, &oldmask);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	status = pthread_create(&th, 
 | 
						status = pthread_create(&th, 
 | 
				
			||||||
#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
 | 
					#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
 | 
				
			||||||
				 &attrs,
 | 
									 &attrs,
 | 
				
			||||||
| 
						 | 
					@ -154,9 +146,6 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
 | 
				
			||||||
				 (void *)arg
 | 
									 (void *)arg
 | 
				
			||||||
				 );
 | 
									 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Restore signal mask for original thread */
 | 
					 | 
				
			||||||
	SET_THREAD_SIGMASK(SIG_SETMASK, &oldmask, NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
 | 
					#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
 | 
				
			||||||
	pthread_attr_destroy(&attrs);
 | 
						pthread_attr_destroy(&attrs);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										16
									
								
								configure.in
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								configure.in
									
										
									
									
									
								
							| 
						 | 
					@ -2783,6 +2783,11 @@ then
 | 
				
			||||||
  [Define this if you have flockfile(), getc_unlocked(), and funlockfile()])
 | 
					  [Define this if you have flockfile(), getc_unlocked(), and funlockfile()])
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# check for readline 2.1
 | 
				
			||||||
 | 
					AC_CHECK_LIB(readline, rl_callback_handler_install,
 | 
				
			||||||
 | 
						AC_DEFINE(HAVE_RL_CALLBACK, 1,
 | 
				
			||||||
 | 
					        [Define if you have readline 2.1]), , -ltermcap)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# check for readline 2.2
 | 
					# check for readline 2.2
 | 
				
			||||||
AC_TRY_CPP([#include <readline/readline.h>],
 | 
					AC_TRY_CPP([#include <readline/readline.h>],
 | 
				
			||||||
have_readline=yes, have_readline=no)
 | 
					have_readline=yes, have_readline=no)
 | 
				
			||||||
| 
						 | 
					@ -2804,6 +2809,17 @@ AC_CHECK_LIB(readline, rl_completion_matches,
 | 
				
			||||||
	AC_DEFINE(HAVE_RL_COMPLETION_MATCHES, 1,
 | 
						AC_DEFINE(HAVE_RL_COMPLETION_MATCHES, 1,
 | 
				
			||||||
        [Define if you have readline 4.2]), , -ltermcap)
 | 
					        [Define if you have readline 4.2]), , -ltermcap)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# also in readline 4.2
 | 
				
			||||||
 | 
					AC_TRY_CPP([#include <readline/readline.h>],
 | 
				
			||||||
 | 
					have_readline=yes, have_readline=no)
 | 
				
			||||||
 | 
					if test $have_readline = yes
 | 
				
			||||||
 | 
					then
 | 
				
			||||||
 | 
					  AC_EGREP_HEADER([extern int rl_catch_signals;],
 | 
				
			||||||
 | 
					  [readline/readline.h],
 | 
				
			||||||
 | 
					  AC_DEFINE(HAVE_RL_CATCH_SIGNAL, 1,
 | 
				
			||||||
 | 
					  [Define if you can turn off readline's signal handling.]), )
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AC_MSG_CHECKING(for broken nice())
 | 
					AC_MSG_CHECKING(for broken nice())
 | 
				
			||||||
AC_CACHE_VAL(ac_cv_broken_nice, [
 | 
					AC_CACHE_VAL(ac_cv_broken_nice, [
 | 
				
			||||||
AC_TRY_RUN([
 | 
					AC_TRY_RUN([
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -359,6 +359,12 @@
 | 
				
			||||||
/* Define to 1 if you have the `realpath' function. */
 | 
					/* Define to 1 if you have the `realpath' function. */
 | 
				
			||||||
#undef HAVE_REALPATH
 | 
					#undef HAVE_REALPATH
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Define if you have readline 2.1 */
 | 
				
			||||||
 | 
					#undef HAVE_RL_CALLBACK
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Define if you can turn off readline's signal handling. */
 | 
				
			||||||
 | 
					#undef HAVE_RL_CATCH_SIGNAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Define if you have readline 2.2 */
 | 
					/* Define if you have readline 2.2 */
 | 
				
			||||||
#undef HAVE_RL_COMPLETION_APPEND_CHARACTER
 | 
					#undef HAVE_RL_COMPLETION_APPEND_CHARACTER
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue