* sigproc.h (class sigframe): Implement 'unregister()' method.
(sigframe::~sigframe): Use unregister method. (sigframe::call_signal_handler): Declare new method. * exceptions.cc (sigframe::call_signal_handler): New method. Unregisters current sigframe before calling signal handler. (setup_handler): Clear waiting threads prior to arming signal_arrived. * syscalls.cc (_read): Change goto to loop. Recalculate sigframe inside of loop so that constructor is called when appropriate. * wait.cc (wait4): Ditto. * signal.cc: Change "sig" to "signal" in debugging messages throughout. * sigproc.cc: Ditto.
This commit is contained in:
		| @@ -1,3 +1,18 @@ | ||||
| Sat Mar 31 18:59:52 2001  Christopher Faylor <cgf@cygnus.com> | ||||
|  | ||||
| 	* sigproc.h (class sigframe): Implement 'unregister()' method. | ||||
| 	(sigframe::~sigframe): Use unregister method. | ||||
| 	(sigframe::call_signal_handler): Declare new method. | ||||
| 	* exceptions.cc (sigframe::call_signal_handler): New method. | ||||
| 	Unregisters current sigframe before calling signal handler. | ||||
| 	(setup_handler): Clear waiting threads prior to arming signal_arrived. | ||||
| 	* syscalls.cc (_read): Change goto to loop.  Recalculate sigframe | ||||
| 	inside of loop so that constructor is called when appropriate. | ||||
| 	* wait.cc (wait4): Ditto. | ||||
|  | ||||
| 	* signal.cc: Change "sig" to "signal" in debugging messages throughout. | ||||
| 	* sigproc.cc: Ditto. | ||||
|  | ||||
| Sat Mar 31 17:12:08 2001  Christopher Faylor <cgf@cygnus.com> | ||||
|  | ||||
| 	* fhandler_serial.cc (fhandler_serial::raw_write): Close protected | ||||
|   | ||||
| @@ -864,10 +864,10 @@ setup_handler (int sig, void *handler, struct sigaction& siga) | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       res = SetEvent (signal_arrived);	// For an EINTR case | ||||
|       sigproc_printf ("armed signal_arrived %p, res %d", signal_arrived, res); | ||||
|       /* Clear any waiting threads prior to dispatching to handler function */ | ||||
|       proc_subproc (PROC_CLEARWAIT, 1); | ||||
|       res = SetEvent (signal_arrived);	// For an EINTR case | ||||
|       sigproc_printf ("armed signal_arrived %p, res %d", signal_arrived, res); | ||||
|     } | ||||
|  | ||||
|   if (th) | ||||
| @@ -1127,6 +1127,13 @@ reset_signal_arrived () | ||||
|   sigproc_printf ("reset signal_arrived"); | ||||
| } | ||||
|  | ||||
| int | ||||
| sigframe::call_signal_handler () | ||||
| { | ||||
|   unregister (); | ||||
|   ::call_signal_handler (); | ||||
| } | ||||
|  | ||||
| int __stdcall | ||||
| call_signal_handler () | ||||
| { | ||||
|   | ||||
| @@ -99,7 +99,7 @@ sigprocmask (int sig, const sigset_t *set, sigset_t *oldset) | ||||
|   if (sig < 0 || sig >= NSIG) | ||||
|     { | ||||
|       set_errno (EINVAL); | ||||
|       syscall_printf ("SIG_ERR = sigprocmask sig %d out of range", sig); | ||||
|       syscall_printf ("SIG_ERR = sigprocmask signal %d out of range", sig); | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
| @@ -182,7 +182,7 @@ _kill (pid_t pid, int sig) | ||||
|   if (sig < 0 || sig >= NSIG) | ||||
|     { | ||||
|       set_errno (EINVAL); | ||||
|       syscall_printf ("sig %d out of range", sig); | ||||
|       syscall_printf ("signal %d out of range", sig); | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
| @@ -202,7 +202,7 @@ kill_pgrp (pid_t pid, int sig) | ||||
|   int found = 0; | ||||
|   int killself = 0; | ||||
|  | ||||
|   sigproc_printf ("pid %d, sig %d", pid, sig); | ||||
|   sigproc_printf ("pid %d, signal %d", pid, sig); | ||||
|  | ||||
|   winpids pids; | ||||
|   for (unsigned i = 0; i < pids.npids; i++) | ||||
| @@ -247,12 +247,12 @@ killpg (pid_t pgrp, int sig) | ||||
| extern "C" int | ||||
| sigaction (int sig, const struct sigaction *newact, struct sigaction *oldact) | ||||
| { | ||||
|   sigproc_printf ("sig %d, newact %p, oldact %p", sig, newact, oldact); | ||||
|   sigproc_printf ("signal %d, newact %p, oldact %p", sig, newact, oldact); | ||||
|   /* check that sig is in right range */ | ||||
|   if (sig < 0 || sig >= NSIG) | ||||
|     { | ||||
|       set_errno (EINVAL); | ||||
|       syscall_printf ("SIG_ERR = sigaction sig %d out of range", sig); | ||||
|       syscall_printf ("SIG_ERR = sigaction signal %d out of range", sig); | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
| @@ -286,7 +286,7 @@ sigaddset (sigset_t *set, const int sig) | ||||
|   if (sig <= 0 || sig >= NSIG) | ||||
|     { | ||||
|       set_errno (EINVAL); | ||||
|       syscall_printf ("SIG_ERR = sigaddset sig %d out of range", sig); | ||||
|       syscall_printf ("SIG_ERR = sigaddset signal %d out of range", sig); | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
| @@ -301,7 +301,7 @@ sigdelset (sigset_t *set, const int sig) | ||||
|   if (sig <= 0 || sig >= NSIG) | ||||
|     { | ||||
|       set_errno (EINVAL); | ||||
|       syscall_printf ("SIG_ERR = sigdelset sig %d out of range", sig); | ||||
|       syscall_printf ("SIG_ERR = sigdelset signal %d out of range", sig); | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
| @@ -316,7 +316,7 @@ sigismember (const sigset_t *set, int sig) | ||||
|   if (sig <= 0 || sig >= NSIG) | ||||
|     { | ||||
|       set_errno (EINVAL); | ||||
|       syscall_printf ("SIG_ERR = sigdelset sig %d out of range", sig); | ||||
|       syscall_printf ("SIG_ERR = sigdelset signal %d out of range", sig); | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -736,7 +736,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp) | ||||
|   if (!wait_for_completion) | ||||
|     { | ||||
|       rc = WAIT_OBJECT_0; | ||||
|       sigproc_printf ("Not waiting for sigcomplete.  its_me %d sig %d", its_me, sig); | ||||
|       sigproc_printf ("Not waiting for sigcomplete.  its_me %d signal %d", its_me, sig); | ||||
|       if (!its_me) | ||||
| 	ForceCloseHandle (thiscatch); | ||||
|     } | ||||
| @@ -765,7 +765,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp) | ||||
|     { | ||||
|       /* It's an error unless sig_loop_wait == 0 (the process is exiting). */ | ||||
|       if (!no_signals_available ()) | ||||
| 	system_printf ("wait for sig_complete event failed, sig %d, rc %d, %E", | ||||
| 	system_printf ("wait for sig_complete event failed, signal %d, rc %d, %E", | ||||
| 		      sig, rc); | ||||
|       set_errno (ENOSYS); | ||||
|       rc = -1; | ||||
| @@ -1144,7 +1144,7 @@ wait_sig (VOID *) | ||||
| 		  (sigismember (&myself->getsigmask (), sig) || | ||||
| 		  (sig != SIGCONT && ISSTATE (myself, PID_STOPPED)))) | ||||
| 		{ | ||||
| 		  sigproc_printf ("sig %d blocked", sig); | ||||
| 		  sigproc_printf ("signal %d blocked", sig); | ||||
| 		  break; | ||||
| 		} | ||||
|  | ||||
|   | ||||
| @@ -49,6 +49,17 @@ class sigframe | ||||
| { | ||||
| private: | ||||
|   sigthread *st; | ||||
|   void unregister () | ||||
|   { | ||||
|     if (st) | ||||
|       { | ||||
| 	EnterCriticalSection (&st->lock); | ||||
| 	st->frame = 0; | ||||
| 	st->release_winapi_lock (); | ||||
| 	LeaveCriticalSection (&st->lock); | ||||
| 	st = NULL; | ||||
|       } | ||||
|   } | ||||
|  | ||||
| public: | ||||
|   void set (sigthread &t, DWORD ebp) | ||||
| @@ -70,15 +81,10 @@ public: | ||||
|   } | ||||
|   ~sigframe () | ||||
|   { | ||||
|     if (st) | ||||
|       { | ||||
| 	EnterCriticalSection (&st->lock); | ||||
| 	st->frame = 0; | ||||
| 	st->release_winapi_lock (); | ||||
| 	LeaveCriticalSection (&st->lock); | ||||
| 	st = NULL; | ||||
|       } | ||||
|     unregister (); | ||||
|   } | ||||
|  | ||||
|   int call_signal_handler (); | ||||
| }; | ||||
|  | ||||
| extern sigthread mainthread; | ||||
|   | ||||
| @@ -229,51 +229,54 @@ setsid (void) | ||||
| extern "C" ssize_t | ||||
| _read (int fd, void *ptr, size_t len) | ||||
| { | ||||
|   sigframe thisframe (mainthread); | ||||
|   extern int sigcatchers; | ||||
|   bool sawsig; | ||||
|  | ||||
| beg: | ||||
|   sawsig = 0; | ||||
|   if (fdtab.not_open (fd)) | ||||
|     { | ||||
|       set_errno (EBADF); | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|   // set_sig_errno (0); | ||||
|   fhandler_base *fh = fdtab[fd]; | ||||
|   DWORD wait = (fh->get_flags () & (O_NONBLOCK | OLD_O_NDELAY)) ? 0 : INFINITE; | ||||
|  | ||||
|   /* Could block, so let user know we at least got here.  */ | ||||
|   syscall_printf ("read (%d, %p, %d) %sblocking, sigcatchers %d", fd, ptr, len, wait ? "" : "non", sigcatchers); | ||||
|  | ||||
|   int res; | ||||
|   if (wait && (!sigcatchers || !fh->is_slow () || fh->get_r_no_interrupt ())) | ||||
|     debug_printf ("non-interruptible read\n"); | ||||
|   else if (!fh->ready_for_read (fd, wait, 0)) | ||||
|   fhandler_base *fh; | ||||
|   extern int sigcatchers; | ||||
|  | ||||
|   while (1) | ||||
|     { | ||||
|       if (!wait) | ||||
| 	set_sig_errno (EAGAIN);	/* Don't really need 'set_sig_errno' here, but... */ | ||||
|       else | ||||
| 	set_sig_errno (EINTR); | ||||
|       res = -1; | ||||
|       goto out; | ||||
|       sigframe thisframe (mainthread); | ||||
|  | ||||
|       if (fdtab.not_open (fd)) | ||||
| 	{ | ||||
| 	  set_errno (EBADF); | ||||
| 	  return -1; | ||||
| 	} | ||||
|  | ||||
|       // set_sig_errno (0); | ||||
|       fh = fdtab[fd]; | ||||
|       DWORD wait = (fh->get_flags () & (O_NONBLOCK | OLD_O_NDELAY)) ? 0 : INFINITE; | ||||
|  | ||||
|       /* Could block, so let user know we at least got here.  */ | ||||
|       syscall_printf ("read (%d, %p, %d) %sblocking, sigcatchers %d", fd, ptr, len, wait ? "" : "non", sigcatchers); | ||||
|  | ||||
|       if (wait && (!sigcatchers || !fh->is_slow () || fh->get_r_no_interrupt ())) | ||||
| 	debug_printf ("non-interruptible read\n"); | ||||
|       else if (!fh->ready_for_read (fd, wait, 0)) | ||||
| 	{ | ||||
| 	  if (!wait) | ||||
| 	    set_sig_errno (EAGAIN);	/* Don't really need 'set_sig_errno' here, but... */ | ||||
| 	  else | ||||
| 	    set_sig_errno (EINTR); | ||||
| 	  res = -1; | ||||
| 	  goto out; | ||||
| 	} | ||||
|  | ||||
|       /* Check to see if this is a background read from a "tty", | ||||
| 	 sending a SIGTTIN, if appropriate */ | ||||
|       res = fh->bg_check (SIGTTIN); | ||||
|       if (res > bg_eof) | ||||
| 	{ | ||||
| 	  myself->process_state |= PID_TTYIN; | ||||
| 	  res = fh->read (ptr, len); | ||||
| 	  myself->process_state &= ~PID_TTYIN; | ||||
| 	} | ||||
|  | ||||
|     out: | ||||
|       if (res >= 0 || get_errno () == EINTR || !thisframe.call_signal_handler ()) | ||||
| 	break; | ||||
|     } | ||||
|  | ||||
|   /* Check to see if this is a background read from a "tty", | ||||
|      sending a SIGTTIN, if appropriate */ | ||||
|   res = fh->bg_check (SIGTTIN); | ||||
|   if (res > bg_eof) | ||||
|     { | ||||
|       myself->process_state |= PID_TTYIN; | ||||
|       res = fh->read (ptr, len); | ||||
|       myself->process_state &= ~PID_TTYIN; | ||||
|     } | ||||
|  | ||||
| out: | ||||
|   if (res < 0 && get_errno () == EINTR && call_signal_handler ()) | ||||
|     goto beg; | ||||
|   syscall_printf ("%d = read (%d<%s>, %p, %d), bin %d, errno %d", res, fd, fh->get_name (), | ||||
| 		  ptr, len, fh->get_r_binary (), get_errno ()); | ||||
|   MALLOC_CHECK; | ||||
|   | ||||
| @@ -50,71 +50,74 @@ wait4 (int intpid, int *status, int options, struct rusage *r) | ||||
|   int res; | ||||
|   waitq *w; | ||||
|   HANDLE waitfor; | ||||
|   sigframe thisframe (mainthread); | ||||
|   bool sawsig; | ||||
|  | ||||
| beg: | ||||
|   sawsig = 0; | ||||
|   if (options & ~(WNOHANG | WUNTRACED)) | ||||
|   while (1) | ||||
|     { | ||||
|       set_errno (EINVAL); | ||||
|       return -1; | ||||
|       sigframe thisframe (mainthread); | ||||
|       sawsig = 0; | ||||
|       if (options & ~(WNOHANG | WUNTRACED)) | ||||
| 	{ | ||||
| 	  set_errno (EINVAL); | ||||
| 	  return -1; | ||||
| 	} | ||||
|  | ||||
|       if (r) | ||||
| 	memset (r, 0, sizeof (*r)); | ||||
|  | ||||
|       if ((w = (waitq *) waitq_storage.get ()) == NULL) | ||||
| 	w = (waitq *) waitq_storage.create (); | ||||
|  | ||||
|       w->pid = intpid; | ||||
|       w->options = options; | ||||
|       w->rusage = r; | ||||
|       sigproc_printf ("calling proc_subproc, pid %d, options %d", | ||||
| 		     w->pid, w->options); | ||||
|       if (!proc_subproc (PROC_WAIT, (DWORD)w)) | ||||
| 	{ | ||||
| 	  set_errno (ENOSYS); | ||||
| 	  paranoid_printf ("proc_subproc returned 0"); | ||||
| 	  res = -1; | ||||
| 	  goto done; | ||||
| 	} | ||||
|  | ||||
|       if ((waitfor = w->ev) == NULL) | ||||
| 	goto nochildren; | ||||
|  | ||||
|       res = WaitForSingleObject (waitfor, INFINITE); | ||||
|  | ||||
|       sigproc_printf ("%d = WaitForSingleObject (...)", res); | ||||
|  | ||||
|       if (w->ev == NULL) | ||||
| 	{ | ||||
| 	nochildren: | ||||
| 	  /* found no children */ | ||||
| 	  set_errno (ECHILD); | ||||
| 	  res = -1; | ||||
| 	  goto done; | ||||
| 	} | ||||
|  | ||||
|       if (w->status == -1) | ||||
| 	{ | ||||
| 	  set_sig_errno (EINTR); | ||||
| 	  sawsig = 1; | ||||
| 	  res = -1; | ||||
| 	} | ||||
|       else if (res != WAIT_OBJECT_0) | ||||
| 	{ | ||||
| 	  /* We shouldn't set errno to any random value if we can help it. | ||||
| 	     See the Posix manual for a list of valid values for `errno'.  */ | ||||
| 	  set_errno (EINVAL); | ||||
| 	  res = -1; | ||||
| 	} | ||||
|       else if ((res = w->pid) != 0 && status) | ||||
| 	*status = w->status; | ||||
|  | ||||
|     done: | ||||
|       if (!sawsig || !thisframe.call_signal_handler ()) | ||||
| 	break; | ||||
|     } | ||||
|  | ||||
|   if (r) | ||||
|     memset (r, 0, sizeof (*r)); | ||||
|  | ||||
|   if ((w = (waitq *) waitq_storage.get ()) == NULL) | ||||
|     w = (waitq *) waitq_storage.create (); | ||||
|  | ||||
|   w->pid = intpid; | ||||
|   w->options = options; | ||||
|   w->rusage = r; | ||||
|   sigproc_printf ("calling proc_subproc, pid %d, options %d", | ||||
| 		 w->pid, w->options); | ||||
|   if (!proc_subproc (PROC_WAIT, (DWORD)w)) | ||||
|     { | ||||
|       set_errno (ENOSYS); | ||||
|       paranoid_printf ("proc_subproc returned 0"); | ||||
|       res = -1; | ||||
|       goto done; | ||||
|     } | ||||
|  | ||||
|   if ((waitfor = w->ev) == NULL) | ||||
|     goto nochildren; | ||||
|  | ||||
|   res = WaitForSingleObject (waitfor, INFINITE); | ||||
|  | ||||
|   sigproc_printf ("%d = WaitForSingleObject (...)", res); | ||||
|  | ||||
|   if (w->ev == NULL) | ||||
|     { | ||||
|     nochildren: | ||||
|       /* found no children */ | ||||
|       set_errno (ECHILD); | ||||
|       res = -1; | ||||
|       goto done; | ||||
|     } | ||||
|  | ||||
|   if (w->status == -1) | ||||
|     { | ||||
|       set_sig_errno (EINTR); | ||||
|       sawsig = 1; | ||||
|       res = -1; | ||||
|     } | ||||
|   else if (res != WAIT_OBJECT_0) | ||||
|     { | ||||
|       /* We shouldn't set errno to any random value if we can help it. | ||||
| 	 See the Posix manual for a list of valid values for `errno'.  */ | ||||
|       set_errno (EINVAL); | ||||
|       res = -1; | ||||
|     } | ||||
|   else if ((res = w->pid) != 0 && status) | ||||
|     *status = w->status; | ||||
|  | ||||
| done: | ||||
|   if (sawsig && call_signal_handler ()) | ||||
|     goto beg; | ||||
|   sigproc_printf ("intpid %d, status %p, w->status %d, options %d, res %d", | ||||
| 		  intpid, status, w->status, options, res); | ||||
|   w->status = -1; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user