@@ -169,41 +169,47 @@ checksignals_witharg(void * unused)
169169static void
170170signal_handler (int sig_num )
171171{
172- #ifdef WITH_THREAD
173- #ifdef WITH_PTH
172+ int save_errno = errno ;
173+
174+ #if defined(WITH_THREAD ) && defined(WITH_PTH )
174175 if (PyThread_get_thread_ident () != main_thread ) {
175176 pth_raise (* (pth_t * ) main_thread , sig_num );
176- return ;
177177 }
178+ else
178179#endif
180+ {
181+ #ifdef WITH_THREAD
179182 /* See NOTES section above */
180- if (getpid () == main_pid ) {
183+ if (getpid () == main_pid )
181184#endif
185+ {
182186 Handlers [sig_num ].tripped = 1 ;
183187 /* Set is_tripped after setting .tripped, as it gets
184188 cleared in PyErr_CheckSignals() before .tripped. */
185189 is_tripped = 1 ;
186190 Py_AddPendingCall (checksignals_witharg , NULL );
187191 if (wakeup_fd != -1 )
188192 write (wakeup_fd , "\0" , 1 );
189- #ifdef WITH_THREAD
190193 }
191- #endif
194+
195+ #ifndef HAVE_SIGACTION
192196#ifdef SIGCHLD
193- if (sig_num == SIGCHLD ) {
194- /* To avoid infinite recursion, this signal remains
195- reset until explicit re-instated.
196- Don't clear the 'func' field as it is our pointer
197- to the Python handler... */
198- return ;
199- }
197+ /* To avoid infinite recursion, this signal remains
198+ reset until explicit re-instated.
199+ Don't clear the 'func' field as it is our pointer
200+ to the Python handler... */
201+ if (sig_num != SIGCHLD )
200202#endif
201- #ifndef HAVE_SIGACTION
202203 /* If the handler was not set up with sigaction, reinstall it. See
203204 * Python/pythonrun.c for the implementation of PyOS_setsig which
204205 * makes this true. See also issue8354. */
205206 PyOS_setsig (sig_num , signal_handler );
206207#endif
208+ }
209+
210+ /* Issue #10311: asynchronously executing signal handlers should not
211+ mutate errno under the feet of unsuspecting C code. */
212+ errno = save_errno ;
207213}
208214
209215
0 commit comments