#include <sys/param.h>
#include <sys/queue.h>
#include <sys/exec.h>
#include <sys/lock.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/sbuf.h>
#include <sys/sysproto.h>
#include <sys/systm.h>
#include <sys/vnode.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_param.h>
#include <fs/pseudofs/pseudofs.h>
#include <fs/procfs/procfs.h>
int
procfs_doprocfile(PFS_FILL_ARGS)
{
char *fullpath, *freepath, *binpath;
int error;
freepath = NULL;
binpath = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
PROC_LOCK(p);
error = proc_get_binpath(p, binpath, &fullpath, &freepath);
if (error == 0)
sbuf_cat(sb, fullpath);
free(binpath, M_TEMP);
free(freepath, M_TEMP);
return (error);
}
int
procfs_docurproc(PFS_FILL_ARGS)
{
sbuf_printf(sb, "%ld", (long)td->td_proc->p_pid);
return (0);
}
static int
procfs_attr(PFS_ATTR_ARGS, int mode) {
vap->va_mode = mode;
if (p != NULL) {
PROC_LOCK_ASSERT(p, MA_OWNED);
if ((p->p_flag & P_SUGID) && pn->pn_type != pfstype_procdir)
vap->va_mode = 0;
}
return (0);
}
int
procfs_attr_all_rx(PFS_ATTR_ARGS)
{
return (procfs_attr(td, p, pn, vap, 0555));
}
int
procfs_attr_rw(PFS_ATTR_ARGS)
{
return (procfs_attr(td, p, pn, vap, 0600));
}
int
procfs_attr_w(PFS_ATTR_ARGS)
{
return (procfs_attr(td, p, pn, vap, 0200));
}
int
procfs_notsystem(PFS_VIS_ARGS)
{
PROC_LOCK_ASSERT(p, MA_OWNED);
return ((p->p_flag & P_SYSTEM) == 0);
}
int
procfs_candebug(PFS_VIS_ARGS)
{
PROC_LOCK_ASSERT(p, MA_OWNED);
return ((p->p_flag & P_SYSTEM) == 0 && p_candebug(td, p) == 0);
}
static int
procfs_init(PFS_INIT_ARGS)
{
struct pfs_node *root;
struct pfs_node *dir;
root = pi->pi_root;
pfs_create_link(root, NULL, "curproc", procfs_docurproc, NULL, NULL,
NULL, 0);
pfs_create_link(root, NULL, "self", procfs_docurproc, NULL, NULL, NULL,
0);
pfs_create_dir(root, &dir, "pid", procfs_attr_all_rx, NULL, NULL,
PFS_PROCDEP);
pfs_create_file(dir, NULL, "cmdline", procfs_doproccmdline, NULL, NULL,
NULL, PFS_RD);
pfs_create_file(dir, NULL, "dbregs", procfs_doprocdbregs,
procfs_attr_rw, procfs_candebug, NULL, PFS_RDWR | PFS_RAW);
pfs_create_file(dir, NULL, "etype", procfs_doproctype, NULL, NULL, NULL,
PFS_RD);
pfs_create_file(dir, NULL, "fpregs", procfs_doprocfpregs,
procfs_attr_rw, procfs_candebug, NULL, PFS_RDWR | PFS_RAW);
pfs_create_file(dir, NULL, "map", procfs_doprocmap, NULL,
procfs_notsystem, NULL, PFS_RD);
pfs_create_file(dir, NULL, "mem", procfs_doprocmem, procfs_attr_rw,
procfs_candebug, NULL, PFS_RDWR | PFS_RAW);
pfs_create_file(dir, NULL, "note", procfs_doprocnote, procfs_attr_w,
procfs_candebug, NULL, PFS_WR);
pfs_create_file(dir, NULL, "notepg", procfs_doprocnote, procfs_attr_w,
procfs_candebug, NULL, PFS_WR);
pfs_create_file(dir, NULL, "regs", procfs_doprocregs, procfs_attr_rw,
procfs_candebug, NULL, PFS_RDWR | PFS_RAW);
pfs_create_file(dir, NULL, "rlimit", procfs_doprocrlimit, NULL, NULL,
NULL, PFS_RD);
pfs_create_file(dir, NULL, "status", procfs_doprocstatus, NULL, NULL,
NULL, PFS_RD);
pfs_create_file(dir, NULL, "osrel", procfs_doosrel, procfs_attr_rw,
procfs_candebug, NULL, PFS_RDWR);
pfs_create_link(dir, NULL, "file", procfs_doprocfile, NULL,
procfs_notsystem, NULL, 0);
pfs_create_link(dir, NULL, "exe", procfs_doprocfile, NULL,
procfs_notsystem, NULL, 0);
return (0);
}
static int
procfs_uninit(PFS_INIT_ARGS)
{
return (0);
}
PSEUDOFS(procfs, 1, VFCF_JAIL);