* exceptions.cc: (ctrl_c_handler): Do nothing while a Cygwin subprocess is
starting. * child_info.h (init_child_info): Remove pid argument from declaration. * cygheap.h (init_cygheap::pid): New element. * dcrt0.cc (dll_crt0_0): Eliminate handling of now-noexistent cygpid parameter in child_info struct. Set forkee to 'true' rather than cygpid since the pid value was never used. (dll_crt0_1): Ditto. (_dll_crt0): Ditto. * fork.cc (fork_child): Don't wait for sigthread. This is handled in the fork call now. (fork_parent): Remove obsolete pid argument from init_child_info call. Don't do anything special with cygpid when DEBUGGING. (fork): Delay all signals during fork. (fork_init): Don't do anything special when DEBUGGING. * pinfo.cc (set_myself): Remove pid parameter. Use new pid field in cygheap. (pinfo_init): Don't pass pid argument to set_myself. * sigproc.cc (sig_send): Wait for dwProcessId to be non-zero as well as sendsig. (init_child_info): Eliminate handling of pid. (wait_sig): Implement method to temporarily hold off sending signals. * sigproc.h (__SIGHOLD): New enum. (__SIGNOHOLD): Ditto. * spawn.cc (spawn_guts): Remove obsolete pid argument from init_child_info call.
This commit is contained in:
		
							parent
							
								
									ca5ec6685a
								
							
						
					
					
						commit
						d584454c82
					
				| 
						 | 
				
			
			@ -1,3 +1,36 @@
 | 
			
		|||
2004-09-11  Pierre Humblet  <pierre.humblet@ieee.org>
 | 
			
		||||
	    Christopher Faylor  <cgf@timesys.com>
 | 
			
		||||
 | 
			
		||||
	* exceptions.cc: (ctrl_c_handler): Do nothing while a Cygwin subprocess
 | 
			
		||||
	is starting.
 | 
			
		||||
 | 
			
		||||
2004-09-10  Christopher Faylor  <cgf@timesys.com>
 | 
			
		||||
 | 
			
		||||
	* child_info.h (init_child_info): Remove pid argument from declaration.
 | 
			
		||||
	* cygheap.h (init_cygheap::pid): New element.
 | 
			
		||||
	* dcrt0.cc (dll_crt0_0): Eliminate handling of now-noexistent cygpid
 | 
			
		||||
	parameter in child_info struct.  Set forkee to 'true' rather than cygpid
 | 
			
		||||
	since the pid value was never used.
 | 
			
		||||
	(dll_crt0_1): Ditto.
 | 
			
		||||
	(_dll_crt0): Ditto.
 | 
			
		||||
	* fork.cc (fork_child): Don't wait for sigthread.  This is handled in
 | 
			
		||||
	the fork call now.
 | 
			
		||||
	(fork_parent): Remove obsolete pid argument from init_child_info call.  Don't
 | 
			
		||||
	do anything special with cygpid when DEBUGGING.
 | 
			
		||||
	(fork): Delay all signals during fork.
 | 
			
		||||
	(fork_init): Don't do anything special when DEBUGGING.
 | 
			
		||||
	* pinfo.cc (set_myself): Remove pid parameter.  Use new pid field in
 | 
			
		||||
	cygheap.
 | 
			
		||||
	(pinfo_init): Don't pass pid argument to set_myself.
 | 
			
		||||
	* sigproc.cc (sig_send): Wait for dwProcessId to be non-zero as well as
 | 
			
		||||
	sendsig.
 | 
			
		||||
	(init_child_info): Eliminate handling of pid.
 | 
			
		||||
	(wait_sig): Implement method to temporarily hold off sending signals.
 | 
			
		||||
	* sigproc.h (__SIGHOLD): New enum.
 | 
			
		||||
	(__SIGNOHOLD): Ditto.
 | 
			
		||||
	* spawn.cc (spawn_guts): Remove obsolete pid argument from
 | 
			
		||||
	init_child_info call.
 | 
			
		||||
 | 
			
		||||
2004-09-10  Corinna Vinschen  <corinna@vinschen.de>
 | 
			
		||||
 | 
			
		||||
	* fhandler.cc (fhandler_base::dup): Use debug_printf.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,7 +42,6 @@ public:
 | 
			
		|||
  DWORD intro;		// improbable string
 | 
			
		||||
  unsigned long magic;	// magic number unique to child_info
 | 
			
		||||
  unsigned short type;	// type of record, exec, spawn, fork
 | 
			
		||||
  int cygpid;		// cygwin pid of child process
 | 
			
		||||
  HANDLE subproc_ready;	// used for synchronization with parent
 | 
			
		||||
  HANDLE user_h;
 | 
			
		||||
  HANDLE parent;
 | 
			
		||||
| 
						 | 
				
			
			@ -105,7 +104,7 @@ public:
 | 
			
		|||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void __stdcall init_child_info (DWORD, child_info *, int, HANDLE);
 | 
			
		||||
void __stdcall init_child_info (DWORD, child_info *, HANDLE);
 | 
			
		||||
 | 
			
		||||
extern child_info *child_proc_info;
 | 
			
		||||
extern child_info_spawn *spawn_info __attribute__ ((alias ("child_proc_info")));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -277,6 +277,7 @@ struct init_cygheap
 | 
			
		|||
  struct _cygtls **threadlist;
 | 
			
		||||
  size_t sthreads;
 | 
			
		||||
  int open_fhs;
 | 
			
		||||
  pid_t pid;			/* my pid */
 | 
			
		||||
  void close_ctty ();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -605,7 +605,6 @@ dll_crt0_0 ()
 | 
			
		|||
  GetStartupInfo (&si);
 | 
			
		||||
  child_proc_info = (child_info *) si.lpReserved2;
 | 
			
		||||
 | 
			
		||||
  int mypid = 0;
 | 
			
		||||
  if (si.cbReserved2 < EXEC_MAGIC_SIZE || !child_proc_info
 | 
			
		||||
      || memcmp (child_proc_info->zero, zeros,
 | 
			
		||||
		 sizeof (child_proc_info->zero)) != 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -625,7 +624,7 @@ dll_crt0_0 ()
 | 
			
		|||
      switch (child_proc_info->type)
 | 
			
		||||
	{
 | 
			
		||||
	  case _PROC_FORK:
 | 
			
		||||
	    user_data->forkee = child_proc_info->cygpid;
 | 
			
		||||
	    user_data->forkee = true;
 | 
			
		||||
	    should_be_cb = sizeof (child_info_fork);
 | 
			
		||||
	    /* fall through */;
 | 
			
		||||
	  case _PROC_SPAWN:
 | 
			
		||||
| 
						 | 
				
			
			@ -639,7 +638,6 @@ dll_crt0_0 ()
 | 
			
		|||
	    else
 | 
			
		||||
	      {
 | 
			
		||||
		cygwin_user_h = child_proc_info->user_h;
 | 
			
		||||
		mypid = child_proc_info->cygpid;
 | 
			
		||||
		break;
 | 
			
		||||
	      }
 | 
			
		||||
	  default:
 | 
			
		||||
| 
						 | 
				
			
			@ -667,7 +665,7 @@ dll_crt0_0 ()
 | 
			
		|||
	    alloc_stack (fork_info);
 | 
			
		||||
	    cygheap_fixup_in_child (false);
 | 
			
		||||
	    memory_init ();
 | 
			
		||||
	    set_myself (mypid);
 | 
			
		||||
	    set_myself (NULL);
 | 
			
		||||
	    close_ppid_handle = !!child_proc_info->pppid_handle;
 | 
			
		||||
	    break;
 | 
			
		||||
	  case _PROC_SPAWN:
 | 
			
		||||
| 
						 | 
				
			
			@ -686,7 +684,7 @@ dll_crt0_0 ()
 | 
			
		|||
				  hMainProc, &h, 0, FALSE,
 | 
			
		||||
				  DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
 | 
			
		||||
	      h = NULL;
 | 
			
		||||
	    set_myself (mypid, h);
 | 
			
		||||
	    set_myself (h);
 | 
			
		||||
	    __argc = spawn_info->moreinfo->argc;
 | 
			
		||||
	    __argv = spawn_info->moreinfo->argv;
 | 
			
		||||
	    envp = spawn_info->moreinfo->envp;
 | 
			
		||||
| 
						 | 
				
			
			@ -771,7 +769,7 @@ dll_crt0_1 (char *)
 | 
			
		|||
	  _tlsbase = (char *) fork_info->stackbottom;
 | 
			
		||||
	  _tlstop = (char *) fork_info->stacktop;
 | 
			
		||||
	}
 | 
			
		||||
      longjmp (fork_info->jmp, fork_info->cygpid);
 | 
			
		||||
      longjmp (fork_info->jmp, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUGGING
 | 
			
		||||
| 
						 | 
				
			
			@ -934,7 +932,7 @@ _dll_crt0 ()
 | 
			
		|||
  _impure_ptr->_current_locale = "C";
 | 
			
		||||
 | 
			
		||||
  if (child_proc_info && child_proc_info->type == _PROC_FORK)
 | 
			
		||||
    user_data->forkee = child_proc_info->cygpid;
 | 
			
		||||
    user_data->forkee = true;
 | 
			
		||||
  else
 | 
			
		||||
    __sinit (_impure_ptr);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -805,6 +805,8 @@ ctrl_c_handler (DWORD type)
 | 
			
		|||
 | 
			
		||||
  if (!cygwin_finished_initializing)
 | 
			
		||||
    {
 | 
			
		||||
      if (myself->ppid_handle)	/* Was this process created by a cygwin process? */
 | 
			
		||||
	return TRUE;		/* Yes.  Let the parent eventually handle CTRL-C issues. */
 | 
			
		||||
      debug_printf ("exiting with status %p", STATUS_CONTROL_C_EXIT);
 | 
			
		||||
      ExitProcess (STATUS_CONTROL_C_EXIT);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -484,10 +484,10 @@ fhandler_base::open_9x (int flags, mode_t mode)
 | 
			
		|||
    {
 | 
			
		||||
      /* If mode has no write bits set, we set the R/O attribute. */
 | 
			
		||||
      if (!(mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
 | 
			
		||||
        file_attributes |= FILE_ATTRIBUTE_READONLY;
 | 
			
		||||
	file_attributes |= FILE_ATTRIBUTE_READONLY;
 | 
			
		||||
      /* The file attributes are needed for later use in, e.g. fchmod. */
 | 
			
		||||
      pc.file_attributes (file_attributes & FILE_ATTRIBUTE_VALID_SET_FLAGS);
 | 
			
		||||
    } 
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  x = CreateFile (get_win32_name (), access, shared, &sa, creation_distribution,
 | 
			
		||||
		  file_attributes, 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -818,7 +818,7 @@ fhandler_base::write (const void *ptr, size_t len)
 | 
			
		|||
		 on any OS. */
 | 
			
		||||
	      /* Check there is enough space */
 | 
			
		||||
	      if (!SetEndOfFile (get_output_handle ()))
 | 
			
		||||
	        {
 | 
			
		||||
		{
 | 
			
		||||
		  __seterrno ();
 | 
			
		||||
		  return -1;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -837,7 +837,7 @@ fhandler_base::write (const void *ptr, size_t len)
 | 
			
		|||
		  if (!ret || written < zeros_this_time)
 | 
			
		||||
		    {
 | 
			
		||||
		      if (!ret)
 | 
			
		||||
		        {
 | 
			
		||||
			{
 | 
			
		||||
			  __seterrno ();
 | 
			
		||||
			  if (get_errno () == EPIPE)
 | 
			
		||||
			    raise (SIGPIPE);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -882,7 +882,7 @@ fhandler_dev_dsp::Audio_in::waitfordata ()
 | 
			
		|||
  if (pHdr->dwFlags) /* Zero if queued following error in queueblock */
 | 
			
		||||
    {
 | 
			
		||||
      /* Errors are ignored here. They will probbaly cause a failure
 | 
			
		||||
         in the subsequent PrepareHeader */
 | 
			
		||||
	 in the subsequent PrepareHeader */
 | 
			
		||||
      rc = waveInUnprepareHeader (dev_, pHdr, sizeof (WAVEHDR));
 | 
			
		||||
      debug_printf ("%d = waveInUnprepareHeader (0x%08x)", rc, pHdr);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1149,7 +1149,7 @@ fhandler_dev_dsp::ioctl (unsigned int cmd, void *ptr)
 | 
			
		|||
      CASE (SNDCTL_DSP_RESET)
 | 
			
		||||
	close_audio_in ();
 | 
			
		||||
	close_audio_out (true);
 | 
			
		||||
        return 0;
 | 
			
		||||
	return 0;
 | 
			
		||||
	break;
 | 
			
		||||
 | 
			
		||||
      CASE (SNDCTL_DSP_GETBLKSIZE)
 | 
			
		||||
| 
						 | 
				
			
			@ -1328,8 +1328,8 @@ fhandler_dev_dsp::ioctl (unsigned int cmd, void *ptr)
 | 
			
		|||
      CASE (SNDCTL_DSP_SYNC)
 | 
			
		||||
	// Stop audio out device
 | 
			
		||||
	close_audio_out ();
 | 
			
		||||
        // Stop audio in device
 | 
			
		||||
        close_audio_in ();
 | 
			
		||||
	// Stop audio in device
 | 
			
		||||
	close_audio_in ();
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -849,36 +849,36 @@ format_proc_cpuinfo (char *destbuf, size_t maxsize)
 | 
			
		|||
	      if (features1 & (1 << 25))
 | 
			
		||||
		print (" sse");
 | 
			
		||||
	      if (is_intel)
 | 
			
		||||
	        {
 | 
			
		||||
	          if (features1 & (1 << 26))
 | 
			
		||||
		{
 | 
			
		||||
		  if (features1 & (1 << 26))
 | 
			
		||||
		    print (" sse2");
 | 
			
		||||
	          if (features1 & (1 << 27))
 | 
			
		||||
		  if (features1 & (1 << 27))
 | 
			
		||||
		    print (" ss");
 | 
			
		||||
	          if (features1 & (1 << 28))
 | 
			
		||||
		  if (features1 & (1 << 28))
 | 
			
		||||
		    print (" htt");
 | 
			
		||||
	          if (features1 & (1 << 29))
 | 
			
		||||
		  if (features1 & (1 << 29))
 | 
			
		||||
		    print (" tmi");
 | 
			
		||||
	          if (features1 & (1 << 30))
 | 
			
		||||
		  if (features1 & (1 << 30))
 | 
			
		||||
		    print (" ia-64");
 | 
			
		||||
	          if (features1 & (1 << 31))
 | 
			
		||||
		  if (features1 & (1 << 31))
 | 
			
		||||
		    print (" pbe");
 | 
			
		||||
 | 
			
		||||
	          if (features2 & (1 << 0))
 | 
			
		||||
		  if (features2 & (1 << 0))
 | 
			
		||||
		    print (" pni");
 | 
			
		||||
	          if (features2 & (1 << 3))
 | 
			
		||||
		  if (features2 & (1 << 3))
 | 
			
		||||
		    print (" monitor");
 | 
			
		||||
	          if (features2 & (1 << 4))
 | 
			
		||||
		  if (features2 & (1 << 4))
 | 
			
		||||
		    print (" ds_cpl");
 | 
			
		||||
		  if (features2 & (1 << 7))
 | 
			
		||||
		    print (" tm2");
 | 
			
		||||
	          if (features2 & (1 << 8))
 | 
			
		||||
		  if (features2 & (1 << 8))
 | 
			
		||||
		    print (" est");
 | 
			
		||||
	         if (features2 & (1 << 10))
 | 
			
		||||
		 if (features2 & (1 << 10))
 | 
			
		||||
		    print (" cid");
 | 
			
		||||
	        }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	      if (is_amd && maxe >= 0x80000001)
 | 
			
		||||
	        {
 | 
			
		||||
		{
 | 
			
		||||
		  // uses AMD extended calls to check
 | 
			
		||||
		  // for 3dnow and 3dnow extended support
 | 
			
		||||
		  // (source: AMD Athlon Processor Recognition Application Note)
 | 
			
		||||
| 
						 | 
				
			
			@ -887,14 +887,14 @@ format_proc_cpuinfo (char *destbuf, size_t maxsize)
 | 
			
		|||
		    {
 | 
			
		||||
		      cpuid (&unused, &unused, &unused, &features2, 0x80000001);
 | 
			
		||||
 | 
			
		||||
                      if (features2 & (1 << 11))
 | 
			
		||||
		        print (" syscall");
 | 
			
		||||
                      if (features2 & (1 << 19))
 | 
			
		||||
		        print (" mp");
 | 
			
		||||
                      if (features2 & (1 << 22))
 | 
			
		||||
                        print (" mmxext");
 | 
			
		||||
                      if (features2 & (1 << 29))
 | 
			
		||||
                        print (" lm");
 | 
			
		||||
		      if (features2 & (1 << 11))
 | 
			
		||||
			print (" syscall");
 | 
			
		||||
		      if (features2 & (1 << 19))
 | 
			
		||||
			print (" mp");
 | 
			
		||||
		      if (features2 & (1 << 22))
 | 
			
		||||
			print (" mmxext");
 | 
			
		||||
		      if (features2 & (1 << 29))
 | 
			
		||||
			print (" lm");
 | 
			
		||||
		      if (features2 & (1 << 30)) // 31th bit is on
 | 
			
		||||
			print (" 3dnowext");
 | 
			
		||||
		      if (features2 & (1 << 31)) // 32th bit (highest) is on
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,12 +31,6 @@ details. */
 | 
			
		|||
#include "cygmalloc.h"
 | 
			
		||||
#include "cygthread.h"
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUGGING
 | 
			
		||||
static int npid;
 | 
			
		||||
static int npid_max;
 | 
			
		||||
static pid_t fork_pids[100];
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Timeout to wait for child to start, parent to init child, etc.  */
 | 
			
		||||
/* FIXME: Once things stabilize, bump up to a few minutes.  */
 | 
			
		||||
#define FORK_WAIT_TIMEOUT (300 * 1000)     /* 300 seconds */
 | 
			
		||||
| 
						 | 
				
			
			@ -318,7 +312,6 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
 | 
			
		|||
 | 
			
		||||
  pthread::atforkchild ();
 | 
			
		||||
  fixup_timers_after_fork ();
 | 
			
		||||
  wait_for_sigthread ();
 | 
			
		||||
  cygbench ("fork-child");
 | 
			
		||||
  cygwin_finished_initializing = true;
 | 
			
		||||
  return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -425,7 +418,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
 | 
			
		|||
  ProtectHandleINH (subproc_ready);
 | 
			
		||||
  ProtectHandleINH (forker_finished);
 | 
			
		||||
 | 
			
		||||
  init_child_info (PROC_FORK, &ch, 1, subproc_ready);
 | 
			
		||||
  init_child_info (PROC_FORK, &ch, subproc_ready);
 | 
			
		||||
 | 
			
		||||
  ch.forker_finished = forker_finished;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -439,23 +432,6 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
 | 
			
		|||
  cygheap->user.deimpersonate ();
 | 
			
		||||
 | 
			
		||||
  ch.parent = hParent;
 | 
			
		||||
#ifdef DEBUGGING
 | 
			
		||||
  if (npid_max)
 | 
			
		||||
    {
 | 
			
		||||
      for (int pass = 0; pass < 2; pass++)
 | 
			
		||||
	{
 | 
			
		||||
	  pid_t pid;
 | 
			
		||||
	  while ((pid = fork_pids[npid++]))
 | 
			
		||||
	    if (!pinfo (pid))
 | 
			
		||||
	      {
 | 
			
		||||
		ch.cygpid = pid;
 | 
			
		||||
		goto out;
 | 
			
		||||
	      }
 | 
			
		||||
	  npid = 0;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 out:
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %x, 0, 0, %p, %p)",
 | 
			
		||||
		  myself->progname, myself->progname, c_flags, &si, &pi);
 | 
			
		||||
| 
						 | 
				
			
			@ -499,11 +475,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
 | 
			
		|||
      ResumeThread (pi.hThread);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUGGING
 | 
			
		||||
  int forked_pid = ch.cygpid != 1 ? ch.cygpid : cygwin_pid (pi.dwProcessId);
 | 
			
		||||
#else
 | 
			
		||||
  int forked_pid = cygwin_pid (pi.dwProcessId);
 | 
			
		||||
#endif
 | 
			
		||||
  pinfo forked (forked_pid, 1);
 | 
			
		||||
 | 
			
		||||
  if (!forked)
 | 
			
		||||
| 
						 | 
				
			
			@ -665,11 +637,13 @@ fork ()
 | 
			
		|||
 | 
			
		||||
  child_info_fork ch;
 | 
			
		||||
 | 
			
		||||
  sig_send (NULL, __SIGHOLD);
 | 
			
		||||
  int res = setjmp (ch.jmp);
 | 
			
		||||
  if (res)
 | 
			
		||||
    res = fork_child (grouped.hParent, grouped.first_dll, grouped.load_dlls);
 | 
			
		||||
  else
 | 
			
		||||
    res = fork_parent (grouped.hParent, grouped.first_dll, grouped.load_dlls, esp, ch);
 | 
			
		||||
  sig_send (NULL, __SIGNOHOLD);
 | 
			
		||||
 | 
			
		||||
  MALLOC_CHECK;
 | 
			
		||||
  syscall_printf ("%d = fork()", res);
 | 
			
		||||
| 
						 | 
				
			
			@ -679,13 +653,6 @@ fork ()
 | 
			
		|||
void
 | 
			
		||||
fork_init ()
 | 
			
		||||
{
 | 
			
		||||
  char buf[1024];
 | 
			
		||||
  if (!GetEnvironmentVariable ("CYGWIN_FORK_PIDS", buf, 1024))
 | 
			
		||||
    return;
 | 
			
		||||
  pid_t pid;
 | 
			
		||||
  char *p, *pe;
 | 
			
		||||
  for (p = buf; (pid = strtol (p, &pe, 10)); p = pe)
 | 
			
		||||
    fork_pids[npid_max++] = pid;
 | 
			
		||||
}
 | 
			
		||||
#endif /*DEBUGGING*/
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -116,10 +116,10 @@ dll_entry (HANDLE h, DWORD reason, void *static_load)
 | 
			
		|||
    {
 | 
			
		||||
    case DLL_PROCESS_ATTACH:
 | 
			
		||||
      /* Is the stack at an unusual high address?  Check if we're running on
 | 
			
		||||
         a 64 bit machine.  If so, respawn. */
 | 
			
		||||
	 a 64 bit machine.  If so, respawn. */
 | 
			
		||||
      if (&is_64bit_machine >= (PBOOL) 0x400000
 | 
			
		||||
          && IsWow64Process (hMainProc, &is_64bit_machine)
 | 
			
		||||
          && is_64bit_machine)
 | 
			
		||||
	  && IsWow64Process (hMainProc, &is_64bit_machine)
 | 
			
		||||
	  && is_64bit_machine)
 | 
			
		||||
	respawn_wow64_process ();
 | 
			
		||||
 | 
			
		||||
      prime_threads ();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -797,7 +797,7 @@ mprotect (void *addr, size_t len, int prot)
 | 
			
		|||
    {
 | 
			
		||||
      MEMORY_BASIC_INFORMATION mbi;
 | 
			
		||||
      if (VirtualQuery (addr, &mbi, sizeof mbi))
 | 
			
		||||
        {
 | 
			
		||||
	{
 | 
			
		||||
	  if (mbi.AllocationProtect == PAGE_WRITECOPY
 | 
			
		||||
	      || mbi.AllocationProtect == PAGE_EXECUTE_WRITECOPY)
 | 
			
		||||
	    writecopy = true;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -981,14 +981,14 @@ normalize_win32_path (const char *src, char *dst, char **tail)
 | 
			
		|||
  else if (strchr (src, ':') == NULL && *src != '/')
 | 
			
		||||
    {
 | 
			
		||||
      if (beg_src_slash)
 | 
			
		||||
        dst += cygheap->cwd.get_drive (dst);
 | 
			
		||||
	dst += cygheap->cwd.get_drive (dst);
 | 
			
		||||
      else if (!cygheap->cwd.get (dst, 0))
 | 
			
		||||
	return get_errno ();
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          dst += strlen (dst);
 | 
			
		||||
          *dst++ = '\\';
 | 
			
		||||
        }
 | 
			
		||||
	{
 | 
			
		||||
	  dst += strlen (dst);
 | 
			
		||||
	  *dst++ = '\\';
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  while (*src)
 | 
			
		||||
| 
						 | 
				
			
			@ -1508,11 +1508,11 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
 | 
			
		|||
	return err;
 | 
			
		||||
      chroot_ok = true;
 | 
			
		||||
    }
 | 
			
		||||
  else 
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      int offset = 0;
 | 
			
		||||
      if (src_path[1] != '/' && src_path[1] != ':')
 | 
			
		||||
        offset = cygheap->cwd.get_drive (dst);
 | 
			
		||||
	offset = cygheap->cwd.get_drive (dst);
 | 
			
		||||
      backslashify (src_path, dst + offset, 0);
 | 
			
		||||
    }
 | 
			
		||||
 out:
 | 
			
		||||
| 
						 | 
				
			
			@ -2189,7 +2189,7 @@ mount_info::add_item (const char *native, const char *posix, unsigned mountflags
 | 
			
		|||
    posixerr = normalize_posix_path (posix, posixtmp, &posixtail);
 | 
			
		||||
 | 
			
		||||
  debug_printf ("%s[%s], %s[%s], %p",
 | 
			
		||||
                native, nativeerr ? error : nativetmp,
 | 
			
		||||
		native, nativeerr ? error : nativetmp,
 | 
			
		||||
		posix, posixerr ? error : posixtmp, mountflags);
 | 
			
		||||
 | 
			
		||||
  if (nativeerr || posixerr)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,7 +44,7 @@ pinfo_fixup_after_fork ()
 | 
			
		|||
{
 | 
			
		||||
  if (hexec_proc)
 | 
			
		||||
    CloseHandle (hexec_proc);
 | 
			
		||||
  /* Keeps the cygpid from being reused. No rights required */
 | 
			
		||||
  /* Keeps the cygpid from being reused.  No rights required */
 | 
			
		||||
  if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &hexec_proc, 0,
 | 
			
		||||
			TRUE, 0))
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -58,19 +58,18 @@ pinfo_fixup_after_fork ()
 | 
			
		|||
   This is done once when the dll is first loaded.  */
 | 
			
		||||
 | 
			
		||||
void __stdcall
 | 
			
		||||
set_myself (pid_t pid, HANDLE h)
 | 
			
		||||
set_myself (HANDLE h)
 | 
			
		||||
{
 | 
			
		||||
  DWORD winpid = GetCurrentProcessId ();
 | 
			
		||||
  if (pid == 1)
 | 
			
		||||
    pid = cygwin_pid (winpid);
 | 
			
		||||
  myself.init (pid, PID_IN_USE | PID_MYSELF, h);
 | 
			
		||||
  myself->dwProcessId = winpid;
 | 
			
		||||
  if (!h)
 | 
			
		||||
    cygheap->pid = cygwin_pid (GetCurrentProcessId ());
 | 
			
		||||
  myself.init (cygheap->pid, PID_IN_USE | PID_MYSELF, h);
 | 
			
		||||
  myself->process_state |= PID_IN_USE;
 | 
			
		||||
  myself->start_time = time (NULL); /* Register our starting time. */
 | 
			
		||||
 | 
			
		||||
  (void) GetModuleFileName (NULL, myself->progname, sizeof (myself->progname));
 | 
			
		||||
  if (!strace.active)
 | 
			
		||||
    strace.hello ();
 | 
			
		||||
  debug_printf ("myself->dwProcessId %u", myself->dwProcessId);
 | 
			
		||||
  InitializeCriticalSection (&myself->lock);
 | 
			
		||||
  return;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -90,7 +89,7 @@ pinfo_init (char **envp, int envc)
 | 
			
		|||
    {
 | 
			
		||||
      /* Invent our own pid.  */
 | 
			
		||||
 | 
			
		||||
      set_myself (1);
 | 
			
		||||
      set_myself (NULL);
 | 
			
		||||
      myself->ppid = 1;
 | 
			
		||||
      myself->pgid = myself->sid = myself->pid;
 | 
			
		||||
      myself->ctty = -1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -223,9 +223,9 @@ leave:
 | 
			
		|||
   unlike CreatePipe, which returns a bool for success or failure.  */
 | 
			
		||||
static int
 | 
			
		||||
create_selectable_pipe (PHANDLE read_pipe_ptr,
 | 
			
		||||
                        PHANDLE write_pipe_ptr,
 | 
			
		||||
                        LPSECURITY_ATTRIBUTES sa_ptr,
 | 
			
		||||
                        DWORD psize)
 | 
			
		||||
			PHANDLE write_pipe_ptr,
 | 
			
		||||
			LPSECURITY_ATTRIBUTES sa_ptr,
 | 
			
		||||
			DWORD psize)
 | 
			
		||||
{
 | 
			
		||||
  /* Default to error. */
 | 
			
		||||
  *read_pipe_ptr = *write_pipe_ptr = INVALID_HANDLE_VALUE;
 | 
			
		||||
| 
						 | 
				
			
			@ -251,62 +251,62 @@ create_selectable_pipe (PHANDLE read_pipe_ptr,
 | 
			
		|||
      debug_printf ("CreateNamedPipe: name %s, size %lu", pipename, psize);
 | 
			
		||||
 | 
			
		||||
      /* Use CreateNamedPipe instead of CreatePipe, because the latter
 | 
			
		||||
         returns a write handle that does not permit FILE_READ_ATTRIBUTES
 | 
			
		||||
         access, on versions of win32 earlier than WinXP SP2.
 | 
			
		||||
         CreatePipe also stupidly creates a full duplex pipe, which is
 | 
			
		||||
         a waste, since only a single direction is actually used.
 | 
			
		||||
         It's important to only allow a single instance, to ensure that
 | 
			
		||||
         the pipe was not created earlier by some other process, even if
 | 
			
		||||
         the pid has been reused.  We avoid FILE_FLAG_FIRST_PIPE_INSTANCE
 | 
			
		||||
         because that is only available for Win2k SP2 and WinXP.  */
 | 
			
		||||
	 returns a write handle that does not permit FILE_READ_ATTRIBUTES
 | 
			
		||||
	 access, on versions of win32 earlier than WinXP SP2.
 | 
			
		||||
	 CreatePipe also stupidly creates a full duplex pipe, which is
 | 
			
		||||
	 a waste, since only a single direction is actually used.
 | 
			
		||||
	 It's important to only allow a single instance, to ensure that
 | 
			
		||||
	 the pipe was not created earlier by some other process, even if
 | 
			
		||||
	 the pid has been reused.  We avoid FILE_FLAG_FIRST_PIPE_INSTANCE
 | 
			
		||||
	 because that is only available for Win2k SP2 and WinXP.  */
 | 
			
		||||
      SetLastError (0);
 | 
			
		||||
      read_pipe = CreateNamedPipe (pipename,
 | 
			
		||||
                                   PIPE_ACCESS_INBOUND,
 | 
			
		||||
                                   PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
 | 
			
		||||
                                   1,       /* max instances */
 | 
			
		||||
                                   psize,   /* output buffer size */
 | 
			
		||||
                                   psize,   /* input buffer size */
 | 
			
		||||
                                   NMPWAIT_USE_DEFAULT_WAIT,
 | 
			
		||||
                                   sa_ptr);
 | 
			
		||||
				   PIPE_ACCESS_INBOUND,
 | 
			
		||||
				   PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
 | 
			
		||||
				   1,       /* max instances */
 | 
			
		||||
				   psize,   /* output buffer size */
 | 
			
		||||
				   psize,   /* input buffer size */
 | 
			
		||||
				   NMPWAIT_USE_DEFAULT_WAIT,
 | 
			
		||||
				   sa_ptr);
 | 
			
		||||
 | 
			
		||||
      DWORD err = GetLastError ();
 | 
			
		||||
      /* Win 95 seems to return NULL instead of INVALID_HANDLE_VALUE */
 | 
			
		||||
      if ((read_pipe || !err) && read_pipe != INVALID_HANDLE_VALUE)
 | 
			
		||||
        {
 | 
			
		||||
          debug_printf ("pipe read handle %p", read_pipe);
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
	{
 | 
			
		||||
	  debug_printf ("pipe read handle %p", read_pipe);
 | 
			
		||||
	  break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      switch (err)
 | 
			
		||||
        {
 | 
			
		||||
        case ERROR_PIPE_BUSY:
 | 
			
		||||
          /* The pipe is already open with compatible parameters.
 | 
			
		||||
             Pick a new name and retry.  */
 | 
			
		||||
          debug_printf ("pipe busy, retrying");
 | 
			
		||||
          continue;
 | 
			
		||||
        case ERROR_ACCESS_DENIED:
 | 
			
		||||
          /* The pipe is already open with incompatible parameters.
 | 
			
		||||
             Pick a new name and retry.  */
 | 
			
		||||
          debug_printf ("pipe access denied, retrying");
 | 
			
		||||
          continue;
 | 
			
		||||
        case ERROR_CALL_NOT_IMPLEMENTED:
 | 
			
		||||
          /* We are on an older Win9x platform without named pipes.
 | 
			
		||||
             Return an anonymous pipe as the best approximation.  */
 | 
			
		||||
          debug_printf ("CreateNamedPipe not implemented, resorting to "
 | 
			
		||||
                        "CreatePipe size %lu", psize);
 | 
			
		||||
          if (CreatePipe (read_pipe_ptr, write_pipe_ptr, sa_ptr, psize))
 | 
			
		||||
            {
 | 
			
		||||
              debug_printf ("pipe read handle %p", *read_pipe_ptr);
 | 
			
		||||
              debug_printf ("pipe write handle %p", *write_pipe_ptr);
 | 
			
		||||
              return NO_ERROR;
 | 
			
		||||
            }
 | 
			
		||||
          err = GetLastError ();
 | 
			
		||||
          debug_printf ("CreatePipe failed, %E");
 | 
			
		||||
          return err;
 | 
			
		||||
        default:
 | 
			
		||||
          debug_printf ("CreateNamedPipe failed, %E");
 | 
			
		||||
          return err;
 | 
			
		||||
        }
 | 
			
		||||
	{
 | 
			
		||||
	case ERROR_PIPE_BUSY:
 | 
			
		||||
	  /* The pipe is already open with compatible parameters.
 | 
			
		||||
	     Pick a new name and retry.  */
 | 
			
		||||
	  debug_printf ("pipe busy, retrying");
 | 
			
		||||
	  continue;
 | 
			
		||||
	case ERROR_ACCESS_DENIED:
 | 
			
		||||
	  /* The pipe is already open with incompatible parameters.
 | 
			
		||||
	     Pick a new name and retry.  */
 | 
			
		||||
	  debug_printf ("pipe access denied, retrying");
 | 
			
		||||
	  continue;
 | 
			
		||||
	case ERROR_CALL_NOT_IMPLEMENTED:
 | 
			
		||||
	  /* We are on an older Win9x platform without named pipes.
 | 
			
		||||
	     Return an anonymous pipe as the best approximation.  */
 | 
			
		||||
	  debug_printf ("CreateNamedPipe not implemented, resorting to "
 | 
			
		||||
			"CreatePipe size %lu", psize);
 | 
			
		||||
	  if (CreatePipe (read_pipe_ptr, write_pipe_ptr, sa_ptr, psize))
 | 
			
		||||
	    {
 | 
			
		||||
	      debug_printf ("pipe read handle %p", *read_pipe_ptr);
 | 
			
		||||
	      debug_printf ("pipe write handle %p", *write_pipe_ptr);
 | 
			
		||||
	      return NO_ERROR;
 | 
			
		||||
	    }
 | 
			
		||||
	  err = GetLastError ();
 | 
			
		||||
	  debug_printf ("CreatePipe failed, %E");
 | 
			
		||||
	  return err;
 | 
			
		||||
	default:
 | 
			
		||||
	  debug_printf ("CreateNamedPipe failed, %E");
 | 
			
		||||
	  return err;
 | 
			
		||||
	}
 | 
			
		||||
      /* NOTREACHED */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -315,12 +315,12 @@ create_selectable_pipe (PHANDLE read_pipe_ptr,
 | 
			
		|||
  /* Open the named pipe for writing.
 | 
			
		||||
     Be sure to permit FILE_READ_ATTRIBUTES access.  */
 | 
			
		||||
  write_pipe = CreateFile (pipename,
 | 
			
		||||
                           GENERIC_WRITE | FILE_READ_ATTRIBUTES,
 | 
			
		||||
                           0,       /* share mode */
 | 
			
		||||
                           sa_ptr,
 | 
			
		||||
                           OPEN_EXISTING,
 | 
			
		||||
                           0,       /* flags and attributes */
 | 
			
		||||
                           0);      /* handle to template file */
 | 
			
		||||
			   GENERIC_WRITE | FILE_READ_ATTRIBUTES,
 | 
			
		||||
			   0,       /* share mode */
 | 
			
		||||
			   sa_ptr,
 | 
			
		||||
			   OPEN_EXISTING,
 | 
			
		||||
			   0,       /* flags and attributes */
 | 
			
		||||
			   0);      /* handle to template file */
 | 
			
		||||
 | 
			
		||||
  if (write_pipe == INVALID_HANDLE_VALUE)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -163,8 +163,8 @@ str2buf2uni (UNICODE_STRING &tgt, WCHAR *buf, const char *srcstr)
 | 
			
		|||
{
 | 
			
		||||
  tgt.Buffer = (PWCHAR) buf;
 | 
			
		||||
  tgt.MaximumLength = (strlen (srcstr) + 1) * sizeof (WCHAR);
 | 
			
		||||
  tgt.Length = sys_mbstowcs (buf, srcstr, tgt.MaximumLength / sizeof (WCHAR)) 
 | 
			
		||||
               * sizeof (WCHAR);
 | 
			
		||||
  tgt.Length = sys_mbstowcs (buf, srcstr, tgt.MaximumLength / sizeof (WCHAR))
 | 
			
		||||
	       * sizeof (WCHAR);
 | 
			
		||||
  if (tgt.Length)
 | 
			
		||||
    tgt.Length -= sizeof (WCHAR);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -173,7 +173,7 @@ void
 | 
			
		|||
str2uni_cat (UNICODE_STRING &tgt, const char *srcstr)
 | 
			
		||||
{
 | 
			
		||||
  int len = sys_mbstowcs (tgt.Buffer + tgt.Length / sizeof (WCHAR), srcstr,
 | 
			
		||||
		          (tgt.MaximumLength - tgt.Length) / sizeof (WCHAR));
 | 
			
		||||
			  (tgt.MaximumLength - tgt.Length) / sizeof (WCHAR));
 | 
			
		||||
  if (len)
 | 
			
		||||
    tgt.Length += (len - 1) * sizeof (WCHAR);
 | 
			
		||||
  else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -507,63 +507,63 @@ out:
 | 
			
		|||
  if (s->write_selected)
 | 
			
		||||
    {
 | 
			
		||||
      if (s->write_ready)
 | 
			
		||||
        {
 | 
			
		||||
          select_printf ("%s, already ready for write", fh->get_name ());
 | 
			
		||||
          gotone++;
 | 
			
		||||
        }
 | 
			
		||||
	{
 | 
			
		||||
	  select_printf ("%s, already ready for write", fh->get_name ());
 | 
			
		||||
	  gotone++;
 | 
			
		||||
	}
 | 
			
		||||
      /* Do we need to do anything about SIGTTOU here? */
 | 
			
		||||
      else if (fh->get_device () == FH_PIPER)
 | 
			
		||||
	select_printf ("%s, select for write on read end of pipe",
 | 
			
		||||
		       fh->get_name ());
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          /* We don't worry about the guard mutex, because that only applies
 | 
			
		||||
             when from_select is false, and peek_pipe is never called that
 | 
			
		||||
             way for writes.  */
 | 
			
		||||
	{
 | 
			
		||||
	  /* We don't worry about the guard mutex, because that only applies
 | 
			
		||||
	     when from_select is false, and peek_pipe is never called that
 | 
			
		||||
	     way for writes.  */
 | 
			
		||||
 | 
			
		||||
          IO_STATUS_BLOCK iosb = {0};
 | 
			
		||||
          FILE_PIPE_LOCAL_INFORMATION fpli = {0};
 | 
			
		||||
	  IO_STATUS_BLOCK iosb = {0};
 | 
			
		||||
	  FILE_PIPE_LOCAL_INFORMATION fpli = {0};
 | 
			
		||||
 | 
			
		||||
          if (NtQueryInformationFile (h,
 | 
			
		||||
                                      &iosb,
 | 
			
		||||
                                      &fpli,
 | 
			
		||||
                                      sizeof (fpli),
 | 
			
		||||
                                      FilePipeLocalInformation))
 | 
			
		||||
            {
 | 
			
		||||
              /* If NtQueryInformationFile fails, optimistically assume the
 | 
			
		||||
                 pipe is writable.  This could happen on Win9x, because
 | 
			
		||||
                 NtQueryInformationFile is not available, or if we somehow
 | 
			
		||||
                 inherit a pipe that doesn't permit FILE_READ_ATTRIBUTES
 | 
			
		||||
                 access on the write end.  */
 | 
			
		||||
              select_printf ("%s, NtQueryInformationFile failed",
 | 
			
		||||
                             fh->get_name ());
 | 
			
		||||
              gotone += s->write_ready = true;
 | 
			
		||||
            }
 | 
			
		||||
          /* Ensure that enough space is available for atomic writes,
 | 
			
		||||
             as required by POSIX.  Subsequent writes with size > PIPE_BUF
 | 
			
		||||
             can still block, but most (all?) UNIX variants seem to work
 | 
			
		||||
             this way (e.g., BSD, Linux, Solaris).  */
 | 
			
		||||
          else if (fpli.WriteQuotaAvailable >= PIPE_BUF)
 | 
			
		||||
            {
 | 
			
		||||
              select_printf ("%s, ready for write: size %lu, avail %lu",
 | 
			
		||||
                             fh->get_name (),
 | 
			
		||||
                             fpli.OutboundQuota,
 | 
			
		||||
                             fpli.WriteQuotaAvailable);
 | 
			
		||||
              gotone += s->write_ready = true;
 | 
			
		||||
            }
 | 
			
		||||
          /* If we somehow inherit a tiny pipe (size < PIPE_BUF), then consider
 | 
			
		||||
             the pipe writable only if it is completely empty, to minimize the
 | 
			
		||||
             probability that a subsequent write will block.  */
 | 
			
		||||
          else if (fpli.OutboundQuota < PIPE_BUF &&
 | 
			
		||||
                   fpli.WriteQuotaAvailable == fpli.OutboundQuota)
 | 
			
		||||
            {
 | 
			
		||||
              select_printf ("%s, tiny pipe: size %lu, avail %lu",
 | 
			
		||||
                             fh->get_name (),
 | 
			
		||||
                             fpli.OutboundQuota,
 | 
			
		||||
                             fpli.WriteQuotaAvailable);
 | 
			
		||||
              gotone += s->write_ready = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
	  if (NtQueryInformationFile (h,
 | 
			
		||||
				      &iosb,
 | 
			
		||||
				      &fpli,
 | 
			
		||||
				      sizeof (fpli),
 | 
			
		||||
				      FilePipeLocalInformation))
 | 
			
		||||
	    {
 | 
			
		||||
	      /* If NtQueryInformationFile fails, optimistically assume the
 | 
			
		||||
		 pipe is writable.  This could happen on Win9x, because
 | 
			
		||||
		 NtQueryInformationFile is not available, or if we somehow
 | 
			
		||||
		 inherit a pipe that doesn't permit FILE_READ_ATTRIBUTES
 | 
			
		||||
		 access on the write end.  */
 | 
			
		||||
	      select_printf ("%s, NtQueryInformationFile failed",
 | 
			
		||||
			     fh->get_name ());
 | 
			
		||||
	      gotone += s->write_ready = true;
 | 
			
		||||
	    }
 | 
			
		||||
	  /* Ensure that enough space is available for atomic writes,
 | 
			
		||||
	     as required by POSIX.  Subsequent writes with size > PIPE_BUF
 | 
			
		||||
	     can still block, but most (all?) UNIX variants seem to work
 | 
			
		||||
	     this way (e.g., BSD, Linux, Solaris).  */
 | 
			
		||||
	  else if (fpli.WriteQuotaAvailable >= PIPE_BUF)
 | 
			
		||||
	    {
 | 
			
		||||
	      select_printf ("%s, ready for write: size %lu, avail %lu",
 | 
			
		||||
			     fh->get_name (),
 | 
			
		||||
			     fpli.OutboundQuota,
 | 
			
		||||
			     fpli.WriteQuotaAvailable);
 | 
			
		||||
	      gotone += s->write_ready = true;
 | 
			
		||||
	    }
 | 
			
		||||
	  /* If we somehow inherit a tiny pipe (size < PIPE_BUF), then consider
 | 
			
		||||
	     the pipe writable only if it is completely empty, to minimize the
 | 
			
		||||
	     probability that a subsequent write will block.  */
 | 
			
		||||
	  else if (fpli.OutboundQuota < PIPE_BUF &&
 | 
			
		||||
		   fpli.WriteQuotaAvailable == fpli.OutboundQuota)
 | 
			
		||||
	    {
 | 
			
		||||
	      select_printf ("%s, tiny pipe: size %lu, avail %lu",
 | 
			
		||||
			     fh->get_name (),
 | 
			
		||||
			     fpli.OutboundQuota,
 | 
			
		||||
			     fpli.WriteQuotaAvailable);
 | 
			
		||||
	      gotone += s->write_ready = true;
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return gotone;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -707,6 +707,8 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
 | 
			
		|||
    sendsig = myself->sendsig;
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      for (int i = 0; !p->dwProcessId && i < 10000; i++)
 | 
			
		||||
	low_priority_sleep (0);
 | 
			
		||||
      HANDLE hp = OpenProcess (PROCESS_DUP_HANDLE, false, p->dwProcessId);
 | 
			
		||||
      if (!hp)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -854,14 +856,13 @@ subproc_init (void)
 | 
			
		|||
   by fork/spawn/exec. */
 | 
			
		||||
 | 
			
		||||
void __stdcall
 | 
			
		||||
init_child_info (DWORD chtype, child_info *ch, pid_t pid, HANDLE subproc_ready)
 | 
			
		||||
init_child_info (DWORD chtype, child_info *ch, HANDLE subproc_ready)
 | 
			
		||||
{
 | 
			
		||||
  memset (ch, 0, sizeof *ch);
 | 
			
		||||
  ch->cb = chtype == PROC_FORK ? sizeof (child_info_fork) : sizeof (child_info);
 | 
			
		||||
  ch->intro = PROC_MAGIC_GENERIC;
 | 
			
		||||
  ch->magic = CHILD_INFO_MAGIC;
 | 
			
		||||
  ch->type = chtype;
 | 
			
		||||
  ch->cygpid = pid;
 | 
			
		||||
  ch->subproc_ready = subproc_ready;
 | 
			
		||||
  ch->pppid_handle = myself->ppid_handle;
 | 
			
		||||
  ch->fhandler_union_cb = sizeof (fhandler_union);
 | 
			
		||||
| 
						 | 
				
			
			@ -1064,6 +1065,7 @@ wait_sig (VOID *self)
 | 
			
		|||
{
 | 
			
		||||
  HANDLE readsig;
 | 
			
		||||
  char sa_buf[1024];
 | 
			
		||||
  Static bool holding_signals;
 | 
			
		||||
 | 
			
		||||
  /* Initialization */
 | 
			
		||||
  (void) SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY);
 | 
			
		||||
| 
						 | 
				
			
			@ -1080,6 +1082,7 @@ wait_sig (VOID *self)
 | 
			
		|||
  myself->process_state |= PID_ACTIVE;
 | 
			
		||||
  myself->process_state &= ~PID_INITIALIZING;
 | 
			
		||||
 | 
			
		||||
  sigproc_printf ("myself->dwProcessId %u", myself->dwProcessId);
 | 
			
		||||
  /* If we've been execed, then there is still a stub left in the previous
 | 
			
		||||
     windows process waiting to see if it's started a cygwin process or not.
 | 
			
		||||
     Signalling subproc_ready indicates that we are a cygwin process.  */
 | 
			
		||||
| 
						 | 
				
			
			@ -1159,9 +1162,17 @@ wait_sig (VOID *self)
 | 
			
		|||
	    if (q->si.si_signo == __SIGDELETE || q->process () > 0)
 | 
			
		||||
	      sigq.del ();
 | 
			
		||||
	  break;
 | 
			
		||||
	case __SIGHOLD:
 | 
			
		||||
	  holding_signals = 1;
 | 
			
		||||
	  break;
 | 
			
		||||
	case __SIGNOHOLD:
 | 
			
		||||
	  holding_signals = 0;
 | 
			
		||||
	  break;
 | 
			
		||||
	default:
 | 
			
		||||
	  if (pack.si.si_signo < 0)
 | 
			
		||||
	    sig_clear (-pack.si.si_signo);
 | 
			
		||||
	  else if (holding_signals)
 | 
			
		||||
	    sigq.add (pack);
 | 
			
		||||
	  else
 | 
			
		||||
	    {
 | 
			
		||||
	      int sig = pack.si.si_signo;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,7 +24,9 @@ enum
 | 
			
		|||
  __SIGCOMMUNE	    = -(NSIG + 3),
 | 
			
		||||
  __SIGPENDING	    = -(NSIG + 4),
 | 
			
		||||
  __SIGDELETE	    = -(NSIG + 5),
 | 
			
		||||
  __SIGFLUSHFAST    = -(NSIG + 6)
 | 
			
		||||
  __SIGFLUSHFAST    = -(NSIG + 6),
 | 
			
		||||
  __SIGHOLD	    = -(NSIG + 7),
 | 
			
		||||
  __SIGNOHOLD	    = -(NSIG + 8)
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -393,8 +393,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
 | 
			
		|||
      ProtectHandleINH (subproc_ready);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  init_child_info (chtype, &ciresrv, (mode == _P_OVERLAY) ? myself->pid : 1,
 | 
			
		||||
		   subproc_ready);
 | 
			
		||||
  init_child_info (chtype, &ciresrv, subproc_ready);
 | 
			
		||||
 | 
			
		||||
  ciresrv.moreinfo = (cygheap_exec_info *) ccalloc (HEAP_1_EXEC, 1, sizeof (cygheap_exec_info));
 | 
			
		||||
  ciresrv.moreinfo->old_title = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -630,6 +629,10 @@ spawn_guts (const char * prog_arg, const char *const *argv,
 | 
			
		|||
    flags |= DETACHED_PROCESS;
 | 
			
		||||
  if (mode != _P_OVERLAY)
 | 
			
		||||
    flags |= CREATE_SUSPENDED;
 | 
			
		||||
#if 0 //someday
 | 
			
		||||
  else
 | 
			
		||||
    myself->dwProcessId = 0;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  /* Some file types (currently only sockets) need extra effort in the
 | 
			
		||||
     parent after CreateProcess and before copying the datastructures
 | 
			
		||||
| 
						 | 
				
			
			@ -638,7 +641,6 @@ spawn_guts (const char * prog_arg, const char *const *argv,
 | 
			
		|||
  if (cygheap->fdtab.need_fixup_before ())
 | 
			
		||||
    flags |= CREATE_SUSPENDED;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  const char *runpath = null_app_name ? NULL : (const char *) real_path;
 | 
			
		||||
 | 
			
		||||
  syscall_printf ("null_app_name %d (%s, %.9500s)", null_app_name, runpath, one_line.buf);
 | 
			
		||||
| 
						 | 
				
			
			@ -649,6 +651,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
 | 
			
		|||
 | 
			
		||||
  cygheap->fdtab.set_file_pointers_for_exec ();
 | 
			
		||||
  cygheap->user.deimpersonate ();
 | 
			
		||||
 | 
			
		||||
  /* When ruid != euid we create the new process under the current original
 | 
			
		||||
     account and impersonate in child, this way maintaining the different
 | 
			
		||||
     effective vs. real ids.
 | 
			
		||||
| 
						 | 
				
			
			@ -729,6 +732,10 @@ spawn_guts (const char * prog_arg, const char *const *argv,
 | 
			
		|||
    {
 | 
			
		||||
      __seterrno ();
 | 
			
		||||
      syscall_printf ("CreateProcess failed, %E");
 | 
			
		||||
#if 0 // someday
 | 
			
		||||
      if (mode == _P_OVERLAY)
 | 
			
		||||
	myself->dwProcessId = GetCurrentProcessId ();
 | 
			
		||||
#endif
 | 
			
		||||
      if (subproc_ready)
 | 
			
		||||
	ForceCloseHandle (subproc_ready);
 | 
			
		||||
      cygheap_setup_for_child_cleanup (newheap, &ciresrv, 0);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -712,7 +712,7 @@ link (const char *a, const char *b)
 | 
			
		|||
	  goto docopy;
 | 
			
		||||
	}
 | 
			
		||||
      if (GetLastError () != ERROR_PROC_NOT_FOUND)
 | 
			
		||||
        {
 | 
			
		||||
	{
 | 
			
		||||
	  syscall_printf ("CreateHardLinkA failed");
 | 
			
		||||
	  __seterrno ();
 | 
			
		||||
	  goto done;
 | 
			
		||||
| 
						 | 
				
			
			@ -804,7 +804,7 @@ link (const char *a, const char *b)
 | 
			
		|||
      CloseHandle (hFileSource);
 | 
			
		||||
 | 
			
		||||
      if (!bSuccess)
 | 
			
		||||
        {
 | 
			
		||||
	{
 | 
			
		||||
	  /* Only copy file if FS doesn't support hard links */
 | 
			
		||||
	  if (write_err == ERROR_INVALID_FUNCTION)
 | 
			
		||||
	    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,13 +79,13 @@ uname (struct utsname *name)
 | 
			
		|||
	__small_sprintf (name->machine, "i%d86", ptype);
 | 
			
		||||
	break;
 | 
			
		||||
      case PROCESSOR_ARCHITECTURE_IA64:
 | 
			
		||||
        strcpy (name->machine, "ia64");
 | 
			
		||||
	strcpy (name->machine, "ia64");
 | 
			
		||||
	break;
 | 
			
		||||
      case PROCESSOR_ARCHITECTURE_AMD64:
 | 
			
		||||
        strcpy (name->machine, "amd64");
 | 
			
		||||
	strcpy (name->machine, "amd64");
 | 
			
		||||
	break;
 | 
			
		||||
      case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
 | 
			
		||||
      	strcpy (name->machine, "ia32-win64");
 | 
			
		||||
	strcpy (name->machine, "ia32-win64");
 | 
			
		||||
      case PROCESSOR_ARCHITECTURE_ALPHA:
 | 
			
		||||
	strcpy (name->machine, "alpha");
 | 
			
		||||
	break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue