/* pinfo.cc: process table support

This file is part of Cygwin.

This software is a copyrighted work licensed under the terms of the
Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
details. */

#include "winsup.h"
#include "miscfuncs.h"
#include <stdlib.h>
#include "cygerrno.h"
#include "security.h"
#include "path.h"
#include "fhandler.h"
#include "dtable.h"
#include "sigproc.h"
#include "pinfo.h"
#include "perprocess.h"
#include "environ.h"
#include "ntdll.h"
#include "shared_info.h"
#include "cygheap.h"
#include "cygmalloc.h"
#include "cygtls.h"
#include "tls_pbuf.h"
#include "child_info.h"

class pinfo_basic: public _pinfo
{
public:
  pinfo_basic();
};

pinfo_basic::pinfo_basic ()
{
  pid = dwProcessId = GetCurrentProcessId ();
  PWCHAR pend = wcpncpy (progname, global_progname,
			 sizeof (progname) / sizeof (WCHAR) - 1);
  *pend = L'\0';
  /* Default uid/gid are needed very early to initialize shared user info. */
  uid = ILLEGAL_UID;
  gid = ILLEGAL_GID;
}

pinfo_basic myself_initial NO_COPY;

pinfo NO_COPY myself (static_cast<_pinfo *> (&myself_initial));	// Avoid myself != NULL checks

/* Setup the pinfo structure for this process.  There may already be a
   _pinfo for this "pid" if h != NULL. */

void
pinfo::thisproc (HANDLE h)
{
  procinfo = NULL;

  DWORD flags = PID_IN_USE | PID_ACTIVE;
  if (!h)
    {
      h = INVALID_HANDLE_VALUE;
      cygheap->pid = cygwin_pid (myself_initial.pid);
      flags |= PID_NEW;
    }

  init (cygheap->pid, flags, h);
  procinfo->process_state |= PID_IN_USE;
  procinfo->dwProcessId = myself_initial.pid;
  procinfo->sendsig = myself_initial.sendsig;
  wcscpy (procinfo->progname, myself_initial.progname);
  debug_printf ("myself dwProcessId %u", procinfo->dwProcessId);
  if (h != INVALID_HANDLE_VALUE)
    {
      /* here if execed */
      static pinfo NO_COPY myself_identity;
      myself_identity.init (cygwin_pid (procinfo->dwProcessId), PID_EXECED, NULL);
      procinfo->exec_sendsig = NULL;
      procinfo->exec_dwProcessId = 0;
      myself_identity->ppid = procinfo->pid;
    }
}

/* Initialize the process table entry for the current task.
   This is not called for forked tasks, only execed ones.  */
void __stdcall
pinfo_init (char **envp, int envc)
{
  if (envp)
    {
      environ_init (envp, envc);
      /* spawn has already set up a pid structure for us so we'll use that */
      myself->process_state |= PID_CYGPARENT;
    }
  else
    {
      /* Invent our own pid.  */

      myself.thisproc (NULL);
      myself->pgid = myself->sid = myself->pid;
      myself->ctty = -1;
      myself->uid = ILLEGAL_UID;
      myself->gid = ILLEGAL_GID;
      environ_init (NULL, 0);	/* call after myself has been set up */
      myself->nice = winprio_to_nice (GetPriorityClass (GetCurrentProcess ()));
      myself->ppid = 1;		/* always set last */
      debug_printf ("Set nice to %d", myself->nice);
    }

  myself->process_state |= PID_ACTIVE;
  myself->process_state &= ~(PID_INITIALIZING | PID_EXITED | PID_REAPED);
  myself.preserve ();
  debug_printf ("pid %d, pgid %d, process_state %y", myself->pid, myself->pgid, myself->process_state);
}

DWORD
pinfo::status_exit (DWORD x)
{
  switch (x)
    {
    case STATUS_DLL_NOT_FOUND:
      {
	path_conv pc;
	if (!procinfo)
	   pc.check ("/dev/null", PC_NOWARN | PC_POSIX);
	else
	  {
	    UNICODE_STRING uc;
	    RtlInitUnicodeString(&uc, procinfo->progname);
	    pc.check (&uc, PC_NOWARN | PC_POSIX);
	  }
	small_printf ("%s: error while loading shared libraries: %s: cannot "
		      "open shared object file: No such file or directory\n",
		      pc.get_posix (), find_first_notloaded_dll (pc));
	x = 127 << 8;
      }
      break;
    case STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION: /* custom error value */
      /* We've already printed the error message in pseudo-reloc.c */
      x = 127 << 8;
      break;
    case STATUS_ACCESS_VIOLATION:
      x = SIGSEGV;
      break;
    case STATUS_ILLEGAL_INSTRUCTION:
      x = SIGILL;
      break;
    case STATUS_NO_MEMORY:
      /* If the PATH environment variable is longer than about 30K and the full
	 Windows environment is > 32K, startup of an exec'ed process fails with
	 STATUS_NO_MEMORY.  This happens with all Cygwin executables, as well
	 as, for instance, notepad, but it does not happen with CMD for some
	 reason (but note, the environment *in* CMD is broken and shortened).
	 This occurs at a point where there's no return to the exec'ing parent
	 process, so we have to find some way to inform the user what happened.
	 
	 FIXME: For now, just return with SIGBUS set.  Maybe it's better to add
	 a lengthy small_printf instead. */
      x = SIGBUS;
      break;
    default:
      debug_printf ("*** STATUS_%y\n", x);
      x = 127 << 8;
    }
  return EXITCODE_SET | x;
}

# define self (*this)
void
pinfo::set_exit_code (DWORD x)
{
  if (x >= 0xc0000000UL)
    self->exitcode = status_exit (x);
  else
    self->exitcode = EXITCODE_SET | (sigExeced ?: (x & 0xff) << 8);
}

void
pinfo::maybe_set_exit_code_from_windows ()
{
  DWORD x = 0xdeadbeef;
  DWORD oexitcode = self->exitcode;

  if (hProcess && !(self->exitcode & EXITCODE_SET))
    {
      WaitForSingleObject (hProcess, INFINITE);	/* just to be safe, in case
						   process hasn't quite exited
						   after closing pipe */
      GetExitCodeProcess (hProcess, &x);
      set_exit_code (x);
    }
  sigproc_printf ("pid %d, exit value - old %y, windows %y, cygwin %y",
		  self->pid, oexitcode, x, self->exitcode);
}

void
pinfo::exit (DWORD n)
{
  debug_only_printf ("winpid %d, exit %d", GetCurrentProcessId (), n);
  proc_terminate ();
  lock_process until_exit (true);
  cygthread::terminate ();

  if (n != EXITCODE_NOSET)
    self->exitcode = EXITCODE_SET | n;/* We're really exiting.  Record the UNIX exit code. */
  else
    maybe_set_exit_code_from_windows ();	/* may block */
  exit_state = ES_FINAL;

  if (myself->ctty > 0 && !iscons_dev (myself->ctty))
    {
      lock_ttys here;
      tty *t = cygwin_shared->tty[device::minor(myself->ctty)];
      if (!t->slave_alive ())
	t->setpgid (0);
    }

  /* FIXME:  There is a potential race between an execed process and its
     parent here.  I hated to add a mutex just for that, though.  */
  struct rusage r;
  fill_rusage (&r, GetCurrentProcess ());
  add_rusage (&self->rusage_self, &r);
  int exitcode = self->exitcode & 0xffff;
  if (!self->cygstarted)
    exitcode = ((exitcode & 0xff) << 8) | ((exitcode >> 8) & 0xff);
  sigproc_printf ("Calling ExitProcess n %y, exitcode %y", n, exitcode);
  if (!TerminateProcess (GetCurrentProcess (), exitcode))
    system_printf ("TerminateProcess failed, %E");
  ExitProcess (exitcode);
}
# undef self

inline void
pinfo::_pinfo_release ()
{
  if (procinfo)
    {
      void *unmap_procinfo = procinfo;
      procinfo = NULL;
      UnmapViewOfFile (unmap_procinfo);
    }
  HANDLE close_h;
  if (h)
    {
      close_h = h;
      h = NULL;
      ForceCloseHandle1 (close_h, pinfo_shared_handle);
    }
}

void
pinfo::init (pid_t n, DWORD flag, HANDLE h0)
{
  shared_locations shloc;
  h = NULL;
  if (myself && !(flag & PID_EXECED)
      && (n == myself->pid || (DWORD) n == myself->dwProcessId))
    {
      procinfo = myself;
      destroy = 0;
      return;
    }

  int createit = flag & (PID_IN_USE | PID_EXECED);
  DWORD access = FILE_MAP_READ
		 | (flag & (PID_IN_USE | PID_EXECED | PID_MAP_RW)
		    ? FILE_MAP_WRITE : 0);
  if (!h0 || myself.h)
    shloc = (flag & (PID_IN_USE | PID_EXECED)) ? SH_JUSTCREATE : SH_JUSTOPEN;
  else
    {
      shloc = SH_MYSELF;
      if (h0 == INVALID_HANDLE_VALUE)
	h0 = NULL;
    }

  procinfo = NULL;
  PSECURITY_ATTRIBUTES sa_buf = (PSECURITY_ATTRIBUTES) alloca (1024);
  PSECURITY_ATTRIBUTES sec_attribs = sec_user_nih (sa_buf, cygheap->user.sid(),
						   well_known_world_sid,
						   FILE_MAP_READ);

  for (int i = 0; i < 20; i++)
    {
      DWORD mapsize;
      if (flag & PID_EXECED)
	mapsize = PINFO_REDIR_SIZE;
      else
	mapsize = sizeof (_pinfo);

      procinfo = (_pinfo *) open_shared (L"cygpid", n, h0, mapsize, &shloc,
					 sec_attribs, access);
      if (!h0)
	{
	  if (createit)
	    __seterrno ();
	  return;
	}

      if (!procinfo)
	{
	  if (exit_state)
	    return;

	  if (GetLastError () == ERROR_INVALID_HANDLE)
	    api_fatal ("MapViewOfFileEx h0 %p, i %d failed, %E", h0, i);

	  debug_printf ("MapViewOfFileEx h0 %p, i %d failed, %E", h0, i);
	  yield ();
	  continue;
	}

      bool created = shloc != SH_JUSTOPEN;

      /* Detect situation where a transitional memory block is being retrieved.
	 If the block has been allocated with PINFO_REDIR_SIZE but not yet
	 updated with a PID_EXECED state then we'll retry.  */
      if (!created && !(flag & PID_NEW) && !procinfo->ppid)
	{
	  /* Fetching process info for /proc or ps?  just ignore this one. */
	  if (flag & PID_NOREDIR)
	    break;
	  /* FIXME: Do we ever hit this case?  And if so, in what situation? */
	  system_printf ("This shouldn't happen:\n"
			 "    me: (%d, %d, %d, %W)\n"
			 "    pid %d\n"
			 "    process_state %y\n"
			 "    cygstarted %d\n"
			 "    dwProcessId %d\n"
			 "    name %W",
			 myself->pid, myself->dwProcessId, myself->cygstarted,
			 myself->progname,
			 procinfo->pid, procinfo->process_state,
			 procinfo->cygstarted, procinfo->dwProcessId,
			 procinfo->progname);
	  /* If not populated, wait 2 seconds for procinfo to become populated.
	     Would like to wait with finer granularity but that is not easily
	     doable.  */
	  for (int i = 0; i < 200 && !procinfo->ppid; i++)
	    Sleep (10);
	}

      if (!created && createit && (procinfo->process_state & PID_REAPED))
	{
	  memset (procinfo, 0, sizeof (*procinfo));
	  created = true;	/* Lie that we created this - just reuse old
				   shared memory */
	}

      if ((procinfo->process_state & PID_REAPED)
	  || ((procinfo->process_state & PID_INITIALIZING) && (flag & PID_NOREDIR)
	      && cygwin_pid (procinfo->dwProcessId) != procinfo->pid))
	{
	  set_errno (ESRCH);
	  break;
	}

      if (procinfo->process_state & PID_EXECED)
	{
	  pid_t realpid = procinfo->pid;
	  debug_printf ("execed process windows pid %u, cygwin pid %d", n, realpid);
	  if (realpid == n)
	    api_fatal ("retrieval of execed process info for pid %d failed due to recursion.", n);

	  n = realpid;
	  CloseHandle (h0);
	  h0 = NULL;
	  goto loop;
	}

      /* In certain pathological cases, it is possible for the shared memory
	 region to exist for a while after a process has exited.  This should
	 only be a brief occurrence, so rather than introduce some kind of
	 locking mechanism, just loop.  */
      if (!created && createit && (procinfo->process_state & (PID_EXITED | PID_REAPED)))
	{
	  debug_printf ("looping because pid %d, procinfo->pid %d, "
			"procinfo->dwProcessid %u has PID_EXITED|PID_REAPED set",
			n, procinfo->pid, procinfo->dwProcessId);
	  goto loop;
	}

      if (flag & PID_NEW)
	procinfo->start_time = time (NULL);
      if (!created)
	/* nothing */;
      else if (!(flag & PID_EXECED))
	procinfo->pid = n;
      else
	{
	  procinfo->process_state |= PID_IN_USE | PID_EXECED;
	  procinfo->pid = myself->pid;
	}

      h = h0;	/* Success! */
      break;

    loop:
      _pinfo_release ();
      if (h0)
	yield ();
    }

  if (h)
    {
      destroy = 1;
      ProtectHandle1 (h, pinfo_shared_handle);
    }
  else
    {
      h = h0;
      _pinfo_release ();
    }
}

void
pinfo::set_acl()
{
  PACL acl_buf = (PACL) alloca (1024);
  SECURITY_DESCRIPTOR sd;
  NTSTATUS status;

  sec_acl (acl_buf, true, true, cygheap->user.sid (),
	   well_known_world_sid, FILE_MAP_READ);
  RtlCreateSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);
  status = RtlSetDaclSecurityDescriptor (&sd, TRUE, acl_buf, FALSE);
  if (!NT_SUCCESS (status))
    debug_printf ("RtlSetDaclSecurityDescriptor %y", status);
  else if ((status = NtSetSecurityObject (h, DACL_SECURITY_INFORMATION, &sd)))
    debug_printf ("NtSetSecurityObject %y", status);
}

pinfo::pinfo (HANDLE parent, pinfo_minimal& from, pid_t pid):
  pinfo_minimal (), destroy (false), procinfo (NULL), waiter_ready (false),
  wait_thread (NULL)
{
  HANDLE herr;
  const char *duperr = NULL;
  if (!DuplicateHandle (parent, herr = from.rd_proc_pipe, GetCurrentProcess (),
			&rd_proc_pipe, 0, false, DUPLICATE_SAME_ACCESS))
    duperr = "couldn't duplicate parent rd_proc_pipe handle %p for forked child %d after exec, %E";
  else if (!DuplicateHandle (parent, herr = from.hProcess, GetCurrentProcess (),
			     &hProcess, 0, false, DUPLICATE_SAME_ACCESS))
    duperr = "couldn't duplicate parent process handle %p for forked child %d after exec, %E";
  else
    {
      h = NULL;
      DuplicateHandle (parent, from.h, GetCurrentProcess (), &h, 0, false,
		       DUPLICATE_SAME_ACCESS);
      init (pid, PID_MAP_RW, h);
      if (*this)
	return;
    }

  if (duperr)
    debug_printf (duperr, herr, pid);

  /* Returning with procinfo == NULL.  Any open handles will be closed by the
     destructor. */
}

const char *
_pinfo::_ctty (char *buf)
{
  if (ctty <= 0)
    strcpy (buf, "no ctty");
  else
    {
      device d;
      d.parse (ctty);
      __small_sprintf (buf, "ctty %s", d.name ());
    }
  return buf;
}

bool
_pinfo::set_ctty (fhandler_termios *fh, int flags)
{
  tty_min& tc = *fh->tc ();
  debug_printf ("old %s, ctty device number %y, tc.ntty device number %y flags & O_NOCTTY %y", __ctty (), ctty, tc.ntty, flags & O_NOCTTY);
  if (fh && (ctty <= 0 || ctty == tc.ntty) && !(flags & O_NOCTTY))
    {
      ctty = tc.ntty;
      if (cygheap->ctty != fh->archetype)
	{
	  debug_printf ("cygheap->ctty %p, archetype %p", cygheap->ctty, fh->archetype);
	  if (!cygheap->ctty)
	    syscall_printf ("ctty was NULL");
	  else
	    {
	      syscall_printf ("ctty %p, usecount %d", cygheap->ctty,
			      cygheap->ctty->archetype_usecount (0));
	      cygheap->ctty->close ();
	    }
	  cygheap->ctty = (fhandler_termios *) fh->archetype;
	  if (cygheap->ctty)
	    {
	      fh->archetype_usecount (1);
	      /* guard ctty fh */
	      report_tty_counts (cygheap->ctty, "ctty", "");
	    }
	}

      lock_ttys here;
      syscall_printf ("attaching %s sid %d, pid %d, pgid %d, tty->pgid %d, tty->sid %d",
		      __ctty (), sid, pid, pgid, tc.getpgid (), tc.getsid ());
      if (!cygwin_finished_initializing && !myself->cygstarted
	  && pgid == pid && tc.getpgid () && tc.getsid ())
	pgid = tc.getpgid ();

      /* May actually need to do this:

	 if (sid == pid && !tc.getsid () || !procinfo (tc.getsid ())->exists)

	 but testing for process existence is expensive so we avoid it until
	 an obvious bug surfaces. */
      if (sid == pid && !tc.getsid ())
	tc.setsid (sid);
      sid = tc.getsid ();
      /* See above */
      if (!tc.getpgid () && pgid == pid)
	tc.setpgid (pgid);
    }
  debug_printf ("cygheap->ctty now %p, archetype %p", cygheap->ctty, fh ? fh->archetype : NULL);
  return ctty > 0;
}

/* Test to determine if a process really exists and is processing signals.
 */
bool __reg1
_pinfo::exists ()
{
  return process_state && !(process_state & (PID_EXITED | PID_REAPED | PID_EXECED));
}

bool
_pinfo::alive ()
{
  HANDLE h = OpenProcess (PROCESS_QUERY_LIMITED_INFORMATION, false,
			  dwProcessId);
  if (h)
    CloseHandle (h);
  return !!h;
}

DWORD WINAPI
commune_process (void *arg)
{
  siginfo_t& si = *((siginfo_t *) arg);
  tmp_pathbuf tp;
  char *path = tp.c_get ();
  DWORD nr;
  HANDLE& tothem = si._si_commune._si_write_handle;
  HANDLE process_sync =
    OpenSemaphore (SYNCHRONIZE, false, shared_name (path, "commune", si.si_pid));
  if (process_sync)		// FIXME: this test shouldn't be necessary
    ProtectHandle (process_sync);

  lock_process now;
  if (si._si_commune._si_code & PICOM_EXTRASTR)
    si._si_commune._si_str = (char *) (&si + 1);

  switch (si._si_commune._si_code)
    {
    case PICOM_CMDLINE:
      {
	sigproc_printf ("processing PICOM_CMDLINE");
	unsigned n = 0;
	const char *argv[__argc_safe + 1];

	for (int i = 0; i < __argc_safe; i++)
	  {
	    if (IsBadStringPtr (__argv[i], INT32_MAX))
	      argv[i] = "";
	    else
	      argv[i] = __argv[i];
	    n += strlen (argv[i]) + 1;
	  }
	argv[__argc_safe] = NULL;
	if (!WritePipeOverlapped (tothem, &n, sizeof n, &nr, 1000L))
	  {
	    /*__seterrno ();*/	// this is run from the signal thread, so don't set errno
	    sigproc_printf ("WritePipeOverlapped sizeof argv failed, %E");
	  }
	else
	  for (const char **a = argv; *a; a++)
	    if (!WritePipeOverlapped (tothem, *a, strlen (*a) + 1, &nr, 1000L))
	      {
		sigproc_printf ("WritePipeOverlapped arg %d failed, %E",
				a - argv);
		break;
	      }
	break;
      }
    case PICOM_CWD:
      {
	sigproc_printf ("processing PICOM_CWD");
	unsigned int n = strlen (cygheap->cwd.get (path, 1, 1, NT_MAX_PATH)) + 1;
	if (!WritePipeOverlapped (tothem, &n, sizeof n, &nr, 1000L))
	  sigproc_printf ("WritePipeOverlapped sizeof cwd failed, %E");
	else if (!WritePipeOverlapped (tothem, path, n, &nr, 1000L))
	  sigproc_printf ("WritePipeOverlapped cwd failed, %E");
	break;
      }
    case PICOM_ROOT:
      {
	sigproc_printf ("processing PICOM_ROOT");
	unsigned n;
	if (cygheap->root.exists ())
	  n = strlen (strcpy (path, cygheap->root.posix_path ())) + 1;
	else
	  n = strlen (strcpy (path, "/")) + 1;
	if (!WritePipeOverlapped (tothem, &n, sizeof n, &nr, 1000L))
	  sigproc_printf ("WritePipeOverlapped sizeof root failed, %E");
	else if (!WritePipeOverlapped (tothem, path, n, &nr, 1000L))
	  sigproc_printf ("WritePipeOverlapped root failed, %E");
	break;
      }
    case PICOM_FDS:
      {
	sigproc_printf ("processing PICOM_FDS");
	unsigned int n = 0;
	int fd;
	cygheap_fdenum cfd;
	while ((fd = cfd.next ()) >= 0)
	  n += sizeof (int);
	cfd.rewind ();
	if (!WritePipeOverlapped (tothem, &n, sizeof n, &nr, 1000L))
	  sigproc_printf ("WritePipeOverlapped sizeof fds failed, %E");
	else
	  while ((fd = cfd.next ()) >= 0)
	    if (!WritePipeOverlapped (tothem, &fd, sizeof fd, &nr, 1000L))
	      {
		sigproc_printf ("WritePipeOverlapped fd %d failed, %E", fd);
		break;
	      }
	break;
      }
    case PICOM_PIPE_FHANDLER:
      {
	sigproc_printf ("processing PICOM_FDS");
	int64_t unique_id = si._si_commune._si_pipe_unique_id;
	unsigned int n = 0;
	cygheap_fdenum cfd;
	while (cfd.next () >= 0)
	  if (cfd->get_unique_id () == unique_id)
	    {
	      fhandler_pipe *fh = cfd;
	      n = sizeof *fh;
	      if (!WritePipeOverlapped (tothem, &n, sizeof n, &nr, 1000L))
		sigproc_printf ("WritePipeOverlapped sizeof hdl failed, %E");
	      else if (!WritePipeOverlapped (tothem, fh, n, &nr, 1000L))
		sigproc_printf ("WritePipeOverlapped hdl failed, %E");
	      break;
	    }
	if (!n && !WritePipeOverlapped (tothem, &n, sizeof n, &nr, 1000L))
	  sigproc_printf ("WritePipeOverlapped sizeof hdl failed, %E");
	break;
      }
    case PICOM_FD:
      {
	sigproc_printf ("processing PICOM_FD");
	int fd = si._si_commune._si_fd;
	unsigned int n = 0;
	cygheap_fdget cfd (fd);
	if (cfd < 0)
	  n = strlen (strcpy (path, "")) + 1;
	else
	  n = strlen (cfd->get_proc_fd_name (path)) + 1;
	if (!WritePipeOverlapped (tothem, &n, sizeof n, &nr, 1000L))
	  sigproc_printf ("WritePipeOverlapped sizeof fd failed, %E");
	else if (!WritePipeOverlapped (tothem, path, n, &nr, 1000L))
	  sigproc_printf ("WritePipeOverlapped fd failed, %E");
	break;
      }
    case PICOM_ENVIRON:
      {
	sigproc_printf ("processing PICOM_ENVIRON");
	unsigned n = 0;
	char **env = cur_environ ();
	for (char **e = env; *e; e++)
	  n += strlen (*e) + 1;
	if (!WritePipeOverlapped (tothem, &n, sizeof n, &nr, 1000L))
	  sigproc_printf ("WritePipeOverlapped sizeof argv failed, %E");
	else
	  for (char **e = env; *e; e++)
	    if (!WritePipeOverlapped (tothem, *e, strlen (*e) + 1, &nr, 1000L))
	      {
	        sigproc_printf ("WritePipeOverlapped arg %d failed, %E",
				e - env);
	        break;
	      }
	break;
      }
    }
  if (process_sync)
    {
      DWORD res = WaitForSingleObject (process_sync, 5000);
      if (res != WAIT_OBJECT_0)
	sigproc_printf ("WFSO failed - %u, %E", res);
      else
	sigproc_printf ("synchronized with pid %d", si.si_pid);
      ForceCloseHandle (process_sync);
    }
  CloseHandle (tothem);
  _my_tls._ctinfo->auto_release ();
  return 0;
}

commune_result
_pinfo::commune_request (__uint32_t code, ...)
{
  DWORD nr;
  commune_result res;
  va_list args;
  siginfo_t si = {0};
  HANDLE& hp = si._si_commune._si_process_handle;
  HANDLE& fromthem = si._si_commune._si_read_handle;
  HANDLE request_sync = NULL;

  res.s = NULL;
  res.n = 0;

  if (!pid)
    {
      set_errno (ESRCH);
      goto err;
    }
  if (ISSTATE (this, PID_NOTCYGWIN))
    {
      set_errno (ENOTSUP);
      goto err;
    }

  va_start (args, code);
  si._si_commune._si_code = code;
  switch (code)
    {
    case PICOM_PIPE_FHANDLER:
      si._si_commune._si_pipe_unique_id = va_arg (args, int64_t);
      break;

    case PICOM_FD:
      si._si_commune._si_fd = va_arg (args, int);
      break;

    break;
    }
  va_end (args);

  char name_buf[MAX_PATH];
  request_sync = CreateSemaphore (&sec_none_nih, 0, INT32_MAX,
				  shared_name (name_buf, "commune", myself->pid));
  if (!request_sync)
    goto err;
  ProtectHandle (request_sync);

  si.si_signo = __SIGCOMMUNE;
  if (sig_send (this, si))
    {
      ForceCloseHandle (request_sync);	/* don't signal semaphore since there was apparently no receiving process */
      request_sync = NULL;
      goto err;
    }

  DWORD n;
  switch (code)
    {
    case PICOM_CMDLINE:
    case PICOM_CWD:
    case PICOM_ENVIRON:
    case PICOM_ROOT:
    case PICOM_FDS:
    case PICOM_FD:
    case PICOM_PIPE_FHANDLER:
      if (!ReadPipeOverlapped (fromthem, &n, sizeof n, &nr, 1000L)
	  || nr != sizeof n)
	{
	  __seterrno ();
	  goto err;
	}
      if (!n)
	res.s = NULL;
      else
	{
	  res.s = (char *) cmalloc_abort (HEAP_COMMUNE, n);
	  char *p;
	  for (p = res.s;
	       n && ReadPipeOverlapped (fromthem, p, n, &nr, 1000L);
	       p += nr, n -= nr)
	    continue;
	  if (n)
	    {
	      __seterrno ();
	      goto err;
	    }
	  res.n = p - res.s;
	}
      break;
    }
  goto out;

err:
  memset (&res, 0, sizeof (res));

out:
  if (request_sync)
    {
      LONG res;
      ReleaseSemaphore (request_sync, 1, &res);
      ForceCloseHandle (request_sync);
    }
  if (hp)
    CloseHandle (hp);
  if (fromthem)
    CloseHandle (fromthem);
  return res;
}

fhandler_pipe *
_pinfo::pipe_fhandler (int64_t unique_id, size_t &n)
{
  if (!pid)
    return NULL;
  if (pid == myself->pid)
    return NULL;
  commune_result cr = commune_request (PICOM_PIPE_FHANDLER, unique_id);
  n = cr.n;
  return (fhandler_pipe *) cr.s;
}

char *
_pinfo::fd (int fd, size_t &n)
{
  char *s;
  if (!pid)
    return NULL;
  if (pid != myself->pid)
    {
      commune_result cr = commune_request (PICOM_FD, fd);
      s = cr.s;
      n = cr.n;
    }
  else
    {
      cygheap_fdget cfd (fd);
      if (cfd < 0)
	s = cstrdup ("");
      else
	s = cfd->get_proc_fd_name ((char *) cmalloc_abort (HEAP_COMMUNE, NT_MAX_PATH));
      n = strlen (s) + 1;
    }
  return s;
}

char *
_pinfo::fds (size_t &n)
{
  char *s;
  if (!pid)
    return NULL;
  if (pid != myself->pid)
    {
      commune_result cr = commune_request (PICOM_FDS);
      s = cr.s;
      n = cr.n;
    }
  else
    {
      n = 0;
      int fd;
      cygheap_fdenum cfd (true);
      while ((fd = cfd.next ()) >= 0)
	n += sizeof (int);
      cfd.rewind ();
      s = (char *) cmalloc_abort (HEAP_COMMUNE, n);
      int *p = (int *) s;
      while ((fd = cfd.next ()) >= 0 && (char *) p - s < (int) n)
	*p++ = fd;
    }
  return s;
}

char *
_pinfo::root (size_t& n)
{
  char *s;
  if (!pid)
    return NULL;
  if (pid != myself->pid && !ISSTATE (this, PID_NOTCYGWIN))
    {
      commune_result cr = commune_request (PICOM_ROOT);
      s = cr.s;
      n = cr.n;
    }
  else
    {
      if (cygheap->root.exists ())
	s = cstrdup (cygheap->root.posix_path ());
      else
	s = cstrdup ("/");
      n = strlen (s) + 1;
    }
  return s;
}

static HANDLE
open_commune_proc_parms (DWORD pid, PRTL_USER_PROCESS_PARAMETERS prupp)
{
  HANDLE proc;
  NTSTATUS status;
  PROCESS_BASIC_INFORMATION pbi;
  PEB lpeb;

  proc = OpenProcess (PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ,
		      FALSE, pid);
  if (!proc)
    return NULL;
  status = NtQueryInformationProcess (proc, ProcessBasicInformation,
				      &pbi, sizeof pbi, NULL);
  if (NT_SUCCESS (status)
      && ReadProcessMemory (proc, pbi.PebBaseAddress, &lpeb, sizeof lpeb, NULL)
      && ReadProcessMemory (proc, lpeb.ProcessParameters, prupp, sizeof *prupp,
			    NULL))
	return proc;
  NtClose (proc);
  return NULL;
}

char *
_pinfo::cwd (size_t& n)
{
  char *s = NULL;
  if (!pid)
    return NULL;
  if (ISSTATE (this, PID_NOTCYGWIN))
    {
      RTL_USER_PROCESS_PARAMETERS rupp;
      HANDLE proc = open_commune_proc_parms (dwProcessId, &rupp);

      n = 0;
      if (!proc)
	return NULL;

      tmp_pathbuf tp;
      PWCHAR cwd = tp.w_get ();

      if (ReadProcessMemory (proc, rupp.CurrentDirectoryName.Buffer,
			     cwd, rupp.CurrentDirectoryName.Length,
			     NULL))
	{
	  /* Drop trailing backslash, add trailing \0 in passing. */
	  cwd[rupp.CurrentDirectoryName.Length / sizeof (WCHAR) - 1]
	  = L'\0';
	  s = (char *) cmalloc_abort (HEAP_COMMUNE, NT_MAX_PATH);
	  mount_table->conv_to_posix_path (cwd, s, 0);
	  n = strlen (s) + 1;
	}
      NtClose (proc);
    }
  else if (pid != myself->pid)
    {
      commune_result cr = commune_request (PICOM_CWD);
      s = cr.s;
      n = cr.n;
    }
  else
    {
      s = (char *) cmalloc_abort (HEAP_COMMUNE, NT_MAX_PATH);
      cygheap->cwd.get (s, 1, 1, NT_MAX_PATH);
      n = strlen (s) + 1;
    }
  return s;
}

char *
_pinfo::cmdline (size_t& n)
{
  char *s = NULL;
  if (!pid)
    return NULL;
  if (ISSTATE (this, PID_NOTCYGWIN))
    {
      RTL_USER_PROCESS_PARAMETERS rupp;
      HANDLE proc = open_commune_proc_parms (dwProcessId, &rupp);

      n = 0;
      if (!proc)
	return NULL;

      tmp_pathbuf tp;
      PWCHAR cmdline = tp.w_get ();

      if (ReadProcessMemory (proc, rupp.CommandLine.Buffer, cmdline,
			     rupp.CommandLine.Length, NULL))
	{
	  /* Add trailing \0. */
	  cmdline[rupp.CommandLine.Length / sizeof (WCHAR)]
	  = L'\0';
	  n = sys_wcstombs_alloc (&s, HEAP_COMMUNE, cmdline,
				  rupp.CommandLine.Length
				  / sizeof (WCHAR));
	  /* Quotes & Spaces post-processing. */
	  bool in_quote = false;
	  for (char *c = s; *c; ++c)
	    if (*c == '"')
	      in_quote = !in_quote;
	    else if (*c == ' ' && !in_quote)
	     *c = '\0';
	}
      NtClose (proc);
    }
  else if (pid != myself->pid)
    {
      commune_result cr = commune_request (PICOM_CMDLINE);
      s = cr.s;
      n = cr.n;
    }
  else
    {
      n = 0;
      for (char **a = __argv; *a; a++)
	n += strlen (*a) + 1;
      char *p;
      p = s = (char *) cmalloc_abort (HEAP_COMMUNE, n);
      for (char **a = __argv; *a; a++)
	{
	  strcpy (p, *a);
	  p = strchr (p, '\0') + 1;
	}
    }
  return s;
}


char *
_pinfo::environ (size_t& n)
{
  char **env = NULL;
  if (!pid)
    return NULL;
  if (ISSTATE (this, PID_NOTCYGWIN))
    {
      RTL_USER_PROCESS_PARAMETERS rupp;
      HANDLE proc = open_commune_proc_parms (dwProcessId, &rupp);

      if (!proc)
        return NULL;

      MEMORY_BASIC_INFORMATION mbi;
      SIZE_T envsize;
      PWCHAR envblock;
      if (!VirtualQueryEx (proc, rupp.Environment, &mbi, sizeof(mbi)))
        {
          NtClose (proc);
          return NULL;
        }

      SIZE_T read;
      envsize = (ptrdiff_t) mbi.RegionSize
                - ((ptrdiff_t) rupp.Environment - (ptrdiff_t) mbi.BaseAddress);
      envblock = (PWCHAR) cmalloc_abort (HEAP_COMMUNE, envsize);

      if (ReadProcessMemory (proc, rupp.Environment, envblock, envsize, &read))
        env = win32env_to_cygenv (envblock, false);

      NtClose (proc);
    }
  else if (pid != myself->pid)
    {
      commune_result cr = commune_request (PICOM_ENVIRON);
      n = cr.n;
      return cr.s;
    }
  else
    env = cur_environ ();

  if (env == NULL)
    return NULL;

  n = 0;
  for (char **e = env; *e; e++)
    n += strlen (*e) + 1;

  char *p, *s;
  p = s = (char *) cmalloc_abort (HEAP_COMMUNE, n);
  for (char **e = env; *e; e++)
    {
      strcpy (p, *e);
      p = strchr (p, '\0') + 1;
    }
  return s;
}

/* This is the workhorse which waits for the write end of the pipe
   created during new process creation.  If the pipe is closed or a zero
   is received on the pipe, it is assumed that the cygwin pid has exited.
   Otherwise, various "signals" can be sent to the parent to inform the
   parent to perform a certain action. */
static DWORD WINAPI
proc_waiter (void *arg)
{
  pinfo vchild = *(pinfo *) arg;
  ((pinfo *) arg)->waiter_ready = true;

  siginfo_t si = {0};
  si.si_signo = SIGCHLD;
  si.si_code = CLD_EXITED;
  si.si_pid = vchild->pid;
#if 0	// FIXME: This is tricky to get right
  si.si_utime = pchildren[rc]->rusage_self.ru_utime;
  si.si_stime = pchildren[rc].rusage_self.ru_stime;
#endif
  pid_t pid = vchild->pid;
  bool its_me = vchild == myself;

  for (;;)
    {
      DWORD nb;
      char buf = '\0';

      if (!ReadFile (vchild.rd_proc_pipe, &buf, 1, &nb, NULL)
	  && GetLastError () != ERROR_BROKEN_PIPE)
	{
	  system_printf ("error on read of child wait pipe %p, %E", vchild.rd_proc_pipe);
	  break;
	}

      if (!its_me && have_execed_cygwin)
	break;

      si.si_uid = vchild->uid;

      switch (buf)
	{
	case __ALERT_ALIVE:
	  continue;
	case 0:
	  /* Child exited.  Do some cleanup and signal myself.  */
	  vchild.maybe_set_exit_code_from_windows ();
	  if (WIFEXITED (vchild->exitcode))
	    si.si_code = CLD_EXITED;
	  else if (WCOREDUMP (vchild->exitcode))
	    si.si_code = CLD_DUMPED;
	  else
	    si.si_code = CLD_KILLED;
	  si.si_status = vchild->exitcode;
	  vchild->process_state = PID_EXITED;
	  /* This should always be last.  Do not use vchild-> beyond this point */
	  break;
	case SIGTTIN:
	case SIGTTOU:
	case SIGTSTP:
	case SIGSTOP:
	  if (ISSTATE (myself, PID_NOCLDSTOP))	// FIXME: No need for this flag to be in _pinfo any longer
	    continue;
	  /* Child stopped.  Signal myself.  */
	  si.si_code = CLD_STOPPED;
	  break;
	case SIGCONT:
	  continue;
	default:
	  system_printf ("unknown value %d on proc pipe", buf);
	  continue;
	}

      if (its_me && ch_spawn.signal_myself_exited ())
	break;

      /* Send a SIGCHLD to myself.   We do this here, rather than in proc_subproc
	 to avoid the proc_subproc lock since the signal thread will eventually
	 be calling proc_subproc and could unnecessarily block. */
      sig_send (myself_nowait, si);

      /* If we're just stopped or got a continue signal, keep looping.
	 Otherwise, return this thread to the pool. */
      if (buf != '\0')
	sigproc_printf ("looping");
      else
	break;
    }

  sigproc_printf ("exiting wait thread for pid %d", pid);
  vchild.wait_thread = NULL;
  _my_tls._ctinfo->auto_release ();	/* automatically return the cygthread to the cygthread pool */
  return 0;
}

/* function to set up the process pipe and kick off proc_waiter */
bool
pinfo::wait ()
{
  preserve ();		/* Preserve the shared memory associated with the pinfo */

  waiter_ready = false;
  /* Fire up a new thread to track the subprocess */
  cygthread *h = new cygthread (proc_waiter, this, "waitproc");
  if (!h)
    sigproc_printf ("tracking thread creation failed for pid %d", (*this)->pid);
  else
    {
      wait_thread = h;
      sigproc_printf ("created tracking thread for pid %d, winpid %y, rd_proc_pipe %p",
		      (*this)->pid, (*this)->dwProcessId, rd_proc_pipe);
    }

  return true;
}

/* function to send a "signal" to the parent when something interesting happens
   in the child. */
bool
_pinfo::alert_parent (char sig)
{
  DWORD nb = 0;

  /* Send something to our parent.  If the parent has gone away, close the pipe.
     Don't send if this is an exec stub.

     FIXME: Is there a race here if we run this while another thread is attempting
     to exec()? */
  if (my_wr_proc_pipe)
    {
      if (WriteFile (my_wr_proc_pipe, &sig, 1, &nb, NULL))
	/* all is well */;
      else if (GetLastError () != ERROR_BROKEN_PIPE)
	debug_printf ("sending %d notification to parent failed, %E", sig);
      else
	{
	  ppid = 1;
	  HANDLE closeit = my_wr_proc_pipe;
	  my_wr_proc_pipe = NULL;
	  ForceCloseHandle1 (closeit, wr_proc_pipe);
	}
    }
  return (bool) nb;
}

void
pinfo::release ()
{
  _pinfo_release ();
  HANDLE close_h;
  if (rd_proc_pipe)
    {
      close_h = rd_proc_pipe;
      rd_proc_pipe = NULL;
      ForceCloseHandle1 (close_h, rd_proc_pipe);
    }
  if (hProcess)
    {
      close_h = hProcess;
      hProcess = NULL;
      ForceCloseHandle1 (close_h, childhProc);
    }
}

/* DOCTOOL-START

<sect1 id="func-cygwin-winpid-to-pid">
  <title>cygwin_winpid_to_pid</title>

  <funcsynopsis><funcprototype>
    <funcdef>extern "C" pid_t
      <function>cygwin_winpid_to_pid</function>
      </funcdef>
      <paramdef>int <parameter>winpid</parameter></paramdef>
  </funcprototype></funcsynopsis>

  <para>Given a windows pid, converts to the corresponding Cygwin
pid, if any.  Returns -1 if windows pid does not correspond to
a cygwin pid.</para>
  <example>
    <title>Example use of cygwin_winpid_to_pid</title>
    <programlisting>
      extern "C" cygwin_winpid_to_pid (int winpid);
      pid_t mypid;
      mypid = cygwin_winpid_to_pid (windows_pid);
    </programlisting>
  </example>
</sect1>

   DOCTOOL-END */

extern "C" pid_t
cygwin_winpid_to_pid (int winpid)
{
  pinfo p (cygwin_pid (winpid));
  if (p)
    return p->pid;

  set_errno (ESRCH);
  return (pid_t) -1;
}


#define slop_pidlist 200
#define size_pidlist(i) (sizeof (pidlist[0]) * ((i) + 1))
#define size_pinfolist(i) (sizeof (pinfolist[0]) * ((i) + 1))
class _onreturn
{
  HANDLE h;
public:
  ~_onreturn ()
  {
    if (h)
      {
	CloseHandle (h);
      }
  }
  void no_close_handle (pinfo& p)
  {
    p.hProcess = h;
    h = NULL;
  }
  _onreturn (): h (NULL) {}
  void operator = (HANDLE h0) {h = h0;}
  operator HANDLE () const {return h;}
};

inline void
winpids::add (DWORD& nelem, bool winpid, DWORD pid)
{
  pid_t cygpid = cygwin_pid (pid);

  if (nelem >= npidlist)
    {
      npidlist += slop_pidlist;
      pidlist = (DWORD *) realloc (pidlist, size_pidlist (npidlist + 1));
      pinfolist = (pinfo *) realloc (pinfolist, size_pinfolist (npidlist + 1));
    }

  _onreturn onreturn;
  pinfo& p = pinfolist[nelem];
  memset (&p, 0, sizeof (p));

  bool perform_copy;
  if (cygpid == myself->pid)
    {
      p = myself;
      perform_copy = false;
    }
  else
    {
      /* Open a process to prevent a subsequent exit from invalidating the
	 shared memory region. */
      onreturn = OpenProcess (PROCESS_QUERY_LIMITED_INFORMATION, false, pid);

      /* If we couldn't open the process then we don't have rights to it and should
	 make a copy of the shared memory area when it exists (it may not).  */
      perform_copy = onreturn ? make_copy : true;

      p.init (cygpid, PID_NOREDIR | pinfo_access, NULL);
    }

  /* If we're just looking for winpids then don't do any special cygwin "stuff* */
  if (winpid)
    {
      perform_copy = true;
      goto out;
    }

  /* !p means that we couldn't find shared memory for this pid.  Probably means
     that it isn't a cygwin process. */
  if (!p)
    {
      if (!pinfo_access)
	return;
      p.init (cygpid, PID_NOREDIR, NULL);
      if (!p)
	return;
    }

  /* Scan list of previously recorded pids to make sure that this pid hasn't
     shown up before.  This can happen when a process execs. */
  for (unsigned i = 0; i < nelem; i++)
    if (pinfolist[i]->pid == p->pid)
      {
	if ((_pinfo *) p != (_pinfo *) myself)
	  p.release ();
	return;
      }

out:
  /* Exit here.

     If p is "false" then, eventually any opened process handle will be closed and
     the function will exit without adding anything to the pid list.

     If p is "true" then we've discovered a cygwin process.

     Handle "myself" differently.  Don't copy it and close/zero the handle we
     just opened to it.
     If not performing a copy, then keep the process handle open for the duration
     of the life of the procinfo region to potential races when a new process uses
     this pid.
     Otherwise, malloc some memory for a copy of the shared memory.

     If the malloc failed, then "oh well".  Just keep the shared memory around
     and eventually close the handle when the winpids goes out of scope.

     If malloc succeeds, copy the procinfo we just grabbed into the new region,
     release the shared memory and allow the handle to be closed when this
     function returns.

     Oh, and add the pid to the list and bump the number of elements.  */

  if (p)
    {
      if (p == (_pinfo *) myself)
	/* handle specially.  Close the handle but (eventually) don't
	   deallocate procinfo in release call */;
      else if (!perform_copy)
	onreturn.no_close_handle (p);	/* Don't close the handle until release */
      else
	{
	  _pinfo *pnew = (_pinfo *) malloc (sizeof (*p.procinfo));
	  if (!pnew)
	    onreturn.no_close_handle (p);
	  else
	    {
	      *pnew = *p.procinfo;
	      p.release ();
	      p.procinfo = pnew;
	      p.destroy = false;
	      if (winpid)
		p->dwProcessId = pid;
	    }
	}
    }
  if (p || winpid)
    pidlist[nelem++] = !p ? pid : p->dwProcessId;
}

DWORD
winpids::enum_processes (bool winpid)
{
  DWORD nelem = 0;

  if (!winpid)
    {
      HANDLE dir = get_shared_parent_dir ();
      BOOLEAN restart = TRUE;
      ULONG context;
      struct fdbi
	{
	  DIRECTORY_BASIC_INFORMATION dbi;
	  WCHAR buf[2][NAME_MAX + 1];
	} f;
      while (NT_SUCCESS (NtQueryDirectoryObject (dir, &f, sizeof f, TRUE,
						 restart, &context, NULL)))
	{
	  restart = FALSE;
	  f.dbi.ObjectName.Buffer[f.dbi.ObjectName.Length / sizeof (WCHAR)] = L'\0';
	  if (wcsncmp (f.dbi.ObjectName.Buffer, L"cygpid.", 7) == 0)
	    {
	    DWORD pid = wcstoul (f.dbi.ObjectName.Buffer + 7, NULL, 10);
	    add (nelem, false, pid);
	  }
	}
    }
  else
    {
      static DWORD szprocs;
      static PSYSTEM_PROCESS_INFORMATION procs;

      while (1)
	{
	  PSYSTEM_PROCESS_INFORMATION new_p = (PSYSTEM_PROCESS_INFORMATION)
	    realloc (procs, szprocs += 200 * sizeof (*procs));
	  if (!new_p)
	    {
	      system_printf ("out of memory reading system process "
			     "information");
	      return 0;
	    }
	  procs = new_p;
	  NTSTATUS status = NtQuerySystemInformation (SystemProcessInformation,
						      procs, szprocs, NULL);
	  if (NT_SUCCESS (status))
	    break;

	  if (status != STATUS_INFO_LENGTH_MISMATCH)
	    {
	      system_printf ("error %y reading system process information",
			     status);
	      return 0;
	    }
	}

      PSYSTEM_PROCESS_INFORMATION px = procs;
      while (1)
	{
	  if (px->UniqueProcessId)
	    add (nelem, true, (DWORD) (uintptr_t) px->UniqueProcessId);
	  if (!px->NextEntryOffset)
	    break;
          px = (PSYSTEM_PROCESS_INFORMATION) ((char *) px + px->NextEntryOffset);
	}
    }
  return nelem;
}

void
winpids::set (bool winpid)
{
  npids = enum_processes (winpid);
  if (pidlist)
    pidlist[npids] = 0;
}

DWORD
winpids::enum_init (bool winpid)
{
  return enum_processes (winpid);
}

void
winpids::release ()
{
  _pinfo *p;
  for (unsigned i = 0; i < npids; i++)
    if (pinfolist[i] == (_pinfo *) myself)
      continue;
    else if (pinfolist[i].hProcess)
      pinfolist[i].release ();
    else if ((p = pinfolist[i]))
      {
	pinfolist[i].procinfo = NULL;
	free (p);
      }
}

winpids::~winpids ()
{
  if (npidlist)
    {
      release ();
      free (pidlist);
      free (pinfolist);
    }
}
