* sigproc.cc (sigalloc): Don't set SA_RESTART here.
* signal.cc (_SA_NORESTART): New flag. (sigaction_worker): New function, derived from sigaction. Don't set internal flags unless called internally. (sigaction): Use sigaction_worker. (signal): Honor new _SA_NORESTART flag. (siginterrupt): Set _SA_NORESTART flag appropriately. Use sigaction_worker to set flags. * include/cygwin/signal.h: Define _SA_INTERNAL_MASK here.
This commit is contained in:
		| @@ -1,3 +1,15 @@ | |||||||
|  | 2006-03-23  Christopher Faylor  <cgf@timesys.com> | ||||||
|  |  | ||||||
|  | 	* sigproc.cc (sigalloc): Don't set SA_RESTART here. | ||||||
|  | 	* signal.cc (_SA_NORESTART): New flag. | ||||||
|  | 	(sigaction_worker): New function, derived from sigaction.  Don't set | ||||||
|  | 	internal flags unless called internally. | ||||||
|  | 	(sigaction): Use sigaction_worker. | ||||||
|  | 	(signal): Honor new _SA_NORESTART flag. | ||||||
|  | 	(siginterrupt): Set _SA_NORESTART flag appropriately.  Use | ||||||
|  | 	sigaction_worker to set flags. | ||||||
|  | 	* include/cygwin/signal.h: Define _SA_INTERNAL_MASK here. | ||||||
|  |  | ||||||
| 2006-03-22  Corinna Vinschen  <corinna@vinschen.de> | 2006-03-22  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
| 	* thread.cc (pthread_mutex::is_good_initializer_or_bad_object): Delete. | 	* thread.cc (pthread_mutex::is_good_initializer_or_bad_object): Delete. | ||||||
|   | |||||||
| @@ -215,6 +215,10 @@ struct sigaction | |||||||
| #define SA_ONESHOT   SA_RESETHAND	/* Historical linux name */ | #define SA_ONESHOT   SA_RESETHAND	/* Historical linux name */ | ||||||
| #define SA_NOMASK    SA_NODEFER		/* Historical linux name */ | #define SA_NOMASK    SA_NODEFER		/* Historical linux name */ | ||||||
|  |  | ||||||
|  | /* Used internally by cygwin.  Included here to group everything in one place. | ||||||
|  |    Do not use.  */ | ||||||
|  | #define _SA_INTERNAL_MASK 0xf000	/* bits in this range are internal */ | ||||||
|  |  | ||||||
| #define	SIGHUP	1	/* hangup */ | #define	SIGHUP	1	/* hangup */ | ||||||
| #define	SIGINT	2	/* interrupt */ | #define	SIGINT	2	/* interrupt */ | ||||||
| #define	SIGQUIT	3	/* quit */ | #define	SIGQUIT	3	/* quit */ | ||||||
|   | |||||||
| @@ -28,6 +28,11 @@ details. */ | |||||||
|  |  | ||||||
| int sigcatchers;	/* FIXME: Not thread safe. */ | int sigcatchers;	/* FIXME: Not thread safe. */ | ||||||
|  |  | ||||||
|  | #define _SA_NORESTART	0x8000 | ||||||
|  |  | ||||||
|  | static int sigaction_worker (int, const struct sigaction *, struct sigaction *, bool) | ||||||
|  |   __attribute__ ((regparm (3))); | ||||||
|  |  | ||||||
| #define sigtrapped(func) ((func) != SIG_IGN && (func) != SIG_DFL) | #define sigtrapped(func) ((func) != SIG_IGN && (func) != SIG_DFL) | ||||||
|  |  | ||||||
| static inline void | static inline void | ||||||
| @@ -62,9 +67,16 @@ signal (int sig, _sig_func_ptr func) | |||||||
|     } |     } | ||||||
|  |  | ||||||
|   prev = global_sigs[sig].sa_handler; |   prev = global_sigs[sig].sa_handler; | ||||||
|   global_sigs[sig].sa_handler = func; |   struct sigaction& gs = global_sigs[sig]; | ||||||
|   global_sigs[sig].sa_mask = 0; |   if (gs.sa_flags & _SA_NORESTART) | ||||||
|   global_sigs[sig].sa_flags &= ~SA_SIGINFO; |     gs.sa_flags &= ~SA_RESTART; | ||||||
|  |   else | ||||||
|  |     gs.sa_flags |= SA_RESTART; | ||||||
|  |  | ||||||
|  |   gs.sa_mask = 0; | ||||||
|  |   gs.sa_handler = func; | ||||||
|  |   gs.sa_flags &= ~SA_SIGINFO; | ||||||
|  |  | ||||||
|   set_sigcatchers (prev, func); |   set_sigcatchers (prev, func); | ||||||
|  |  | ||||||
|   syscall_printf ("%p = signal (%d, %p)", prev, sig, func); |   syscall_printf ("%p = signal (%d, %p)", prev, sig, func); | ||||||
| @@ -336,8 +348,8 @@ abort (void) | |||||||
|   do_exit (SIGABRT);	/* signal handler didn't exit.  Goodbye. */ |   do_exit (SIGABRT);	/* signal handler didn't exit.  Goodbye. */ | ||||||
| } | } | ||||||
|  |  | ||||||
| extern "C" int | static int | ||||||
| sigaction (int sig, const struct sigaction *newact, struct sigaction *oldact) | sigaction_worker (int sig, const struct sigaction *newact, struct sigaction *oldact, bool isinternal) | ||||||
| { | { | ||||||
|   sig_dispatch_pending (); |   sig_dispatch_pending (); | ||||||
|   /* check that sig is in right range */ |   /* check that sig is in right range */ | ||||||
| @@ -361,29 +373,41 @@ sigaction (int sig, const struct sigaction *newact, struct sigaction *oldact) | |||||||
| 	  set_errno (EINVAL); | 	  set_errno (EINVAL); | ||||||
| 	  return -1; | 	  return -1; | ||||||
| 	} | 	} | ||||||
|       struct sigaction& na = global_sigs[sig]; |       struct sigaction na = *newact; | ||||||
|       na = *newact; |       struct sigaction& gs = global_sigs[sig]; | ||||||
|       if (!(na.sa_flags & SA_NODEFER)) |       if (!isinternal) | ||||||
| 	na.sa_mask |= SIGTOMASK(sig); | 	na.sa_flags &= ~_SA_INTERNAL_MASK; | ||||||
|       if (na.sa_handler == SIG_IGN) |       gs = na; | ||||||
|  |       if (!(gs.sa_flags & SA_NODEFER)) | ||||||
|  | 	gs.sa_mask |= SIGTOMASK(sig); | ||||||
|  |       if (gs.sa_handler == SIG_IGN) | ||||||
| 	sig_clear (sig); | 	sig_clear (sig); | ||||||
|       if (na.sa_handler == SIG_DFL && sig == SIGCHLD) |       if (gs.sa_handler == SIG_DFL && sig == SIGCHLD) | ||||||
| 	sig_clear (sig); | 	sig_clear (sig); | ||||||
|       set_sigcatchers (oa.sa_handler, na.sa_handler); |       set_sigcatchers (oa.sa_handler, gs.sa_handler); | ||||||
|       if (sig == SIGCHLD) |       if (sig == SIGCHLD) | ||||||
| 	{ | 	{ | ||||||
| 	  myself->process_state &= ~PID_NOCLDSTOP; | 	  myself->process_state &= ~PID_NOCLDSTOP; | ||||||
| 	  if (na.sa_flags & SA_NOCLDSTOP) | 	  if (gs.sa_flags & SA_NOCLDSTOP) | ||||||
| 	    myself->process_state |= PID_NOCLDSTOP; | 	    myself->process_state |= PID_NOCLDSTOP; | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   if (oldact) |   if (oldact) | ||||||
|  |     { | ||||||
|       *oldact = oa; |       *oldact = oa; | ||||||
|  |       oa.sa_flags &= ~_SA_INTERNAL_MASK; | ||||||
|  |     } | ||||||
|  |  | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | extern "C" int | ||||||
|  | sigaction (int sig, const struct sigaction *newact, struct sigaction *oldact) | ||||||
|  | { | ||||||
|  |   return sigaction_worker (sig, newact, oldact, false); | ||||||
|  | } | ||||||
|  |  | ||||||
| extern "C" int | extern "C" int | ||||||
| sigaddset (sigset_t *set, const int sig) | sigaddset (sigset_t *set, const int sig) | ||||||
| { | { | ||||||
| @@ -469,10 +493,16 @@ siginterrupt (int sig, int flag) | |||||||
|   struct sigaction act; |   struct sigaction act; | ||||||
|   sigaction (sig, NULL, &act); |   sigaction (sig, NULL, &act); | ||||||
|   if (flag) |   if (flag) | ||||||
|  |     { | ||||||
|       act.sa_flags &= ~SA_RESTART; |       act.sa_flags &= ~SA_RESTART; | ||||||
|  |       act.sa_flags |= _SA_NORESTART; | ||||||
|  |     } | ||||||
|   else |   else | ||||||
|  |     { | ||||||
|  |       act.sa_flags &= ~_SA_NORESTART; | ||||||
|       act.sa_flags |= SA_RESTART; |       act.sa_flags |= SA_RESTART; | ||||||
|   return sigaction (sig, &act, NULL); |     } | ||||||
|  |   return sigaction_worker (sig, &act, NULL, true); | ||||||
| } | } | ||||||
|  |  | ||||||
| extern "C" int | extern "C" int | ||||||
|   | |||||||
| @@ -115,10 +115,6 @@ sigalloc () | |||||||
|   cygheap->sigs = global_sigs = |   cygheap->sigs = global_sigs = | ||||||
|     (struct sigaction *) ccalloc (HEAP_SIGS, NSIG, sizeof (struct sigaction)); |     (struct sigaction *) ccalloc (HEAP_SIGS, NSIG, sizeof (struct sigaction)); | ||||||
|   global_sigs[SIGSTOP].sa_flags = SA_RESTART | SA_NODEFER; |   global_sigs[SIGSTOP].sa_flags = SA_RESTART | SA_NODEFER; | ||||||
|   for (int i = 0; i < NSIG; i++) |  | ||||||
|     /* SA_RESTART is set to maintain BSD compatible signal behaviour by default. |  | ||||||
|        This is also compatible with the behaviour of signal(2) in Linux. */ |  | ||||||
|     global_sigs[i].sa_flags = SA_RESTART; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void __stdcall | void __stdcall | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user