* child_info.h (child_info): Add pppid_handle for closing the parent's of the
parent handle. * dcrt0.cc (_dll_crt0): Close parent's parent handle when spawned or forked. * debug.cc (add_handle): Correct erroneous reference to handle structure when printing warning. * exceptions.cc (interrupt_now): Always return 1. (interrupt_on_return): Accept a sigthread argument. Check to see if this argument has been trashed prior to setting up the stack return. (call_handler): Add a loop around attempts to dispatch signals to detect case where interrupt_on_return fails. (_sigdelayed): Set up a temporary frame pointer prior to calling stuff that could trigger an interrupt or the stack walking code will be very confused. * fork.cc (fork_parent): Move a lot of the setup of the child process into proc_subproc. * spawn.cc (spawn_guts): Ditto. Use ppid_handle to contact logical parent when reparenting. * pinfo.h (_pinfo): Remember the logical handle of the parent process. * sigproc.cc (proc_subproc): Record most stuff necessary for the _pinfo structure that is inferrable from myself when adding children. (wait_sig): Always set 'pending_signals' flag when about to kick off the signal scanning loop. Reset it only if there are no pending signals.
This commit is contained in:
		
							parent
							
								
									e0997f5a0f
								
							
						
					
					
						commit
						dd11f11fae
					
				| 
						 | 
				
			
			@ -1,3 +1,30 @@
 | 
			
		|||
Mon Nov  6 01:04:35 2000  Christopher Faylor <cgf@cygnus.com>
 | 
			
		||||
 | 
			
		||||
	* child_info.h (child_info): Add pppid_handle for closing the parent's
 | 
			
		||||
	of the parent handle.
 | 
			
		||||
	* dcrt0.cc (_dll_crt0): Close parent's parent handle when spawned or
 | 
			
		||||
	forked.
 | 
			
		||||
	* debug.cc (add_handle): Correct erroneous reference to handle
 | 
			
		||||
	structure when printing warning.
 | 
			
		||||
	* exceptions.cc (interrupt_now): Always return 1.
 | 
			
		||||
	(interrupt_on_return): Accept a sigthread argument.  Check to see if
 | 
			
		||||
	this argument has been trashed prior to setting up the stack return.
 | 
			
		||||
	(call_handler): Add a loop around attempts to dispatch signals to
 | 
			
		||||
	detect case where interrupt_on_return fails.
 | 
			
		||||
	(_sigdelayed): Set up a temporary frame pointer prior to calling stuff
 | 
			
		||||
	that could trigger an interrupt or the stack walking code will be very
 | 
			
		||||
	confused.
 | 
			
		||||
	* fork.cc (fork_parent): Move a lot of the setup of the child process
 | 
			
		||||
	into proc_subproc.
 | 
			
		||||
	* spawn.cc (spawn_guts): Ditto.  Use ppid_handle to contact logical
 | 
			
		||||
	parent when reparenting.
 | 
			
		||||
	* pinfo.h (_pinfo): Remember the logical handle of the parent process.
 | 
			
		||||
	* sigproc.cc (proc_subproc): Record most stuff necessary for the _pinfo
 | 
			
		||||
	structure that is inferrable from myself when adding children.
 | 
			
		||||
	(wait_sig): Always set 'pending_signals' flag when about to kick off
 | 
			
		||||
	the signal scanning loop.  Reset it only if there are no pending
 | 
			
		||||
	signals.
 | 
			
		||||
 | 
			
		||||
Sun Nov  5 13:46:23 2000  Christopher Faylor <cgf@cygnus.com>
 | 
			
		||||
 | 
			
		||||
	* pinfo (wait_subproc): Son of neverending debug tweaking.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,7 +12,7 @@ details. */
 | 
			
		|||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  PROC_MAGIC = 0xaf09f000,
 | 
			
		||||
  PROC_MAGIC = 0xaf0af000,
 | 
			
		||||
  PROC_FORK = PROC_MAGIC + 1,
 | 
			
		||||
  PROC_EXEC = PROC_MAGIC + 2,
 | 
			
		||||
  PROC_SPAWN = PROC_MAGIC + 3,
 | 
			
		||||
| 
						 | 
				
			
			@ -38,6 +38,7 @@ public:
 | 
			
		|||
  HANDLE console_h;
 | 
			
		||||
  HANDLE parent_alive;	// handle of thread used to track children
 | 
			
		||||
  HANDLE parent;
 | 
			
		||||
  HANDLE pppid_handle;
 | 
			
		||||
  void *cygheap;
 | 
			
		||||
  void *cygheap_max;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -898,8 +898,9 @@ _dll_crt0 ()
 | 
			
		|||
	  case PROC_FORK:
 | 
			
		||||
	  case PROC_FORK1:
 | 
			
		||||
	    user_data->forkee = fork_info->cygpid;
 | 
			
		||||
	  case PROC_EXEC:
 | 
			
		||||
	  case PROC_SPAWN:
 | 
			
		||||
	    CloseHandle (fork_info->pppid_handle);
 | 
			
		||||
	  case PROC_EXEC:
 | 
			
		||||
	    {
 | 
			
		||||
	      child_proc_info = fork_info;
 | 
			
		||||
	      mypid = child_proc_info->cygpid;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -228,7 +228,7 @@ newh ()
 | 
			
		|||
      goto out;
 | 
			
		||||
 | 
			
		||||
  /* All used up??? */
 | 
			
		||||
  if ((hl = (handle_list *)malloc (sizeof *hl)) != NULL)
 | 
			
		||||
  if ((hl = (handle_list *) malloc (sizeof *hl)) != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      memset (hl, 0, sizeof (*hl));
 | 
			
		||||
      hl->allocated = TRUE;
 | 
			
		||||
| 
						 | 
				
			
			@ -248,6 +248,7 @@ add_handle (const char *func, int ln, HANDLE h, const char *name)
 | 
			
		|||
 | 
			
		||||
  if ((hl = find_handle (h)))
 | 
			
		||||
    {
 | 
			
		||||
      hl = hl->next;
 | 
			
		||||
      system_printf ("%s:%d - multiple attempts to add handle %s<%p>", func,
 | 
			
		||||
		     ln, name, h);
 | 
			
		||||
      system_printf (" previously allocated by %s:%d(%s<%p>)",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,6 +30,7 @@ static int handle_exceptions (EXCEPTION_RECORD *, void *, CONTEXT *, void *);
 | 
			
		|||
extern void sigreturn ();
 | 
			
		||||
extern void sigdelayed ();
 | 
			
		||||
extern void siglast ();
 | 
			
		||||
extern DWORD __no_sig_start, __no_sig_end;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern DWORD sigtid;
 | 
			
		||||
| 
						 | 
				
			
			@ -627,12 +628,13 @@ interrupt_setup (int sig, struct sigaction& siga, void *handler,
 | 
			
		|||
  sigsave.saved_errno = -1;		// Flag: no errno to save
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static bool
 | 
			
		||||
interrupt_now (CONTEXT *ctx, int sig, struct sigaction& siga, void *handler)
 | 
			
		||||
{
 | 
			
		||||
  interrupt_setup (sig, siga, handler, ctx->Eip, 0);
 | 
			
		||||
  ctx->Eip = (DWORD) sigdelayed;
 | 
			
		||||
  SetThreadContext (myself->getthread2signal (), ctx); /* Restart the thread */
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void __stdcall
 | 
			
		||||
| 
						 | 
				
			
			@ -662,12 +664,13 @@ signal_fixup_after_exec (bool isspawn)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
interrupt_on_return (DWORD ebp, int sig, struct sigaction& siga, void *handler)
 | 
			
		||||
interrupt_on_return (sigthread *th, int sig, struct sigaction& siga, void *handler)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  DWORD ebp = th->frame;
 | 
			
		||||
 | 
			
		||||
  if (sigsave.sig)
 | 
			
		||||
    return 0;	/* Already have a signal stacked up */
 | 
			
		||||
  if (!ebp)
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
  thestack.init (ebp);  /* Initialize from the input CONTEXT */
 | 
			
		||||
  for (i = 0; i < 32 && thestack++ ; i++)
 | 
			
		||||
| 
						 | 
				
			
			@ -677,12 +680,16 @@ interrupt_on_return (DWORD ebp, int sig, struct sigaction& siga, void *handler)
 | 
			
		|||
	if (*addr_retaddr  == thestack.sf.AddrReturn.Offset)
 | 
			
		||||
	  {
 | 
			
		||||
	    interrupt_setup (sig, siga, handler, *addr_retaddr, addr_retaddr);
 | 
			
		||||
	    if (ebp != th->frame)
 | 
			
		||||
	      {
 | 
			
		||||
		sigsave.sig = 0;
 | 
			
		||||
		break;
 | 
			
		||||
	      }
 | 
			
		||||
	    *addr_retaddr = (DWORD) sigdelayed;
 | 
			
		||||
	  }
 | 
			
		||||
	return 1;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
  api_fatal ("couldn't send signal %d", sig);
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -700,11 +707,10 @@ static int
 | 
			
		|||
call_handler (int sig, struct sigaction& siga, void *handler)
 | 
			
		||||
{
 | 
			
		||||
  CONTEXT cx;
 | 
			
		||||
  int interrupted = 1;
 | 
			
		||||
  bool interrupted = 0;
 | 
			
		||||
  HANDLE hth = NULL;
 | 
			
		||||
  DWORD ebp;
 | 
			
		||||
  int res;
 | 
			
		||||
  int using_mainthread_frame;
 | 
			
		||||
  sigthread *th;
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
  mainthread.lock->acquire ();
 | 
			
		||||
| 
						 | 
				
			
			@ -713,98 +719,101 @@ call_handler (int sig, struct sigaction& siga, void *handler)
 | 
			
		|||
  if (sigsave.sig)
 | 
			
		||||
    goto set_pending;
 | 
			
		||||
 | 
			
		||||
  if (mainthread.frame)
 | 
			
		||||
  for (int i = 0; !interrupted && i < 10; i++)
 | 
			
		||||
    {
 | 
			
		||||
      ebp = mainthread.frame;
 | 
			
		||||
      using_mainthread_frame = 1;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      int i;
 | 
			
		||||
      using_mainthread_frame = 0;
 | 
			
		||||
#if 0
 | 
			
		||||
      mainthread.lock->release ();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
      hth = myself->getthread2signal ();
 | 
			
		||||
      /* Suspend the thread which will receive the signal.  But first ensure that
 | 
			
		||||
	 this thread doesn't have any mutos.  (FIXME: Someday we should just grab
 | 
			
		||||
	 all of the mutos rather than checking for them)
 | 
			
		||||
	 For Windows 95, we also have to ensure that the addresses returned by GetThreadContext
 | 
			
		||||
	 are valid.
 | 
			
		||||
	 If one of these conditions is not true we loop for a fixed number of times
 | 
			
		||||
	 since we don't want to stall the signal handler.  FIXME: Will this result in
 | 
			
		||||
	 noticeable delays?
 | 
			
		||||
	 If the thread is already suspended (which can occur when a program is stopped) then
 | 
			
		||||
	 just queue the signal. */
 | 
			
		||||
      for (i = 0; i < SUSPEND_TRIES; i++)
 | 
			
		||||
      if (mainthread.frame)
 | 
			
		||||
	th = &mainthread;
 | 
			
		||||
      else
 | 
			
		||||
	{
 | 
			
		||||
	  sigproc_printf ("suspending mainthread");
 | 
			
		||||
	  res = SuspendThread (hth);
 | 
			
		||||
 | 
			
		||||
	  muto *m;
 | 
			
		||||
	  /* FIXME: Make multi-thread aware */
 | 
			
		||||
	  for (m = muto_start.next;  m != NULL; m = m->next)
 | 
			
		||||
	    if (m->unstable () || m->owner () == mainthread.id)
 | 
			
		||||
	      goto owns_muto;
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
	  mainthread.lock->acquire ();
 | 
			
		||||
#endif
 | 
			
		||||
	  if (mainthread.frame)
 | 
			
		||||
	    {
 | 
			
		||||
	      ebp = mainthread.frame;	/* try to avoid a race */
 | 
			
		||||
	      using_mainthread_frame = 1;
 | 
			
		||||
	      goto next;
 | 
			
		||||
	    }
 | 
			
		||||
#if 0
 | 
			
		||||
	  int i;
 | 
			
		||||
	  th = NULL;
 | 
			
		||||
    #if 0
 | 
			
		||||
	  mainthread.lock->release ();
 | 
			
		||||
#endif
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
	  cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
 | 
			
		||||
	  if (!GetThreadContext (hth, &cx))
 | 
			
		||||
	  hth = myself->getthread2signal ();
 | 
			
		||||
	  /* Suspend the thread which will receive the signal.  But first ensure that
 | 
			
		||||
	     this thread doesn't have any mutos.  (FIXME: Someday we should just grab
 | 
			
		||||
	     all of the mutos rather than checking for them)
 | 
			
		||||
	     For Windows 95, we also have to ensure that the addresses returned by GetThreadContext
 | 
			
		||||
	     are valid.
 | 
			
		||||
	     If one of these conditions is not true we loop for a fixed number of times
 | 
			
		||||
	     since we don't want to stall the signal handler.  FIXME: Will this result in
 | 
			
		||||
	     noticeable delays?
 | 
			
		||||
	     If the thread is already suspended (which can occur when a program is stopped) then
 | 
			
		||||
	     just queue the signal. */
 | 
			
		||||
	  for (i = 0; i < SUSPEND_TRIES; i++)
 | 
			
		||||
	    {
 | 
			
		||||
	      system_printf ("couldn't get context of main thread, %E");
 | 
			
		||||
	      goto out;
 | 
			
		||||
	      sigproc_printf ("suspending mainthread");
 | 
			
		||||
	      res = SuspendThread (hth);
 | 
			
		||||
 | 
			
		||||
	      /* Just set pending if thread is already suspended */
 | 
			
		||||
	      if (res)
 | 
			
		||||
		goto set_pending;
 | 
			
		||||
 | 
			
		||||
	      muto *m;
 | 
			
		||||
	      /* FIXME: Make multi-thread aware */
 | 
			
		||||
	      for (m = muto_start.next;  m != NULL; m = m->next)
 | 
			
		||||
		if (m->unstable () || m->owner () == mainthread.id)
 | 
			
		||||
		  goto owns_muto;
 | 
			
		||||
 | 
			
		||||
    #if 0
 | 
			
		||||
	      mainthread.lock->acquire ();
 | 
			
		||||
    #endif
 | 
			
		||||
	      if (mainthread.frame)
 | 
			
		||||
		{
 | 
			
		||||
		  th = &mainthread;
 | 
			
		||||
		  goto next;
 | 
			
		||||
		}
 | 
			
		||||
    #if 0
 | 
			
		||||
	      mainthread.lock->release ();
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
	      cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
 | 
			
		||||
	      if (!GetThreadContext (hth, &cx))
 | 
			
		||||
		{
 | 
			
		||||
		  system_printf ("couldn't get context of main thread, %E");
 | 
			
		||||
		  goto out;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	      if (interruptible (cx.Eip, 1))
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	      sigproc_printf ("suspended thread in a strange state pc %p, sp %p",
 | 
			
		||||
			      cx.Eip, cx.Esp);
 | 
			
		||||
	      goto resume_thread;
 | 
			
		||||
 | 
			
		||||
	    owns_muto:
 | 
			
		||||
	      sigproc_printf ("suspended thread owns a muto (%s)", m->name);
 | 
			
		||||
 | 
			
		||||
	    resume_thread:
 | 
			
		||||
	      ResumeThread (hth);
 | 
			
		||||
	      Sleep (0);
 | 
			
		||||
	    }
 | 
			
		||||
 | 
			
		||||
	  if (interruptible (cx.Eip, 1))
 | 
			
		||||
	    break;
 | 
			
		||||
 | 
			
		||||
	  sigproc_printf ("suspended thread in a strange state pc %p, sp %p",
 | 
			
		||||
			  cx.Eip, cx.Esp);
 | 
			
		||||
	  goto resume_thread;
 | 
			
		||||
 | 
			
		||||
	owns_muto:
 | 
			
		||||
	  sigproc_printf ("suspended thread owns a muto (%s)", m->name);
 | 
			
		||||
 | 
			
		||||
	  if (res)
 | 
			
		||||
	  if (i >= SUSPEND_TRIES)
 | 
			
		||||
	    goto set_pending;
 | 
			
		||||
 | 
			
		||||
	resume_thread:
 | 
			
		||||
	  ResumeThread (hth);
 | 
			
		||||
	  Sleep (0);
 | 
			
		||||
	  sigproc_printf ("SuspendThread returned %d", res);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      if (i >= SUSPEND_TRIES)
 | 
			
		||||
	goto set_pending;
 | 
			
		||||
 | 
			
		||||
      sigproc_printf ("SuspendThread returned %d", res);
 | 
			
		||||
      ebp = cx.Ebp;
 | 
			
		||||
    next:
 | 
			
		||||
      if (th)
 | 
			
		||||
	interrupted = interrupt_on_return (th, sig, siga, handler);
 | 
			
		||||
      else if (interruptible (cx.Eip))
 | 
			
		||||
	interrupted = interrupt_now (&cx, sig, siga, handler);
 | 
			
		||||
      else
 | 
			
		||||
	break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
next:
 | 
			
		||||
  if (!using_mainthread_frame && interruptible (cx.Eip))
 | 
			
		||||
    interrupt_now (&cx, sig, siga, handler);
 | 
			
		||||
  else if (!interrupt_on_return (ebp, sig, siga, handler))
 | 
			
		||||
set_pending:
 | 
			
		||||
  if (!interrupted)
 | 
			
		||||
    {
 | 
			
		||||
    set_pending:
 | 
			
		||||
      pending_signals = 1;	/* FIXME: Probably need to be more tricky here */
 | 
			
		||||
      sig_set_pending (sig);
 | 
			
		||||
      interrupted = 0;
 | 
			
		||||
      sigproc_printf ("couldn't send signal %d", sig);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (interrupted)
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      res = SetEvent (signal_arrived);	// For an EINTR case
 | 
			
		||||
      sigproc_printf ("armed signal_arrived %p, res %d", signal_arrived, res);
 | 
			
		||||
| 
						 | 
				
			
			@ -882,6 +891,9 @@ set_process_mask (sigset_t newmask)
 | 
			
		|||
  mask_sync->release ();
 | 
			
		||||
  if (oldmask != newmask && GetCurrentThreadId () != sigtid)
 | 
			
		||||
    sig_dispatch_pending ();
 | 
			
		||||
  else
 | 
			
		||||
    sigproc_printf ("not calling sig_dispatch_pending.  sigtid %p current %p",
 | 
			
		||||
		    sigtid, GetCurrentThreadId ());
 | 
			
		||||
  return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1099,7 +1111,7 @@ __asm__ volatile ("
 | 
			
		|||
	.text
 | 
			
		||||
 | 
			
		||||
_sigreturn:
 | 
			
		||||
	addl	$4,%%esp
 | 
			
		||||
	addl	$4,%%esp	# Remove argument
 | 
			
		||||
	movl	%%esp,%%ebp
 | 
			
		||||
	addl	$36,%%ebp
 | 
			
		||||
	call	_set_process_mask@4
 | 
			
		||||
| 
						 | 
				
			
			@ -1118,6 +1130,7 @@ _sigreturn:
 | 
			
		|||
	popf
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
__no_sig_start:
 | 
			
		||||
_sigdelayed:
 | 
			
		||||
	pushl	%2	# original return address
 | 
			
		||||
	pushf
 | 
			
		||||
| 
						 | 
				
			
			@ -1132,6 +1145,8 @@ _sigdelayed:
 | 
			
		|||
	pushl	%3	# oldmask
 | 
			
		||||
	pushl	%4	# signal argument
 | 
			
		||||
	pushl	$_sigreturn
 | 
			
		||||
	pushl	%%ebp
 | 
			
		||||
	movl	%%esp,%%esp
 | 
			
		||||
 | 
			
		||||
	call	_reset_signal_arrived@0
 | 
			
		||||
	movl	$0,%0
 | 
			
		||||
| 
						 | 
				
			
			@ -1141,7 +1156,9 @@ _sigdelayed:
 | 
			
		|||
	pushl	$0
 | 
			
		||||
	call	_sig_dispatch_pending@4
 | 
			
		||||
 | 
			
		||||
2:	jmp	*%5
 | 
			
		||||
2:	popl	%%ebp
 | 
			
		||||
	jmp	*%5
 | 
			
		||||
__no_sig_end:
 | 
			
		||||
 | 
			
		||||
" : "=m" (sigsave.sig) : "m" (&_impure_ptr->_errno),
 | 
			
		||||
  "g" (sigsave.retaddr), "g" (sigsave.oldmask), "g" (sigsave.sig),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -471,35 +471,12 @@ fork_parent (void *stack_here, HANDLE& hParent, dll *&first_dll, bool& load_dlls
 | 
			
		|||
    system_printf ("couldn't create last_fork_proc, %E");
 | 
			
		||||
 | 
			
		||||
  /* Fill in fields in the child's process table entry.  */
 | 
			
		||||
  forked->ppid = myself->pid;
 | 
			
		||||
  forked->hProcess = pi.hProcess;
 | 
			
		||||
  forked->dwProcessId = pi.dwProcessId;
 | 
			
		||||
  forked->uid = myself->uid;
 | 
			
		||||
  forked->gid = myself->gid;
 | 
			
		||||
  forked->pgid = myself->pgid;
 | 
			
		||||
  forked->sid = myself->sid;
 | 
			
		||||
  forked->ctty = myself->ctty;
 | 
			
		||||
  forked->umask = myself->umask;
 | 
			
		||||
  forked->copysigs(myself);
 | 
			
		||||
  forked->process_state |= PID_INITIALIZING |
 | 
			
		||||
			  (myself->process_state & PID_USETTY);
 | 
			
		||||
  memcpy (forked->username, myself->username, MAX_USER_NAME);
 | 
			
		||||
  if (myself->use_psid)
 | 
			
		||||
    {
 | 
			
		||||
      memcpy (forked->psid, myself->psid, MAX_SID_LEN);
 | 
			
		||||
      forked->use_psid = 1;
 | 
			
		||||
    }
 | 
			
		||||
  memcpy (forked->logsrv, myself->logsrv, MAX_HOST_NAME);
 | 
			
		||||
  memcpy (forked->domain, myself->domain, MAX_COMPUTERNAME_LENGTH+1);
 | 
			
		||||
  forked->token = myself->token;
 | 
			
		||||
  forked->impersonated = myself->impersonated;
 | 
			
		||||
  forked->orig_uid = myself->orig_uid;
 | 
			
		||||
  forked->orig_gid = myself->orig_gid;
 | 
			
		||||
  forked->real_uid = myself->real_uid;
 | 
			
		||||
  forked->real_gid = myself->real_gid;
 | 
			
		||||
  strcpy (forked->root, myself->root);
 | 
			
		||||
  forked->rootlen = myself->rootlen;
 | 
			
		||||
  set_child_mmap_ptr (forked);
 | 
			
		||||
  forked.remember ();
 | 
			
		||||
 | 
			
		||||
  /* Wait for subproc to initialize itself. */
 | 
			
		||||
  if (!sync_with_child(pi, subproc_ready, TRUE, "waiting for longjmp"))
 | 
			
		||||
| 
						 | 
				
			
			@ -536,8 +513,6 @@ fork_parent (void *stack_here, HANDLE& hParent, dll *&first_dll, bool& load_dlls
 | 
			
		|||
	goto cleanup;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  forked.remember ();
 | 
			
		||||
 | 
			
		||||
  /* Start thread, and wait for it to reload dlls.  */
 | 
			
		||||
  if (!resume_child (pi, forker_finished) ||
 | 
			
		||||
      !sync_with_child (pi, subproc_ready, load_dlls, "child loading dlls"))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,6 +44,9 @@ public:
 | 
			
		|||
  /* Handle associated with initial Windows pid which started it all. */
 | 
			
		||||
  HANDLE pid_handle;
 | 
			
		||||
 | 
			
		||||
  /* Handle to the logical parent of this pid. */
 | 
			
		||||
  HANDLE ppid_handle;
 | 
			
		||||
 | 
			
		||||
  /* Parent process id.  */
 | 
			
		||||
  pid_t ppid;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -235,7 +235,7 @@ proc_subproc (DWORD what, DWORD val)
 | 
			
		|||
 | 
			
		||||
  if (!get_proc_lock (what, val))	// Serialize access to this function
 | 
			
		||||
    {
 | 
			
		||||
      sigproc_printf ("I am not ready");
 | 
			
		||||
      system_printf ("couldn't get proc lock.  Something is wrong.");
 | 
			
		||||
      goto out1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -253,6 +253,33 @@ proc_subproc (DWORD what, DWORD val)
 | 
			
		|||
			    0, 0, DUPLICATE_SAME_ACCESS))
 | 
			
		||||
	system_printf ("Couldn't duplicate child handle for pid %d, %E", vchild->pid);
 | 
			
		||||
      ProtectHandle1 (vchild->pid_handle, pid_handle);
 | 
			
		||||
 | 
			
		||||
      if (!DuplicateHandle (hMainProc, hMainProc, vchild->hProcess, &vchild->ppid_handle,
 | 
			
		||||
			    0, TRUE, DUPLICATE_SAME_ACCESS))
 | 
			
		||||
	system_printf ("Couldn't duplicate my handle<%p> for pid %d, %E", hMainProc, vchild->pid);
 | 
			
		||||
      vchild->ppid = myself->pid;
 | 
			
		||||
      vchild->gid = myself->gid;
 | 
			
		||||
      vchild->pgid = myself->pgid;
 | 
			
		||||
      vchild->sid = myself->sid;
 | 
			
		||||
      vchild->ctty = myself->ctty;
 | 
			
		||||
      vchild->umask = myself->umask;
 | 
			
		||||
      vchild->orig_uid = myself->orig_uid;
 | 
			
		||||
      vchild->orig_gid = myself->orig_gid;
 | 
			
		||||
      vchild->real_uid = myself->real_uid;
 | 
			
		||||
      vchild->real_gid = myself->real_gid;
 | 
			
		||||
      vchild->impersonated = myself->impersonated;
 | 
			
		||||
      if (myself->use_psid)
 | 
			
		||||
        {
 | 
			
		||||
          vchild->use_psid = 1;
 | 
			
		||||
          memcpy (vchild->psid, myself->psid, MAX_SID_LEN);
 | 
			
		||||
        }
 | 
			
		||||
      memcpy (vchild->logsrv, myself->logsrv, MAX_HOST_NAME);
 | 
			
		||||
      memcpy (vchild->domain, myself->domain, MAX_COMPUTERNAME_LENGTH+1);
 | 
			
		||||
      memcpy (vchild->root, myself->root, MAX_PATH+1);
 | 
			
		||||
      vchild->token = myself->token;
 | 
			
		||||
      vchild->rootlen = myself->rootlen;
 | 
			
		||||
      vchild->process_state |= PID_INITIALIZING | (myself->process_state & PID_USETTY);
 | 
			
		||||
 | 
			
		||||
      sigproc_printf ("added pid %d to wait list, slot %d, winpid %p, handle %p",
 | 
			
		||||
		  vchild->pid, nchildren, vchild->dwProcessId,
 | 
			
		||||
		  vchild->hProcess);
 | 
			
		||||
| 
						 | 
				
			
			@ -810,6 +837,7 @@ init_child_info (DWORD chtype, child_info *ch, pid_t pid, HANDLE subproc_ready)
 | 
			
		|||
  ch->shared_h = cygwin_shared_h;
 | 
			
		||||
  ch->console_h = console_shared_h;
 | 
			
		||||
  ch->subproc_ready = subproc_ready;
 | 
			
		||||
  ch->pppid_handle = myself->ppid_handle;
 | 
			
		||||
  if (chtype != PROC_EXEC || !parent_alive)
 | 
			
		||||
    ch->parent_alive = hwait_subproc;
 | 
			
		||||
  else
 | 
			
		||||
| 
						 | 
				
			
			@ -1100,7 +1128,7 @@ wait_sig (VOID *)
 | 
			
		|||
 | 
			
		||||
  HANDLE catchem[] = {sigcatch_main, sigcatch_nonmain, sigcatch_nosync};
 | 
			
		||||
  sigproc_printf ("Ready.  dwProcessid %d", myself->dwProcessId);
 | 
			
		||||
  for (;;)
 | 
			
		||||
  for (int i = 0; ; i++)
 | 
			
		||||
    {
 | 
			
		||||
      DWORD rc = WaitForMultipleObjects (3, catchem, FALSE, sig_loop_wait);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1128,7 +1156,8 @@ wait_sig (VOID *)
 | 
			
		|||
      /* A sigcatch semaphore has been signaled.  Scan the sigtodo
 | 
			
		||||
       * array looking for any unprocessed signals.
 | 
			
		||||
       */
 | 
			
		||||
      pending_signals = 0;
 | 
			
		||||
      pending_signals = -1;
 | 
			
		||||
      int saw_pending_signals = 0;
 | 
			
		||||
      int saw_sigchld = 0;
 | 
			
		||||
      int dispatched_sigchld = 0;
 | 
			
		||||
      for (int sig = -__SIGOFFSET; sig < NSIG; sig++)
 | 
			
		||||
| 
						 | 
				
			
			@ -1179,11 +1208,26 @@ wait_sig (VOID *)
 | 
			
		|||
	    }
 | 
			
		||||
	  /* Decremented too far. */
 | 
			
		||||
	  if (InterlockedIncrement (myself->getsigtodo(sig)) > 0)
 | 
			
		||||
	    pending_signals = 1;
 | 
			
		||||
	    saw_pending_signals = 1;
 | 
			
		||||
	nextsig:
 | 
			
		||||
	  continue;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      /* FIXME: The dispatched stuff probably isn't needed anymore. */
 | 
			
		||||
      if (dispatched >= 0 && pending_signals < 0 && !saw_pending_signals)
 | 
			
		||||
	{
 | 
			
		||||
	  pending_signals = 0;
 | 
			
		||||
	  /* FIXME FIXME FIXME FIXME FIXME
 | 
			
		||||
	     This is a real kludge designed to handle runaway processes who
 | 
			
		||||
	     missed a signal and never processed a signal handler.  We have
 | 
			
		||||
	     to reset signal_arrived or stuff goes crazy. */
 | 
			
		||||
	  if (i >= 20)
 | 
			
		||||
	    {
 | 
			
		||||
	      i = 0;
 | 
			
		||||
	      ResetEvent (signal_arrived);
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      if (nzombies && saw_sigchld && !dispatched_sigchld)
 | 
			
		||||
	proc_subproc (PROC_CLEARWAIT, 0);
 | 
			
		||||
      /* Signal completion of signal handling depending on which semaphore
 | 
			
		||||
| 
						 | 
				
			
			@ -1202,8 +1246,6 @@ wait_sig (VOID *)
 | 
			
		|||
	  break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      if (dispatched < 0)
 | 
			
		||||
	pending_signals = 1;
 | 
			
		||||
      sigproc_printf ("looping");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1258,7 +1300,6 @@ wait_subproc (VOID *)
 | 
			
		|||
		system_printf ("pid %d, dwProcessId %u, hProcess %p, progname '%s'",
 | 
			
		||||
			       pchildren[i - 1]->pid, pchildren[i - 1]->dwProcessId,
 | 
			
		||||
			       pchildren[i - 1]->hProcess, pchildren[i - 1]->progname);
 | 
			
		||||
		Sleep (10000);
 | 
			
		||||
	      }
 | 
			
		||||
	  break;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -707,22 +707,6 @@ skip_arg_parsing:
 | 
			
		|||
	}
 | 
			
		||||
      child->username[0] = '\0';
 | 
			
		||||
      child->progname[0] = '\0';
 | 
			
		||||
      child->ppid = myself->pid;
 | 
			
		||||
      child->gid = myself->gid;
 | 
			
		||||
      child->pgid = myself->pgid;
 | 
			
		||||
      child->sid = myself->sid;
 | 
			
		||||
      child->ctty = myself->ctty;
 | 
			
		||||
      child->umask = myself->umask;
 | 
			
		||||
      child->process_state |= PID_INITIALIZING;
 | 
			
		||||
      if (myself->use_psid)
 | 
			
		||||
	{
 | 
			
		||||
	  child->use_psid = 1;
 | 
			
		||||
	  memcpy (child->psid, myself->psid, MAX_SID_LEN);
 | 
			
		||||
	}
 | 
			
		||||
      memcpy (child->logsrv, myself->logsrv, MAX_HOST_NAME);
 | 
			
		||||
      memcpy (child->domain, myself->domain, MAX_COMPUTERNAME_LENGTH+1);
 | 
			
		||||
      memcpy (child->root, myself->root, MAX_PATH+1);
 | 
			
		||||
      child->rootlen = myself->rootlen;
 | 
			
		||||
      child->dwProcessId = pi.dwProcessId;
 | 
			
		||||
      child->hProcess = pi.hProcess;
 | 
			
		||||
      child.remember ();
 | 
			
		||||
| 
						 | 
				
			
			@ -808,20 +792,17 @@ skip_arg_parsing:
 | 
			
		|||
	{
 | 
			
		||||
	  int rc = 0;
 | 
			
		||||
	  HANDLE oldh = myself->hProcess;
 | 
			
		||||
	  HANDLE h = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
 | 
			
		||||
				  parent->dwProcessId);
 | 
			
		||||
	  HANDLE h = myself->ppid_handle;
 | 
			
		||||
	  sigproc_printf ("parent handle %p, pid %d", h, parent->dwProcessId);
 | 
			
		||||
	  if (h == NULL && GetLastError () == ERROR_INVALID_PARAMETER)
 | 
			
		||||
	    rc = 1;
 | 
			
		||||
	    rc = 0;
 | 
			
		||||
	  else if (h)
 | 
			
		||||
	    {
 | 
			
		||||
	      ProtectHandle (h);
 | 
			
		||||
	      rc = DuplicateHandle (hMainProc, pi.hProcess,
 | 
			
		||||
				    h, &myself->hProcess, 0, FALSE,
 | 
			
		||||
				    DUPLICATE_SAME_ACCESS);
 | 
			
		||||
	      sigproc_printf ("%d = DuplicateHandle, oldh %p, newh %p",
 | 
			
		||||
			      rc, oldh, myself->hProcess);
 | 
			
		||||
	      ForceCloseHandle (h);
 | 
			
		||||
	    }
 | 
			
		||||
	  if (!rc)
 | 
			
		||||
	    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue