#ifndef _FS_PROCFS_PRDATA_H /* wrapper symbol for kernel use */
#define _FS_PROCFS_PRDATA_H /* subject to change without notice */

#ident "@(#)kern:fs/procfs/prdata.h    1.19.2.1"
#ident "$Header: $"

#if defined(__cplusplus)
extern "C" {
#endif

#ifdef _KERNEL_HEADERS

#    include <fs/vnode.h>    /* SVR4.2COMPAT */
#    include <io/uio.h>      /* SVR4.0COMPAT */
#    include <mem/seg.h>     /* SVR4.0COMPAT */
#    include <proc/proc.h>   /* REQUIRED */
#    include <util/ksynch.h> /* REQUIRED */
#    include <util/types.h>  /* REQUIRED */

#elif defined(_KERNEL)

#    include <sys/vnode.h>  /* SVR4.2COMPAT */
#    include <sys/uio.h>    /* SVR4.0COMPAT */
#    include <vm/seg.h>     /* SVR4.0COMPAT */
#    include <sys/proc.h>   /* REQUIRED */
#    include <sys/ksynch.h> /* REQUIRED */
#    include <sys/types.h>  /* REQUIRED */

#endif /* _KERNEL_HEADERS */

#if defined(_KERNEL) || defined(_KMEMUSER)

/*
 * Common file object to which all /proc vnodes for a specific process
 * or LWP refer.
 */
typedef struct prcommon {
    lock_t prc_mutex;              /* Lock for prc_flags and prc_rdwriters */
    uchar_t prc_flags;             /* flags */
    ulong_t prc_rdwriters;         /* # holding or queued for process r/w lock
        
        
        
   */
    sv_t prc_rdwrdone;             /* sync object to wait for r/w refs done */
    sv_t prc_stopsv;               /* sync object to wait for proc or LWP stop
              
              
              
   */
    struct pollhead *prc_pollhead; /* Pointer to list of pollers */
    pid_t prc_pid;                 /* process-ID */
    uint_t prc_opens;              /* Number of opens of prnodes */
    uint_t prc_writers;            /* Number of write opens of prnodes */
    proc_t *prc_proc;              /* Associated process */
    lwp_t *prc_lwp;                /* Associated LWP */
    lwpid_t prc_lwpid;             /* LWP id */
    int prc_slot;                  /* Associated process slot number */
} prcommon_t;

/* prc_flags */
#    define PRC_DESTROY 0x01 /* process or LWP is being destroyed */
#    define PRC_LWP 0x02     /* structure refers to an LWP */
#    define PRC_SYS 0x04     /* process is a system process */

/*
 * prc_mutex:   Per prcommon structure lock protecting fields within
 *              a prcommon structure.
 */
extern lkinfo_t prc_mutex_lkinfo;

/*
 * Node types for /proc files (directories and files contained therein).
 */
typedef enum prnodetype {
    PR_PROCDIR,   /* 00 /proc */
    PR_PIDDIR,    /* 01 /proc/pid */
    PR_AS,        /* 02 /proc/pid/as */
    PR_CTL,       /* 03 /proc/pid/ctl */
    PR_STATUS,    /* 04 /proc/pid/status */
    PR_PSINFO,    /* 05 /proc/pid/psinfo */
    PR_MAP,       /* 06 /proc/pid/map */
    PR_CRED,      /* 07 /proc/pid/cred */
    PR_SIGACT,    /* 08 /proc/pid/sigact */
    PR_OBJECTDIR, /* 09 /proc/pid/object */
    PR_LWPDIR,    /* 0A /proc/pid/lwp */
    PR_LWPIDDIR,  /* 0B /proc/pid/lwp/lwpid */
    PR_LWPCTL,    /* 0C /proc/pid/lwp/lwpid/lwpctl */
    PR_LWPSTATUS, /* 0D /proc/pid/lwp/lwpid/lwpstatus */
    PR_LWPSINFO   /* 0F /proc/pid/lwp/lwpid/lwpsinfo */
} prnodetype_t;

typedef struct prnode {
    lock_t pr_mutex;         /* Locks pr_flags and child
  pr_files */
    prnodetype_t pr_type;    /* Node type */
    mode_t pr_mode;          /* File mode */
    ino_t pr_ino;            /* Node id (for stat(2)) */
    ulong_t pr_flags;        /* Private flags */
    prcommon_t *pr_common;   /* common data structure */
    prcommon_t *pr_pcommon;  /* process common data structure */
    struct vnode *pr_parent; /* Parent directory */
    struct vnode **pr_files; /* Contained files (for directory)
                              */
    struct vnode *pr_next;   /* List in chain of (invalid)
  vnodes */
    uint_t pr_index;         /* Position within parent */
    struct vnode pr_vnode;   /* Embedded vnode */
} prnode_t;

/*
 * Values for pr_flags.
 */
#    define PR_INVAL 0x01 /* Vnode is invalidated */

#    define VTOP(vp) ((prnode_t *)((vp)->v_data))
#    define PTOV(pnp) (&(pnp)->pr_vnode)

/*
 * Tables used by prmakenode() in constructing a /proc vnode from
 * a <directory, name> pair.
 */
typedef struct prntable {
    char *prn_comp;         /* Name within directory */
    prnodetype_t prn_ctype; /* Node type of result vnode */
    int prn_zvisible;       /* Visibility if a zombie */
    int prn_nasvisible;     /* Visibility if no address space
                             */
    vtype_t prn_ftype;      /* File type of result vnode */
    mode_t prn_mode;        /* File mode of result vnode */
} prntable_t;

#endif /* _KERNEL || _KMEMUSER */

#ifdef _KERNEL

/*
 * pr_mutex:    Per-structure lock protecting the pr_files field
 *              and the pr_flags field of a child.
 */
extern lkinfo_t pr_mutex_lkinfo;

extern prntable_t pdtable[], ldtable[];
extern int npdent, nldent;

extern struct vnodeops prvnodeops;
extern struct vfs *procvfs;
extern dev_t procdev;

struct pstatus;
struct psinfo;
struct lwpstatus;
struct lwpsinfo;
struct pfamily;

extern ulong_t prsize(prnode_t *);
extern void prgetsigact(proc_t *, struct sigaction *);
extern void prgetaction(proc_t *, int, struct sigaction *);
extern int prusrio(proc_t *, enum uio_rw, struct uio *);
extern lwp_t *prchoose(proc_t *);
extern greg_t prgetpc(gregset_t);
extern int prgetscall(gregset_t);
extern caddr_t prgetpsaddr(lwp_t *);
extern void prdebugon(lwp_t *);
extern void prdebugoff(lwp_t *);
extern void prgetpfamily(const user_t *up, struct pfamily *fp);
extern int prwritectl_family(ulong_t, vnode_t *, uio_t *, int, cred_t *);
extern boolean_t pr_p_rdwr(prcommon_t *, boolean_t);
extern void pr_v_rdwr(prcommon_t *);
extern boolean_t pr_p_mutex(prcommon_t *);
#    ifdef DEBUG
extern int prfilesempty(vnode_t **, int);
#    endif
extern int prvpsegs(proc_t *, vnode_t **);
extern void prmapname(vnode_t *, char *, ino_t *, cred_t *);
extern int prcountsegs(struct as *);
extern int prnsegs(struct as *);
extern int setisempty(ulong_t *, unsigned int);
extern int prgetpstatus(proc_t *, struct pstatus *);
extern void prgetpsinfo(proc_t *, struct psinfo *);
extern int prgetlwpstatus(lwp_t *, struct lwpstatus *);
extern void prgetlwpsinfo(lwp_t *, struct lwpsinfo *);
extern void prchlvl(lid_t);

#    define prino(slot, lwpid, type)                                           \
        (((lwpid) << 18) | ((slot) << 5) | type + 2)

/*
 * Is an LWP stopped on an event of interest to /proc?
 */
#    define ISTOP(lwp)                                                         \
        ((lwp)->l_stat == SSTOP &&                                             \
         ((lwp)->l_whystop == PR_REQUESTED ||                                  \
          (lwp)->l_whystop == PR_SIGNALLED ||                                  \
          (lwp)->l_whystop == PR_SYSENTRY || (lwp)->l_whystop == PR_SYSEXIT || \
          (lwp)->l_whystop == PR_FAULTED))

/*
 * Assign one set to another (possible different sizes).
 *
 * Assigning to a smaller set causes members to be lost.
 * Assigning to a larger set causes extra members to be cleared.
 */
#    define prassignset(ap, sp)                                                \
        {                                                                      \
            register int _i_ = sizeof(*(ap)) / sizeof(ulong_t);                \
            while (--_i_ >= 0)                                                 \
                ((ulong_t *)(ap))[_i_] =                                       \
                    (_i_ >= sizeof(*(sp)) / sizeof(ulong_t))                   \
                        ? 0L                                                   \
                        : ((ulong_t *)(sp))[_i_];                              \
        }

/*
 * Determine whether or not a set (of arbitrary size) is empty.
 */
#    define prisempty(sp) setisempty((ulong_t *)(sp),
sizeof(*(sp))/sizeof(ulong_t))

#endif /* _KERNEL */

#if defined(__cplusplus)
}
#endif

#endif /* _FS_PROCFS_PRDATA_H */
