/* Info we keep on a process
   Copyright (C) 1991 Free Software Foundation

This file is part of the GNU Hurd.

The GNU Hurd is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.

The GNU Hurd is distributed in the hope that it will be useful, 
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with the GNU Hurd; see the file COPYING.  If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */

#include <mach.h>
#include <mach/error.h>
#include <mach/mig_errors.h>
#include <mach/boolean.h>
#include <mach/message.h>
#include <mach/notify.h>
#include <mach/mach_host.h>
#include <device/device.h>
#include <gnu/types.h>
#include <hurd/hurd_types.h>
#include <lib/libhurd.h>
#include <gnu/signal.h>
#include <gnu/resource.h>
#include <gnu/param.h>
#include <gnu/errno.h>
#include <gnu/posix_errors.h>
#include <gnu/wait.h>

#pragma once

/* Global variables */
host_priv_t host_priv;
mach_port_t device_master;
auth_t authserver;

mach_port_t request_portset;

#define WAIT_MSG_ID 24008	/* should be culled from processUser.c */

struct proc
{
  struct proc *p_next, **p_prevp; /* Link within process group */
  struct proc *p_hnext, **p_hprevp; /* Link on hash queue */

  /* Identification of this process */
  mach_port_t p_reqport;	/* receive right we take requests on */
  task_t p_task;		/* send right to task this represents */
  pid_t p_pid;			/* process ID */
  struct login *p_login;	/* login record */

  int p_argv, p_envp;		/* argument and environment vectors */

  /* Process structure */
  struct proc *p_parent, *p_ochild, *p_sib; /* hierarchy structure */
  struct pgrp *p_pgrp;		/* process group */
  pid_t p_pgid;			/* needed for wait */
  struct idblock p_idblock;	/* identification */

  /* Signal info */
  sigthread_t p_sigthread;	/* send right to signal thread of proc */
  int p_nsignals;		/* number of signals received */
  int p_exit_status;		/* exit status for parent */
  int p_stopsig;		/* signal process is currently stopped on */

  /* proc_wait () continuation for parent */
  struct wait_continuation
    {
      mach_port_t pw_reply_port;
      mach_msg_type_name_t pw_reply_port_type;
      pid_t pw_pid;
      int pw_options;
    } p_wc;

  /* Miscellaneous flags */
  int p_exec:1;			/* process has called proc_exec */
  int p_stopped:1;		/* process is known to be signal-stopped */
  int p_system:1;		/* process is immune to SIGKILL */
  int p_waited:1;		/* stop has been reported to parent wait */
  int p_exited:1;		/* process has called exit */
  int p_waiting:1;		/* process is blocked in wait */
  int p_traced:1;		/* process has special wait behavior */
  int p_nostopcld:1;		/* don't send SIGCHLD for stopped children */
};
typedef struct proc *pstruct_t; /* for the benefit of MiG */

struct pgrp
{
  struct pgrp *pg_hnext, **pg_hprevp; /* Link on hash bucket */
  struct proc *pg_plist;	/* pointer to processes */
  pid_t pg_pgid;		/* process group ID */
  struct session *pg_session;	/* session */
  int pg_orphcnt;		/* number of non-orphaned processes */
};

struct session
{
  struct proc *s_leader;	/* session leader or 0 if none */
  mach_port_t s_ctty;		/* controlling tty capability */
  int s_count;			/* number of process groups in session */
};

struct login
{
  int l_refcnt;			/* ref count of this struct */
  char l_name[0];		/* login name */
};

/* Functions in proc_subr.c:  */
int psig (struct proc *, int, int);
void wait_continuation (struct proc *, int);
void wait_reply (mach_port_t, mach_msg_type_name_t, 
		 int, struct rusage *, pid_t);
void join_pgrp (struct proc *);
void leave_pgrp (struct proc *);
struct proc *pfind (pid_t, int);
void paddhash (struct proc *);
int prociterate (int (*)(struct proc *, int), int);
void premhash (struct proc *);
pid_t genpid ();
struct pgrp *pgfind (pid_t);
void pgaddhash (struct pgrp *);
void pgremhash (struct pgrp *);
struct proc *make_process_struct ();
struct proc *convert_port_to_pstruct (process_t);
process_t convert_pstruct_to_port (struct proc *);
