#include <sys/ptrace.h>
#ifdef _KERNEL
#include <sys/proc.h>
typedef enum {
PFSauxv,
PFSchroot,
PFScmdline,
PFScpuinfo,
PFScpustat,
PFScurproc,
PFScwd,
PFSdevices,
PFSemul,
PFSenviron,
PFSexe,
PFSfd,
PFSfile,
PFSfpregs,
PFSloadavg,
PFSlimit,
PFSlimits,
PFSmap,
PFSmaps,
PFSmem,
PFSmeminfo,
PFSmounts,
PFSmqueue,
PFSmq_msg_def,
PFSmq_msg_max,
PFSmq_siz_def,
PFSmq_siz_max,
PFSmq_qmax,
PFSnote,
PFSnotepg,
PFSproc,
PFSregs,
PFSroot,
PFSself,
PFSstat,
PFSstatm,
PFSstatus,
PFSsys,
PFSsysfs,
PFSsysvipc,
PFSsysvipc_msg,
PFSsysvipc_sem,
PFSsysvipc_shm,
PFStask,
PFSuptime,
PFSversion,
#ifdef __HAVE_PROCFS_MACHDEP
PROCFS_MACHDEP_NODE_TYPES
#endif
PFSlast,
} pfstype;
struct pfskey {
pfstype pk_type;
pid_t pk_pid;
int pk_fd;
};
struct pfsnode {
LIST_ENTRY(pfsnode) pfs_hash;
struct vnode *pfs_vnode;
struct mount *pfs_mount;
struct pfskey pfs_key;
#define pfs_type pfs_key.pk_type
#define pfs_pid pfs_key.pk_pid
#define pfs_fd pfs_key.pk_fd
mode_t pfs_mode;
u_long pfs_flags;
uint64_t pfs_fileno;
};
#define PROCFS_NOTELEN 64
#define PROCFS_MAXNAMLEN 255
#endif
struct procfs_args {
int version;
int flags;
};
#define PROCFS_ARGSVERSION 1
#define PROCFSMNT_LINUXCOMPAT 0x01
#define PROCFSMNT_BITS "\177\20" \
"b\00linuxcompat\0"
#ifdef _KERNEL
#define CNEQ(cnp, s, len) \
((cnp)->cn_namelen == (len) && \
(memcmp((s), (cnp)->cn_nameptr, (len)) == 0))
#define UIO_MX 32
static __inline ino_t
procfs_fileno(pid_t _pid, pfstype _type, int _fd)
{
ino_t _ino;
switch (_type) {
case PFSroot:
return 2;
case PFScurproc:
return 3;
case PFSself:
return 4;
default:
_ino = _pid + 1;
if (_fd != -1)
_ino = _ino << 32 | _fd;
return _ino * PFSlast + _type;
}
}
#define PROCFS_FILENO(pid, type, fd) procfs_fileno(pid, type, fd)
#define PROCFS_TYPE(type) ((type) % PFSlast)
struct procfsmount {
int pmnt_flags;
};
#define VFSTOPROC(mp) ((struct procfsmount *)(mp)->mnt_data)
#define VTOPFS(vp) ((struct pfsnode *)(vp)->v_data)
#define PFSTOV(pfs) ((pfs)->pfs_vnode)
typedef struct vfs_namemap vfs_namemap_t;
struct vfs_namemap {
const char *nm_name;
int nm_val;
};
int vfs_getuserstr(struct uio *, char *, int *);
const vfs_namemap_t *vfs_findname(const vfs_namemap_t *, const char *, int);
struct mount;
struct proc *procfs_proc_find(struct mount *, pid_t);
bool procfs_use_linux_compat(struct mount *);
static inline bool
procfs_proc_is_linux_compat(void)
{
const char *emulname = curlwp->l_proc->p_emul->e_name;
return (strncmp(emulname, "linux", 5) == 0);
}
int procfs_proc_lock(struct mount *, int, struct proc **, int);
void procfs_proc_unlock(struct proc *);
int procfs_allocvp(struct mount *, struct vnode **, pid_t, pfstype, int);
int procfs_donote(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_doregs(struct lwp *, struct lwp *, struct pfsnode *,
struct uio *);
int procfs_dofpregs(struct lwp *, struct lwp *, struct pfsnode *,
struct uio *);
int procfs_domem(struct lwp *, struct lwp *, struct pfsnode *,
struct uio *);
int procfs_do_pid_stat(struct lwp *, struct lwp *, struct pfsnode *,
struct uio *);
int procfs_dostatus(struct lwp *, struct lwp *, struct pfsnode *,
struct uio *);
int procfs_domap(struct lwp *, struct proc *, struct pfsnode *,
struct uio *, int);
int procfs_doprocargs(struct lwp *, struct proc *, struct pfsnode *,
struct uio *, int);
int procfs_domeminfo(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_dodevices(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_docpuinfo(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_docpustat(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_doloadavg(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_do_pid_statm(struct lwp *, struct lwp *, struct pfsnode *,
struct uio *);
int procfs_dofd(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_douptime(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_domounts(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_doemul(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_doversion(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_doauxv(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_dolimit(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_dolimits(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_domq_msg_def(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_domq_msg_max(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_domq_siz_def(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_domq_siz_max(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_domq_qmax(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_dosysvipc_msg(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_dosysvipc_sem(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_dosysvipc_shm(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
void procfs_hashrem(struct pfsnode *);
int procfs_getfp(struct pfsnode *, struct proc *, struct file **);
int procfs_validauxv(struct lwp *, struct mount *);
int procfs_validfile(struct lwp *, struct mount *);
int procfs_validfpregs(struct lwp *, struct mount *);
int procfs_validregs(struct lwp *, struct mount *);
int procfs_validmap(struct lwp *, struct mount *);
int procfs_rw(void *);
int procfs_getcpuinfstr(char *, size_t *);
#define PROCFS_LOCKED 0x01
#define PROCFS_WANT 0x02
extern int (**procfs_vnodeop_p)(void *);
extern struct vfsops procfs_vfsops;
int procfs_root(struct mount *, int, struct vnode **);
#ifdef __HAVE_PROCFS_MACHDEP
struct vattr;
void procfs_machdep_allocvp(struct vnode *);
int procfs_machdep_rw(struct lwp *, struct lwp *, struct pfsnode *,
struct uio *);
int procfs_machdep_getattr(struct vnode *, struct vattr *, struct proc *);
#endif
#endif