summaryrefslogtreecommitdiff
path: root/sys/miscfs
diff options
context:
space:
mode:
authorPhilip Guenther <guenther@cvs.openbsd.org>2014-09-08 01:57:01 +0000
committerPhilip Guenther <guenther@cvs.openbsd.org>2014-09-08 01:57:01 +0000
commit9279e2c961d9a4c29af849c66feb8087e377c1b7 (patch)
tree43e6497dfcacf47b9d7f0ed73a8ac77806d4228f /sys/miscfs
parent4c6be48bddde1bbe2127d982ef75c5a73d0e3d5b (diff)
Actually remove the procfs files
Diffstat (limited to 'sys/miscfs')
-rw-r--r--sys/miscfs/procfs/procfs.h135
-rw-r--r--sys/miscfs/procfs/procfs_cmdline.c186
-rw-r--r--sys/miscfs/procfs/procfs_linux.c133
-rw-r--r--sys/miscfs/procfs/procfs_status.c172
-rw-r--r--sys/miscfs/procfs/procfs_subr.c284
-rw-r--r--sys/miscfs/procfs/procfs_vfsops.c219
-rw-r--r--sys/miscfs/procfs/procfs_vnops.c992
7 files changed, 0 insertions, 2121 deletions
diff --git a/sys/miscfs/procfs/procfs.h b/sys/miscfs/procfs/procfs.h
deleted file mode 100644
index 9c091446323..00000000000
--- a/sys/miscfs/procfs/procfs.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/* $OpenBSD: procfs.h,v 1.28 2011/12/24 04:34:20 guenther Exp $ */
-/* $NetBSD: procfs.h,v 1.17 1996/02/12 15:01:41 christos Exp $ */
-
-/*
- * Copyright (c) 1993 Jan-Simon Pendry
- * Copyright (c) 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)procfs.h 8.7 (Berkeley) 6/15/94
- */
-
-/*
- * The different types of node in a procfs filesystem
- */
-typedef enum {
- Proot, /* the filesystem root */
- Pcurproc, /* symbolic link for curproc */
- Pself, /* like curproc, but this is the Linux name */
- Pproc, /* a process-specific sub-directory */
- Pfile, /* the executable file */
- Pmem, /* the process's memory image */
- Pregs, /* the process's register set */
- Pfpregs, /* the process's FP register set */
- Pctl, /* process control */
- Pstatus, /* process status */
- Pnote, /* process notifier */
- Pnotepg, /* process group notifier */
- Pcmdline, /* process command line args */
- Pmeminfo, /* system memory info (if -o linux) */
- Pcpuinfo /* CPU info (if -o linux) */
-} pfstype;
-
-/*
- * control data for the proc file system.
- */
-struct pfsnode {
- TAILQ_ENTRY(pfsnode) list;
- struct vnode *pfs_vnode; /* vnode associated with this pfsnode */
- pfstype pfs_type; /* type of procfs node */
- pid_t pfs_pid; /* associated process */
- mode_t pfs_mode; /* mode bits for stat() */
- u_long pfs_flags; /* open flags */
- u_long pfs_fileno; /* unique file id */
-};
-
-/*
- * Kernel stuff follows
- */
-#ifdef _KERNEL
-#define CNEQ(cnp, s, len) \
- ((cnp)->cn_namelen == (len) && \
- (bcmp((s), (cnp)->cn_nameptr, (len)) == 0))
-
-#define UIO_MX 32
-
-#define PROCFS_FILENO(pid, type) \
- (((type) < Pproc) ? \
- ((type) + 4) : \
- ((((pid)+1) << 5) + ((int) (type))))
-
-struct procfsmount {
- void *pmnt_exechook;
- int pmnt_flags;
-};
-
-#define VFSTOPROC(mp) ((struct procfsmount *)(mp)->mnt_data)
-
-/*
- * Convert between pfsnode vnode
- */
-#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 *, char *, int);
-
-int procfs_allocvp(struct mount *, struct vnode **, pid_t, pfstype);
-int procfs_dostatus(struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio);
-int procfs_docmdline(struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio);
-int procfs_domeminfo(struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio);
-int procfs_docpuinfo(struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio);
-int procfs_freevp(struct vnode *);
-int procfs_getcpuinfstr(char *, int *);
-int procfs_poll(void *);
-
-/* functions to check whether or not files should be displayed */
-int procfs_validfile(struct proc *, struct mount *);
-
-int procfs_rw(void *);
-
-#define PROCFS_LOCKED 0x01
-#define PROCFS_WANT 0x02
-
-extern struct vops procfs_vops;
-extern const struct vfsops procfs_vfsops;
-
-struct vfsconf;
-
-int procfs_init(struct vfsconf *);
-int procfs_root(struct mount *, struct vnode **);
-
-#endif /* _KERNEL */
diff --git a/sys/miscfs/procfs/procfs_cmdline.c b/sys/miscfs/procfs/procfs_cmdline.c
deleted file mode 100644
index ccfed62ebc3..00000000000
--- a/sys/miscfs/procfs/procfs_cmdline.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/* $OpenBSD: procfs_cmdline.c,v 1.13 2014/07/12 18:43:52 tedu Exp $ */
-/* $NetBSD: procfs_cmdline.c,v 1.3 1999/03/13 22:26:48 thorpej Exp $ */
-
-/*
- * Copyright (c) 1999 Jaromir Dolecek <dolecek@ics.muni.cz>
- * Copyright (c) 1999 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Jaromir Dolecek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/syslimits.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/exec.h>
-#include <sys/malloc.h>
-#include <miscfs/procfs/procfs.h>
-
-/*
- * code for returning process's command line arguments
- */
-int
-procfs_docmdline(struct proc *curp, struct proc *p, struct pfsnode *pfs, struct uio *uio)
-{
- struct process *pr = p->p_p;
- struct ps_strings pss;
- int count, error, i;
- size_t len, xlen, upper_bound;
- struct uio auio;
- struct iovec aiov;
- struct vmspace *vm;
- vaddr_t argv;
- char *arg;
-
- /* Don't allow writing. */
- if (uio->uio_rw != UIO_READ)
- return (EOPNOTSUPP);
-
- /*
- * Allocate a temporary buffer to hold the arguments.
- */
- arg = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
-
- /*
- * Zombies don't have a stack, so we can't read their psstrings.
- * System processes also don't have a user stack. This is what
- * ps(1) would display.
- */
- if (pr->ps_flags & (PS_ZOMBIE | PS_SYSTEM)) {
- len = snprintf(arg, PAGE_SIZE, "(%s)", p->p_comm);
- if (uio->uio_offset >= (off_t)len)
- error = 0;
- else
- error = uiomove(arg, len - uio->uio_offset, uio);
-
- free(arg, M_TEMP, 0);
- return (error);
- }
-
- /*
- * NOTE: Don't bother doing a process_checkioperm() here
- * because the psstrings info is available by using ps(1),
- * so it's not like there's anything to protect here.
- */
-
- /*
- * Lock the process down in memory.
- */
- /* XXXCDC: how should locking work here? */
- if ((pr->ps_flags & PS_EXITING) || (pr->ps_vmspace->vm_refcnt < 1)) {
- free(arg, M_TEMP, 0);
- return (EFAULT);
- }
- vm = pr->ps_vmspace;
- vm->vm_refcnt++; /* XXX */
-
- /*
- * Read in the ps_strings structure.
- */
- aiov.iov_base = &pss;
- aiov.iov_len = sizeof(pss);
- auio.uio_iov = &aiov;
- auio.uio_iovcnt = 1;
- auio.uio_offset = (vaddr_t)PS_STRINGS;
- auio.uio_resid = sizeof(pss);
- auio.uio_segflg = UIO_SYSSPACE;
- auio.uio_rw = UIO_READ;
- auio.uio_procp = NULL;
- error = uvm_io(&vm->vm_map, &auio, 0);
- if (error)
- goto bad;
-
- /*
- * Now read the address of the argument vector.
- */
- aiov.iov_base = &argv;
- aiov.iov_len = sizeof(argv);
- auio.uio_iov = &aiov;
- auio.uio_iovcnt = 1;
- auio.uio_offset = (vaddr_t)pss.ps_argvstr;
- auio.uio_resid = sizeof(argv);
- auio.uio_segflg = UIO_SYSSPACE;
- auio.uio_rw = UIO_READ;
- auio.uio_procp = NULL;
- error = uvm_io(&vm->vm_map, &auio, 0);
- if (error)
- goto bad;
-
- /*
- * Now copy in the actual argument vector, one byte at a time,
- * since we don't know how long the vector is (though, we do
- * know how many NUL-terminated strings are in the vector).
- */
- len = 0;
- count = pss.ps_nargvstr;
- upper_bound = round_page(uio->uio_offset + uio->uio_resid);
- for (; count && len < upper_bound; len += xlen) {
- aiov.iov_base = arg;
- aiov.iov_len = PAGE_SIZE;
- auio.uio_iov = &aiov;
- auio.uio_iovcnt = 1;
- auio.uio_offset = argv + len;
- xlen = PAGE_SIZE - ((argv + len) & PAGE_MASK);
- auio.uio_resid = xlen;
- auio.uio_segflg = UIO_SYSSPACE;
- auio.uio_rw = UIO_READ;
- auio.uio_procp = NULL;
- error = uvm_io(&vm->vm_map, &auio, 0);
- if (error)
- goto bad;
-
- for (i = 0; i < xlen && count != 0; i++) {
- if (arg[i] == '\0')
- count--; /* one full string */
- }
-
- if (count == 0)
- i--; /* exclude the final NUL */
-
- if (len + i > uio->uio_offset) {
- /* Have data in this page, copy it out */
- error = uiomove(arg + uio->uio_offset - len,
- i + len - uio->uio_offset, uio);
- if (error || uio->uio_resid <= 0)
- break;
- }
- }
-
-
- bad:
- uvmspace_free(vm);
- free(arg, M_TEMP, 0);
- return (error);
-}
diff --git a/sys/miscfs/procfs/procfs_linux.c b/sys/miscfs/procfs/procfs_linux.c
deleted file mode 100644
index 5480072e037..00000000000
--- a/sys/miscfs/procfs/procfs_linux.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/* $OpenBSD: procfs_linux.c,v 1.9 2014/07/08 17:19:25 deraadt Exp $ */
-/* $NetBSD: procfs_linux.c,v 1.2.4.1 2001/03/30 21:48:11 he Exp $ */
-
-/*
- * Copyright (c) 2001 Wasabi Systems, Inc.
- * All rights reserved.
- *
- * Written by Frank van der Linden for Wasabi Systems, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed for the NetBSD Project by
- * Wasabi Systems, Inc.
- * 4. The name of Wasabi Systems, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-
-#include <miscfs/procfs/procfs.h>
-
-#define PGTOB(p) ((unsigned long)(p) << PAGE_SHIFT)
-#define PGTOKB(p) ((unsigned long)(p) << (PAGE_SHIFT - 10))
-
-/*
- * Linux compatible /proc/meminfo. Only active when the -o linux
- * mountflag is used.
- */
-int
-procfs_domeminfo(struct proc *curp, struct proc *p, struct pfsnode *pfs,
- struct uio *uio)
-{
- char buf[512], *cp;
- int len, error;
-
- len = snprintf(buf, sizeof buf,
- " total: used: free: shared: buffers: cached:\n"
- "Mem: %8lu %8lu %8lu %8lu %8lu %8lu\n"
- "Swap: %8lu %8lu %8lu\n"
- "MemTotal: %8lu kB\n"
- "MemFree: %8lu kB\n"
- "MemShared: %8lu kB\n"
- "Buffers: %8lu kB\n"
- "Cached: %8lu kB\n"
- "SwapTotal: %8lu kB\n"
- "SwapFree: %8lu kB\n",
- PGTOB(uvmexp.npages),
- PGTOB(uvmexp.npages - uvmexp.free),
- PGTOB(uvmexp.free),
- 0L,
- 0L,
- 0L,
- PGTOB(uvmexp.swpages),
- PGTOB(uvmexp.swpginuse),
- PGTOB(uvmexp.swpages - uvmexp.swpginuse),
- PGTOKB(uvmexp.npages),
- PGTOKB(uvmexp.free),
- 0L,
- 0L,
- 0L,
- PGTOKB(uvmexp.swpages),
- PGTOKB(uvmexp.swpages - uvmexp.swpginuse));
-
- if (len <= 0 || len >= sizeof buf ||
- len < uio->uio_offset || uio->uio_resid == 0)
- return EINVAL;
-
- len -= uio->uio_offset;
- cp = buf + uio->uio_offset;
- len = imin(len, uio->uio_resid);
- error = uiomove(cp, len, uio);
- return error;
-}
-
-int
-procfs_docpuinfo(struct proc *curp, struct proc *p, struct pfsnode *pfs,
- struct uio *uio)
-{
- char buf[512], *cp;
- int len, error;
-
- len = sizeof buf;
- if (procfs_getcpuinfstr(buf, &len) < 0)
- return EIO;
-
- if (len == 0 || uio->uio_offset > sizeof(buf))
- return 0;
-
- len -= uio->uio_offset;
- cp = buf + uio->uio_offset;
- len = imin(len, uio->uio_resid);
- if (len <= 0)
- error = 0;
- else
- error = uiomove(cp, len, uio);
- return error;
-}
-
-#ifndef __i386__
-int
-procfs_getcpuinfstr(char *buf, int *len)
-{
- *len = 0;
-
- return 0;
-}
-#endif
diff --git a/sys/miscfs/procfs/procfs_status.c b/sys/miscfs/procfs/procfs_status.c
deleted file mode 100644
index 3596141ee8d..00000000000
--- a/sys/miscfs/procfs/procfs_status.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/* $OpenBSD: procfs_status.c,v 1.16 2014/07/12 18:43:52 tedu Exp $ */
-/* $NetBSD: procfs_status.c,v 1.11 1996/03/16 23:52:50 christos Exp $ */
-
-/*
- * Copyright (c) 1993 Jan-Simon Pendry
- * Copyright (c) 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)procfs_status.c 8.4 (Berkeley) 6/15/94
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/ioctl.h>
-#include <sys/tty.h>
-#include <sys/resource.h>
-#include <sys/resourcevar.h>
-#include <miscfs/procfs/procfs.h>
-
-int procfs_stat_gen(struct proc *, char *s, int);
-
-#define COUNTORCAT(s, l, ps, n) do { \
- if (s) \
- strlcat(s, ps, l); \
- else \
- n += strlen(ps); \
- } while (0)
-
-/* Generates:
- * comm pid ppid pgid sid maj,min ctty,sldr start ut st wmsg uid gid groups
- */
-int
-procfs_stat_gen(struct proc *p, char *s, int l)
-{
- struct process *pr = p->p_p;
- struct session *sess;
- struct tty *tp;
- struct ucred *cr;
- int pid, ppid, pgid, sid;
- struct timeval ut, st;
- char ps[256], *sep;
- int i, n;
-
- pid = pr->ps_pid;
- ppid = pr->ps_pptr ? pr->ps_pptr->ps_pid : 0;
- pgid = pr->ps_pgrp->pg_id;
- sess = pr->ps_pgrp->pg_session;
- sid = sess->s_leader ? sess->s_leader->ps_pid : 0;
-
- n = 0;
- if (s)
- bzero(s, l);
-
- bcopy(p->p_comm, ps, MAXCOMLEN-1);
- ps[MAXCOMLEN] = '\0';
- COUNTORCAT(s, l, ps, n);
-
- (void) snprintf(ps, sizeof(ps), " %d %d %d %d ",
- pid, ppid, pgid, sid);
- COUNTORCAT(s, l, ps, n);
-
- if ((pr->ps_flags & PS_CONTROLT) && (tp = sess->s_ttyp))
- snprintf(ps, sizeof(ps), "%d,%d ",
- major(tp->t_dev), minor(tp->t_dev));
- else
- snprintf(ps, sizeof(ps), "%d,%d ",
- -1, -1);
- COUNTORCAT(s, l, ps, n);
-
- sep = "";
- if (sess->s_ttyvp) {
- snprintf(ps, sizeof(ps), "%sctty", sep);
- sep = ",";
- COUNTORCAT(s, l, ps, n);
- }
-
- if (SESS_LEADER(pr)) {
- snprintf(ps, sizeof(ps), "%ssldr", sep);
- sep = ",";
- COUNTORCAT(s, l, ps, n);
- }
-
- if (*sep != ',') {
- snprintf(ps, sizeof(ps), "noflags");
- COUNTORCAT(s, l, ps, n);
- }
-
- snprintf(ps, sizeof(ps), " %lld,%ld",
- (long long)pr->ps_start.tv_sec, pr->ps_start.tv_nsec/1000);
- COUNTORCAT(s, l, ps, n);
-
- calcru(&pr->ps_tu, &ut, &st, (void *) 0);
- snprintf(ps, sizeof(ps), " %lld,%ld %lld,%ld",
- (long long)ut.tv_sec, ut.tv_usec,
- (long long)st.tv_sec, st.tv_usec);
- COUNTORCAT(s, l, ps, n);
-
- snprintf(ps, sizeof(ps), " %s",
- (p->p_wchan && p->p_wmesg) ? p->p_wmesg : "nochan");
- COUNTORCAT(s, l, ps, n);
-
- cr = p->p_ucred;
-
- snprintf(ps, sizeof(ps), " %u, %u", cr->cr_uid, cr->cr_gid);
- COUNTORCAT(s, l, ps, n);
- for (i = 0; i < cr->cr_ngroups; i++) {
- snprintf(ps, sizeof(ps), ",%u", cr->cr_groups[i]);
- COUNTORCAT(s, l, ps, n);
- }
-
- snprintf(ps, sizeof(ps), "\n");
- COUNTORCAT(s, l, ps, n);
-
- return (s != NULL ? strlen(s) + 1 : n + 1);
-}
-
-int
-procfs_dostatus(struct proc *curp, struct proc *p, struct pfsnode *pfs, struct uio *uio)
-{
- char *ps;
- int error, len;
-
- if (uio->uio_rw != UIO_READ)
- return (EOPNOTSUPP);
-
- len = procfs_stat_gen(p, NULL, 0);
- ps = malloc(len, M_TEMP, M_WAITOK);
- len = procfs_stat_gen(p, ps, len);
-
- if (len <= uio->uio_offset)
- error = 0;
- else {
- len -= uio->uio_offset;
- len = imin(len, uio->uio_resid);
- error = uiomove(ps + uio->uio_offset, len, uio);
- }
-
- free(ps, M_TEMP, 0);
- return (error);
-}
diff --git a/sys/miscfs/procfs/procfs_subr.c b/sys/miscfs/procfs/procfs_subr.c
deleted file mode 100644
index b6b616cf144..00000000000
--- a/sys/miscfs/procfs/procfs_subr.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/* $OpenBSD: procfs_subr.c,v 1.36 2014/07/12 18:43:52 tedu Exp $ */
-/* $NetBSD: procfs_subr.c,v 1.15 1996/02/12 15:01:42 christos Exp $ */
-
-/*
- * Copyright (c) 1993 Jan-Simon Pendry
- * Copyright (c) 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)procfs_subr.c 8.5 (Berkeley) 6/15/94
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/malloc.h>
-#include <sys/rwlock.h>
-#include <sys/stat.h>
-#include <sys/ptrace.h>
-
-#include <miscfs/procfs/procfs.h>
-
-static TAILQ_HEAD(, pfsnode) pfshead;
-struct rwlock pfs_vlock = RWLOCK_INITIALIZER("procfsl");
-
-/*ARGSUSED*/
-int
-procfs_init(struct vfsconf *vfsp)
-{
- TAILQ_INIT(&pfshead);
- return (0);
-}
-
-/*
- * allocate a pfsnode/vnode pair. the vnode is
- * referenced, but not locked.
- *
- * the pid, pfs_type, and mount point uniquely
- * identify a pfsnode. the mount point is needed
- * because someone might mount this filesystem
- * twice.
- *
- * all pfsnodes are maintained on a singly-linked
- * list. new nodes are only allocated when they cannot
- * be found on this list. entries on the list are
- * removed when the vfs reclaim entry is called.
- *
- * a single lock is kept for the entire list. this is
- * needed because the getnewvnode() function can block
- * waiting for a vnode to become free, in which case there
- * may be more than one process trying to get the same
- * vnode. this lock is only taken if we are going to
- * call getnewvnode, since the kernel itself is single-threaded.
- *
- * if an entry is found on the list, then call vget() to
- * take a reference. this is done because there may be
- * zero references to it and so it needs to removed from
- * the vnode free list.
- */
-int
-procfs_allocvp(struct mount *mp, struct vnode **vpp, pid_t pid, pfstype pfs_type)
-{
- struct proc *p = curproc;
- struct pfsnode *pfs;
- struct vnode *vp;
- int error = 0;
-
- /*
- * Lock the vp list, getnewvnode can sleep.
- */
- rw_enter_write(&pfs_vlock);
-loop:
- TAILQ_FOREACH(pfs, &pfshead, list) {
- vp = PFSTOV(pfs);
- if (pfs->pfs_pid == pid &&
- pfs->pfs_type == pfs_type &&
- vp->v_mount == mp) {
- if (vget(vp, 0, p))
- goto loop;
- *vpp = vp;
- goto out;
- }
- }
-
- if ((error = getnewvnode(VT_PROCFS, mp, &procfs_vops, vpp)) != 0)
- goto out;
- vp = *vpp;
-
- pfs = malloc(sizeof(*pfs), M_TEMP, M_WAITOK);
- vp->v_data = pfs;
-
- pfs->pfs_pid = pid;
- pfs->pfs_type = pfs_type;
- pfs->pfs_vnode = vp;
- pfs->pfs_flags = 0;
- pfs->pfs_fileno = PROCFS_FILENO(pid, pfs_type);
-
- switch (pfs_type) {
- case Proot: /* /proc = dr-xr-xr-x */
- pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
- vp->v_type = VDIR;
- vp->v_flag = VROOT;
- break;
-
- case Pcurproc: /* /proc/curproc = lr--r--r-- */
- case Pself: /* /proc/self = lr--r--r-- */
- pfs->pfs_mode = S_IRUSR|S_IRGRP|S_IROTH;
- vp->v_type = VLNK;
- break;
-
- case Pproc: /* /proc/N = dr-xr-xr-x */
- pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
- vp->v_type = VDIR;
- break;
-
- case Pfile: /* /proc/N/file = -rw------- */
- case Pmem: /* /proc/N/mem = -rw------- */
- case Pregs: /* /proc/N/regs = -rw------- */
- case Pfpregs: /* /proc/N/fpregs = -rw------- */
- pfs->pfs_mode = S_IRUSR|S_IWUSR;
- vp->v_type = VREG;
- break;
-
- case Pctl: /* /proc/N/ctl = --w------ */
- case Pnote: /* /proc/N/note = --w------ */
- case Pnotepg: /* /proc/N/notepg = --w------ */
- pfs->pfs_mode = S_IWUSR;
- vp->v_type = VREG;
- break;
-
- case Pstatus: /* /proc/N/status = -r--r--r-- */
- case Pcmdline: /* /proc/N/cmdline = -r--r--r-- */
- case Pmeminfo: /* /proc/meminfo = -r--r--r-- */
- case Pcpuinfo: /* /proc/cpuinfo = -r--r--r-- */
- pfs->pfs_mode = S_IRUSR|S_IRGRP|S_IROTH;
- vp->v_type = VREG;
- break;
-
- default:
- panic("procfs_allocvp");
- }
-
- /* add to procfs vnode list */
- TAILQ_INSERT_TAIL(&pfshead, pfs, list);
- uvm_vnp_setsize(vp, 0);
-out:
- rw_exit_write(&pfs_vlock);
-
- return (error);
-}
-
-int
-procfs_freevp(struct vnode *vp)
-{
- struct pfsnode *pfs = VTOPFS(vp);
-
- TAILQ_REMOVE(&pfshead, pfs, list);
- free(vp->v_data, M_TEMP, 0);
- vp->v_data = 0;
- return (0);
-}
-
-int
-procfs_rw(void *v)
-{
- struct vop_read_args *ap = v;
- struct vnode *vp = ap->a_vp;
- struct uio *uio = ap->a_uio;
- struct proc *curp = uio->uio_procp;
- struct pfsnode *pfs = VTOPFS(vp);
- struct proc *p;
-
- p = pfind(pfs->pfs_pid);
- if (p == 0 || (p->p_flag & P_THREAD))
- return (EINVAL);
- /* Do not permit games to be played with init(8) */
- if (p->p_pid == 1 && securelevel > 0 && uio->uio_rw == UIO_WRITE)
- return (EPERM);
- if (uio->uio_offset < 0)
- return (EINVAL);
-
- switch (pfs->pfs_type) {
- case Pstatus:
- return (procfs_dostatus(curp, p, pfs, uio));
-
- case Pmem:
- return (process_domem(curp, p, uio, PT_WRITE_I));
-
- case Pcmdline:
- return (procfs_docmdline(curp, p, pfs, uio));
-
- case Pmeminfo:
- return (procfs_domeminfo(curp, p, pfs, uio));
-
- case Pcpuinfo:
- return (procfs_docpuinfo(curp, p, pfs, uio));
-
- default:
- return (EOPNOTSUPP);
- }
-}
-
-/*
- * Get a string from userland into (buf). Strip a trailing
- * nl character (to allow easy access from the shell).
- * The buffer should be *buflenp + 1 chars long. vfs_getuserstr
- * will automatically add a nul char at the end.
- *
- * Returns 0 on success or the following errors
- *
- * EINVAL: file offset is non-zero.
- * EMSGSIZE: message is longer than kernel buffer
- * EFAULT: user i/o buffer is not addressable
- */
-int
-vfs_getuserstr(struct uio *uio, char *buf, int *buflenp)
-{
- int xlen;
- int error;
-
- if (uio->uio_offset != 0)
- return (EINVAL);
-
- xlen = *buflenp;
-
- /* must be able to read the whole string in one go */
- if (xlen < uio->uio_resid)
- return (EMSGSIZE);
- xlen = uio->uio_resid;
-
- if ((error = uiomove(buf, xlen, uio)) != 0)
- return (error);
-
- /* allow multiple writes without seeks */
- uio->uio_offset = 0;
-
- /* cleanup string and remove trailing newline */
- buf[xlen] = '\0';
- xlen = strlen(buf);
- if (xlen > 0 && buf[xlen-1] == '\n')
- buf[--xlen] = '\0';
- *buflenp = xlen;
-
- return (0);
-}
-
-const vfs_namemap_t *
-vfs_findname(const vfs_namemap_t *nm, char *buf, int buflen)
-{
- for (; nm->nm_name; nm++)
- if (bcmp(buf, nm->nm_name, buflen + 1) == 0)
- return (nm);
-
- return (0);
-}
diff --git a/sys/miscfs/procfs/procfs_vfsops.c b/sys/miscfs/procfs/procfs_vfsops.c
deleted file mode 100644
index adeb9b1edeb..00000000000
--- a/sys/miscfs/procfs/procfs_vfsops.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/* $OpenBSD: procfs_vfsops.c,v 1.32 2014/07/12 18:43:52 tedu Exp $ */
-/* $NetBSD: procfs_vfsops.c,v 1.25 1996/02/09 22:40:53 christos Exp $ */
-
-/*
- * Copyright (c) 1993 Jan-Simon Pendry
- * Copyright (c) 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)procfs_vfsops.c 8.5 (Berkeley) 6/15/94
- */
-
-/*
- * procfs VFS interface
- */
-
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/buf.h>
-#include <sys/syslog.h>
-#include <sys/mount.h>
-#include <sys/signalvar.h>
-#include <sys/vnode.h>
-#include <sys/malloc.h>
-
-#include <miscfs/procfs/procfs.h>
-
-int procfs_mount(struct mount *, const char *, void *,
- struct nameidata *, struct proc *);
-int procfs_start(struct mount *, int, struct proc *);
-int procfs_unmount(struct mount *, int, struct proc *);
-int procfs_statfs(struct mount *, struct statfs *, struct proc *);
-/*
- * VFS Operations.
- *
- * mount system call
- */
-/* ARGSUSED */
-int
-procfs_mount(struct mount *mp, const char *path, void *data, struct nameidata *ndp,
- struct proc *p)
-{
- struct procfsmount *pmnt;
- struct procfs_args args;
- int error;
-
- if (UIO_MX & (UIO_MX-1)) {
- log(LOG_ERR, "procfs: invalid directory entry size");
- return (EINVAL);
- }
-
- if (mp->mnt_flag & MNT_UPDATE)
- return (EOPNOTSUPP);
-
- if (data != NULL) {
- error = copyin(data, &args, sizeof(args));
- if (error != 0)
- return (error);
-
- if (args.version != PROCFS_ARGSVERSION)
- return (EINVAL);
- } else
- args.flags = 0;
-
- mp->mnt_flag |= MNT_LOCAL;
- pmnt = (struct procfsmount *) malloc(sizeof(struct procfsmount),
- M_MISCFSMNT, M_WAITOK);
-
- mp->mnt_data = pmnt;
- vfs_getnewfsid(mp);
-
- bzero(mp->mnt_stat.f_mntonname, MNAMELEN);
- strlcpy(mp->mnt_stat.f_mntonname, path, MNAMELEN);
- bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
- bcopy("procfs", mp->mnt_stat.f_mntfromname, sizeof("procfs"));
- bzero(mp->mnt_stat.f_mntfromspec, MNAMELEN);
- bcopy("procfs", mp->mnt_stat.f_mntfromspec, sizeof("procfs"));
- bcopy(&args, &mp->mnt_stat.mount_info.procfs_args, sizeof(args));
-
-#ifdef notyet
- pmnt->pmnt_exechook = exechook_establish(procfs_revoke_vnodes, mp);
-#endif
- pmnt->pmnt_flags = args.flags;
-
- return (0);
-}
-
-/*
- * unmount system call
- */
-int
-procfs_unmount(struct mount *mp, int mntflags, struct proc *p)
-{
- int error;
- extern int doforce;
- int flags = 0;
-
- if (mntflags & MNT_FORCE) {
- /* procfs can never be rootfs so don't check for it */
- if (!doforce)
- return (EINVAL);
- flags |= FORCECLOSE;
- }
-
- if ((error = vflush(mp, 0, flags)) != 0)
- return (error);
-
- free(VFSTOPROC(mp), M_MISCFSMNT, 0);
- mp->mnt_data = 0;
-
- return (0);
-}
-
-int
-procfs_root(struct mount *mp, struct vnode **vpp)
-{
- int error;
-
- error = procfs_allocvp(mp, vpp, 0, Proot);
- if (error)
- return (error);
- vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY, curproc);
-
- return (0);
-}
-
-/* ARGSUSED */
-int
-procfs_start(struct mount *mp, int flags, struct proc *p)
-{
-
- return (0);
-}
-
-/*
- * Get file system statistics.
- */
-int
-procfs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p)
-{
- sbp->f_bsize = PAGE_SIZE;
- sbp->f_iosize = PAGE_SIZE;
- sbp->f_blocks = uvmexp.npages - uvmexp.free + uvmexp.swpginuse;
- sbp->f_bfree = uvmexp.npages - uvmexp.free - uvmexp.active;
- sbp->f_bavail = 0;
- sbp->f_files = maxprocess; /* approx */
- sbp->f_ffree = maxprocess - nprocesses; /* approx */
- if (sbp != &mp->mnt_stat) {
- bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
- bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
- bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
- bcopy(mp->mnt_stat.f_mntfromspec, sbp->f_mntfromspec, MNAMELEN);
- bcopy(&mp->mnt_stat.mount_info.procfs_args,
- &sbp->mount_info.procfs_args, sizeof(struct procfs_args));
- }
- strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN);
- return (0);
-}
-
-
-#define procfs_sync ((int (*)(struct mount *, int, struct ucred *, \
- struct proc *))nullop)
-
-#define procfs_fhtovp ((int (*)(struct mount *, struct fid *, \
- struct vnode **))eopnotsupp)
-#define procfs_quotactl ((int (*)(struct mount *, int, uid_t, caddr_t, \
- struct proc *))eopnotsupp)
-#define procfs_sysctl ((int (*)(int *, u_int, void *, size_t *, void *, \
- size_t, struct proc *))eopnotsupp)
-#define procfs_vget ((int (*)(struct mount *, ino_t, struct vnode **)) \
- eopnotsupp)
-#define procfs_vptofh ((int (*)(struct vnode *, struct fid *))eopnotsupp)
-#define procfs_checkexp ((int (*)(struct mount *, struct mbuf *, \
- int *, struct ucred **))eopnotsupp)
-
-const struct vfsops procfs_vfsops = {
- procfs_mount,
- procfs_start,
- procfs_unmount,
- procfs_root,
- procfs_quotactl,
- procfs_statfs,
- procfs_sync,
- procfs_vget,
- procfs_fhtovp,
- procfs_vptofh,
- procfs_init,
- procfs_sysctl,
- procfs_checkexp
-};
diff --git a/sys/miscfs/procfs/procfs_vnops.c b/sys/miscfs/procfs/procfs_vnops.c
deleted file mode 100644
index 5804414e5d1..00000000000
--- a/sys/miscfs/procfs/procfs_vnops.c
+++ /dev/null
@@ -1,992 +0,0 @@
-/* $OpenBSD: procfs_vnops.c,v 1.60 2014/07/08 17:19:25 deraadt Exp $ */
-/* $NetBSD: procfs_vnops.c,v 1.40 1996/03/16 23:52:55 christos Exp $ */
-
-/*
- * Copyright (c) 1993 Jan-Simon Pendry
- * Copyright (c) 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)procfs_vnops.c 8.8 (Berkeley) 6/15/94
- */
-
-/*
- * procfs vnode interface
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/file.h>
-#include <sys/proc.h>
-#include <sys/mount.h>
-#include <sys/vnode.h>
-#include <sys/namei.h>
-#include <sys/malloc.h>
-#include <sys/dirent.h>
-#include <sys/resourcevar.h>
-#include <sys/poll.h>
-#include <sys/ptrace.h>
-#include <sys/stat.h>
-
-#include <machine/reg.h>
-
-#include <miscfs/procfs/procfs.h>
-
-/*
- * Vnode Operations.
- *
- */
-static int procfs_validfile_linux(struct proc *, struct mount *);
-
-/*
- * This is a list of the valid names in the
- * process-specific sub-directories. It is
- * used in procfs_lookup and procfs_readdir
- */
-struct proc_target {
- u_char pt_type;
- u_char pt_namlen;
- char *pt_name;
- pfstype pt_pfstype;
- int (*pt_valid)(struct proc *p, struct mount *mp);
-} proc_targets[] = {
-#define N(s) sizeof(s)-1, s
- /* name type validp */
- { DT_DIR, N("."), Pproc, NULL },
- { DT_DIR, N(".."), Proot, NULL },
- { DT_REG, N("file"), Pfile, procfs_validfile },
- { DT_REG, N("mem"), Pmem, NULL },
- { DT_REG, N("status"), Pstatus, NULL },
- { DT_REG, N("cmdline"), Pcmdline, NULL },
- { DT_REG, N("exe"), Pfile, procfs_validfile_linux },
-#undef N
-};
-static int nproc_targets = sizeof(proc_targets) / sizeof(proc_targets[0]);
-
-/*
- * List of files in the root directory. Note: the validate function
- * will be called with p == NULL for these
- */
-struct proc_target proc_root_targets[] = {
-#define N(s) sizeof(s)-1, s
- /* name type validp */
- { DT_REG, N("meminfo"), Pmeminfo, procfs_validfile_linux },
- { DT_REG, N("cpuinfo"), Pcpuinfo, procfs_validfile_linux },
-#undef N
-};
-static int nproc_root_targets =
- sizeof(proc_root_targets) / sizeof(proc_root_targets[0]);
-
-static pid_t atopid(const char *, u_int);
-
-/*
- * Prototypes for procfs vnode ops
- */
-int procfs_badop(void *);
-
-int procfs_lookup(void *);
-int procfs_open(void *);
-int procfs_close(void *);
-int procfs_access(void *);
-int procfs_getattr(void *);
-int procfs_setattr(void *);
-int procfs_ioctl(void *);
-int procfs_link(void *);
-int procfs_symlink(void *);
-int procfs_readdir(void *);
-int procfs_readlink(void *);
-int procfs_inactive(void *);
-int procfs_reclaim(void *);
-int procfs_print(void *);
-int procfs_pathconf(void *);
-
-static pid_t atopid(const char *, u_int);
-
-/*
- * procfs vnode operations.
- */
-struct vops procfs_vops = {
- .vop_lookup = procfs_lookup,
- .vop_create = procfs_badop,
- .vop_mknod = procfs_badop,
- .vop_open = procfs_open,
- .vop_close = procfs_close,
- .vop_access = procfs_access,
- .vop_getattr = procfs_getattr,
- .vop_setattr = procfs_setattr,
- .vop_read = procfs_rw,
- .vop_write = procfs_rw,
- .vop_ioctl = procfs_ioctl,
- .vop_poll = procfs_poll,
- .vop_fsync = procfs_badop,
- .vop_remove = procfs_badop,
- .vop_link = procfs_link,
- .vop_rename = procfs_badop,
- .vop_mkdir = procfs_badop,
- .vop_rmdir = procfs_badop,
- .vop_symlink = procfs_symlink,
- .vop_readdir = procfs_readdir,
- .vop_readlink = procfs_readlink,
- .vop_abortop = vop_generic_abortop,
- .vop_inactive = procfs_inactive,
- .vop_reclaim = procfs_reclaim,
- .vop_lock = nullop,
- .vop_unlock = nullop,
- .vop_bmap = vop_generic_bmap,
- .vop_strategy = procfs_badop,
- .vop_print = procfs_print,
- .vop_islocked = nullop,
- .vop_pathconf = procfs_pathconf,
- .vop_advlock = procfs_badop,
-};
-/*
- * set things up for doing i/o on
- * the pfsnode (vp). (vp) is locked
- * on entry, and should be left locked
- * on exit.
- *
- * for procfs we don't need to do anything
- * in particular for i/o. all that is done
- * is to support exclusive open on process
- * memory images.
- */
-int
-procfs_open(void *v)
-{
- struct vop_open_args *ap = v;
- struct pfsnode *pfs = VTOPFS(ap->a_vp);
- struct proc *p1 = ap->a_p; /* tracer */
- struct proc *p2; /* traced */
- int error;
-
- if ((p2 = pfind(pfs->pfs_pid)) == 0 || (p2->p_flag & P_THREAD))
- return (ENOENT); /* was ESRCH, jsp */
-
- switch (pfs->pfs_type) {
- case Pmem:
- if (((pfs->pfs_flags & FWRITE) && (ap->a_mode & O_EXCL)) ||
- ((pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE)))
- return (EBUSY);
-
- if ((error = process_checkioperm(p1, p2->p_p)) != 0)
- return (error);
-
- if (ap->a_mode & FWRITE)
- pfs->pfs_flags = ap->a_mode & (FWRITE|O_EXCL);
-
- return (0);
-
- default:
- break;
- }
-
- return (0);
-}
-
-/*
- * close the pfsnode (vp) after doing i/o.
- * (vp) is not locked on entry or exit.
- *
- * nothing to do for procfs other than undo
- * any exclusive open flag (see _open above).
- */
-int
-procfs_close(void *v)
-{
- struct vop_close_args *ap = v;
- struct pfsnode *pfs = VTOPFS(ap->a_vp);
-
- switch (pfs->pfs_type) {
- case Pmem:
- if ((ap->a_fflag & FWRITE) && (pfs->pfs_flags & O_EXCL))
- pfs->pfs_flags &= ~(FWRITE|O_EXCL);
- break;
- case Pctl:
- case Pstatus:
- case Pnotepg:
- case Pnote:
- case Proot:
- case Pcurproc:
- case Pself:
- case Pproc:
- case Pfile:
- case Pregs:
- case Pfpregs:
- case Pcmdline:
- case Pmeminfo:
- case Pcpuinfo:
- break;
- }
-
- return (0);
-}
-
-/*
- * do an ioctl operation on pfsnode (vp).
- * (vp) is not locked on entry or exit.
- */
-/*ARGSUSED*/
-int
-procfs_ioctl(void *v)
-{
-
- return (ENOTTY);
-}
-
-/*
- * _inactive is called when the pfsnode
- * is vrele'd and the reference count goes
- * to zero. (vp) will be on the vnode free
- * list, so to get it back vget() must be
- * used.
- *
- * for procfs, check if the process is still
- * alive and if it isn't then just throw away
- * the vnode by calling vgone(). this may
- * be overkill and a waste of time since the
- * chances are that the process will still be
- * there and pfind is not free.
- *
- * (vp) is not locked on entry or exit.
- */
-int
-procfs_inactive(void *v)
-{
- struct vop_inactive_args *ap = v;
- struct vnode *vp = ap->a_vp;
- struct pfsnode *pfs = VTOPFS(vp);
-
- if (pfind(pfs->pfs_pid) == NULL && !(vp->v_flag & VXLOCK))
- vgone(vp);
-
- return (0);
-}
-
-/*
- * _reclaim is called when getnewvnode()
- * wants to make use of an entry on the vnode
- * free list. at this time the filesystem needs
- * to free any private data and remove the node
- * from any private lists.
- */
-int
-procfs_reclaim(void *v)
-{
- struct vop_reclaim_args *ap = v;
-
- return (procfs_freevp(ap->a_vp));
-}
-
-/*
- * Return POSIX pathconf information applicable to special devices.
- */
-int
-procfs_pathconf(void *v)
-{
- struct vop_pathconf_args *ap = v;
- int error = 0;
-
- switch (ap->a_name) {
- case _PC_LINK_MAX:
- *ap->a_retval = LINK_MAX;
- break;
- case _PC_CHOWN_RESTRICTED:
- *ap->a_retval = 1;
- break;
- default:
- error = EINVAL;
- break;
- }
-
- return (error);
-}
-
-/*
- * _print is used for debugging.
- * just print a readable description
- * of (vp).
- */
-int
-procfs_print(void *v)
-{
- struct vop_print_args *ap = v;
- struct pfsnode *pfs = VTOPFS(ap->a_vp);
-
- printf("tag VT_PROCFS, type %d, pid %d, mode %x, flags %lx\n",
- pfs->pfs_type, pfs->pfs_pid, pfs->pfs_mode, pfs->pfs_flags);
- return 0;
-}
-
-int
-procfs_link(void *v)
-{
- struct vop_link_args *ap = v;
-
- VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
- vput(ap->a_dvp);
- return (EROFS);
-}
-
-int
-procfs_symlink(void *v)
-{
- struct vop_symlink_args *ap = v;
-
- VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
- vput(ap->a_dvp);
- return (EROFS);
-}
-
-
-/*
- * generic entry point for unsupported operations
- */
-/*ARGSUSED*/
-int
-procfs_badop(void *v)
-{
-
- return (EIO);
-}
-
-/*
- * Invent attributes for pfsnode (vp) and store
- * them in (vap).
- * Directories lengths are returned as zero since
- * any real length would require the genuine size
- * to be computed, and nothing cares anyway.
- *
- * this is relatively minimal for procfs.
- */
-int
-procfs_getattr(void *v)
-{
- struct vop_getattr_args *ap = v;
- struct pfsnode *pfs = VTOPFS(ap->a_vp);
- struct vattr *vap = ap->a_vap;
- struct proc *procp;
- int error;
-
- /* first check the process still exists */
- switch (pfs->pfs_type) {
- case Proot:
- case Pcurproc:
- case Pcpuinfo:
- case Pmeminfo:
- procp = 0;
- break;
-
- default:
- procp = pfind(pfs->pfs_pid);
- if (procp == 0 || (procp->p_flag & P_THREAD))
- return (ENOENT);
- }
-
- error = 0;
-
- /* start by zeroing out the attributes */
- VATTR_NULL(vap);
-
- /* next do all the common fields */
- vap->va_type = ap->a_vp->v_type;
- vap->va_mode = pfs->pfs_mode;
- vap->va_fileid = pfs->pfs_fileno;
- vap->va_flags = 0;
- vap->va_blocksize = PAGE_SIZE;
- vap->va_bytes = vap->va_size = 0;
-
- /*
- * Make all times be current TOD.
- * It would be possible to get the process start
- * time from the p_stat structure, but there's
- * no "file creation" time stamp anyway, and the
- * p_stat structure is not addressible if u. gets
- * swapped out for that process.
- */
- getnanotime(&vap->va_ctime);
- vap->va_atime = vap->va_mtime = vap->va_ctime;
-
- switch (pfs->pfs_type) {
- case Pregs:
- case Pfpregs:
-#ifndef PTRACE
- break;
-#endif
- case Pmem:
- /*
- * If the process has exercised some setuid or setgid
- * privilege, then rip away read/write permission so
- * that only root can gain access.
- */
- if (procp->p_p->ps_flags & PS_SUGID)
- vap->va_mode &= ~(S_IRUSR|S_IWUSR);
- /* FALLTHROUGH */
- case Pctl:
- case Pstatus:
- case Pnote:
- case Pnotepg:
- case Pcmdline:
- vap->va_nlink = 1;
- vap->va_uid = procp->p_ucred->cr_uid;
- vap->va_gid = procp->p_ucred->cr_gid;
- break;
- case Pmeminfo:
- case Pcpuinfo:
- vap->va_nlink = 1;
- vap->va_uid = vap->va_gid = 0;
- break;
- case Pproc:
- case Pfile:
- case Proot:
- case Pcurproc:
- case Pself:
- break;
- }
-
- /*
- * now do the object specific fields
- *
- * The size could be set from struct reg, but it's hardly
- * worth the trouble, and it puts some (potentially) machine
- * dependent data into this machine-independent code. If it
- * becomes important then this function should break out into
- * a per-file stat function in the corresponding .c file.
- */
-
- switch (pfs->pfs_type) {
- case Proot:
- /*
- * Set nlink to 1 to tell fts(3) we don't actually know.
- */
- vap->va_nlink = 1;
- vap->va_uid = 0;
- vap->va_gid = 0;
- vap->va_size = vap->va_bytes = DEV_BSIZE;
- break;
-
- case Pcurproc: {
- char buf[16]; /* should be enough */
- int len;
-
- len = snprintf(buf, sizeof buf, "%ld", (long)curproc->p_pid);
- if (len == -1 || len >= sizeof buf) {
- error = EINVAL;
- break;
- }
- vap->va_nlink = 1;
- vap->va_uid = 0;
- vap->va_gid = 0;
- vap->va_size = vap->va_bytes = len;
- break;
- }
-
- case Pself:
- vap->va_nlink = 1;
- vap->va_uid = 0;
- vap->va_gid = 0;
- vap->va_size = vap->va_bytes = sizeof("curproc");
- break;
-
- case Pproc:
- vap->va_nlink = 2;
- vap->va_uid = procp->p_ucred->cr_uid;
- vap->va_gid = procp->p_ucred->cr_gid;
- vap->va_size = vap->va_bytes = DEV_BSIZE;
- break;
-
- case Pfile:
- error = EOPNOTSUPP;
- break;
-
- case Pmem:
- vap->va_bytes = vap->va_size =
- ptoa(procp->p_vmspace->vm_tsize +
- procp->p_vmspace->vm_dsize +
- procp->p_vmspace->vm_ssize);
- break;
-
- case Pregs:
-#ifdef PTRACE
- vap->va_bytes = vap->va_size = sizeof(struct reg);
-#endif
- break;
-
- case Pfpregs:
-#if defined(PT_GETFPREGS) || defined(PT_SETFPREGS)
-#ifdef PTRACE
- vap->va_bytes = vap->va_size = sizeof(struct fpreg);
-#endif
-#endif
- break;
-
- case Pctl:
- case Pstatus:
- case Pnote:
- case Pnotepg:
- case Pcmdline:
- case Pmeminfo:
- case Pcpuinfo:
- vap->va_bytes = vap->va_size = 0;
- break;
-
-#ifdef DIAGNOSTIC
- default:
- panic("procfs_getattr");
-#endif
- }
-
- return (error);
-}
-
-/*ARGSUSED*/
-int
-procfs_setattr(void *v)
-{
- /*
- * just fake out attribute setting
- * it's not good to generate an error
- * return, otherwise things like creat()
- * will fail when they try to set the
- * file length to 0. worse, this means
- * that echo $note > /proc/$pid/note will fail.
- */
-
- return (0);
-}
-
-/*
- * implement access checking.
- *
- * actually, the check for super-user is slightly
- * broken since it will allow read access to write-only
- * objects. this doesn't cause any particular trouble
- * but does mean that the i/o entry points need to check
- * that the operation really does make sense.
- */
-int
-procfs_access(void *v)
-{
- struct vop_access_args *ap = v;
- struct vattr va;
- int error;
-
- if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred, ap->a_p)) != 0)
- return (error);
-
- return (vaccess(ap->a_vp->v_type, va.va_mode, va.va_uid, va.va_gid,
- ap->a_mode, ap->a_cred));
-}
-
-/*
- * lookup. this is incredibly complicated in the
- * general case, however for most pseudo-filesystems
- * very little needs to be done.
- *
- * unless you want to get a migraine, just make sure your
- * filesystem doesn't do any locking of its own. otherwise
- * read and inwardly digest ufs_lookup().
- */
-int
-procfs_lookup(void *v)
-{
- struct vop_lookup_args *ap = v;
- struct componentname *cnp = ap->a_cnp;
- struct vnode **vpp = ap->a_vpp;
- struct vnode *dvp = ap->a_dvp;
- char *pname = cnp->cn_nameptr;
- struct proc *curp = curproc;
- struct proc_target *pt;
- struct vnode *fvp;
- pid_t pid;
- struct pfsnode *pfs;
- struct proc *p = NULL;
- int i, error, wantpunlock, iscurproc = 0, isself = 0;
-
- *vpp = NULL;
- cnp->cn_flags &= ~PDIRUNLOCK;
-
- if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)
- return (EROFS);
-
- if (cnp->cn_namelen == 1 && *pname == '.') {
- *vpp = dvp;
- vref(dvp);
- return (0);
- }
-
- wantpunlock = (~cnp->cn_flags & (LOCKPARENT | ISLASTCN));
- pfs = VTOPFS(dvp);
- switch (pfs->pfs_type) {
- case Proot:
- if (cnp->cn_flags & ISDOTDOT)
- return (EIO);
-
- iscurproc = CNEQ(cnp, "curproc", 7);
- isself = CNEQ(cnp, "self", 4);
-
- if (iscurproc || isself) {
- error = procfs_allocvp(dvp->v_mount, vpp, 0,
- iscurproc ? Pcurproc : Pself);
- if ((error == 0) && (wantpunlock)) {
- VOP_UNLOCK(dvp, 0, curp);
- cnp->cn_flags |= PDIRUNLOCK;
- }
- return (error);
- }
-
- for (i = 0; i < nproc_root_targets; i++) {
- pt = &proc_root_targets[i];
- if (cnp->cn_namelen == pt->pt_namlen &&
- memcmp(pt->pt_name, pname, cnp->cn_namelen) == 0 &&
- (pt->pt_valid == NULL ||
- (*pt->pt_valid)(p, dvp->v_mount)))
- break;
- }
-
- if (i != nproc_root_targets) {
- error = procfs_allocvp(dvp->v_mount, vpp, 0,
- pt->pt_pfstype);
- if ((error == 0) && (wantpunlock)) {
- VOP_UNLOCK(dvp, 0, curp);
- cnp->cn_flags |= PDIRUNLOCK;
- }
- return (error);
- }
-
- pid = atopid(pname, cnp->cn_namelen);
- if (pid == NO_PID)
- break;
-
- p = pfind(pid);
- if (p == 0 || (p->p_flag & P_THREAD))
- break;
-
- error = procfs_allocvp(dvp->v_mount, vpp, pid, Pproc);
- if ((error == 0) && wantpunlock) {
- VOP_UNLOCK(dvp, 0, curp);
- cnp->cn_flags |= PDIRUNLOCK;
- }
- return (error);
-
- case Pproc:
- /*
- * do the .. dance. We unlock the directory, and then
- * get the root dir. That will automatically return ..
- * locked. Then if the caller wanted dvp locked, we
- * re-lock.
- */
- if (cnp->cn_flags & ISDOTDOT) {
- VOP_UNLOCK(dvp, 0, p);
- cnp->cn_flags |= PDIRUNLOCK;
- error = procfs_root(dvp->v_mount, vpp);
- if ((error == 0) && (wantpunlock == 0) &&
- ((error = vn_lock(dvp, LK_EXCLUSIVE, curp)) == 0))
- cnp->cn_flags &= ~PDIRUNLOCK;
- return (error);
- }
-
- p = pfind(pfs->pfs_pid);
- if (p == 0 || (p->p_flag & P_THREAD))
- break;
-
- for (pt = proc_targets, i = 0; i < nproc_targets; pt++, i++) {
- if (cnp->cn_namelen == pt->pt_namlen &&
- bcmp(pt->pt_name, pname, cnp->cn_namelen) == 0 &&
- (pt->pt_valid == NULL ||
- (*pt->pt_valid)(p, dvp->v_mount)))
- goto found;
- }
- break;
-
- found:
- if (pt->pt_pfstype == Pfile) {
- fvp = p->p_p->ps_textvp;
- /* We already checked that it exists. */
- vref(fvp);
- vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, curp);
- if (wantpunlock) {
- VOP_UNLOCK(dvp, 0, curp);
- cnp->cn_flags |= PDIRUNLOCK;
- }
- *vpp = fvp;
- return (0);
- }
-
- error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid,
- pt->pt_pfstype);
- if ((error == 0) && (wantpunlock)) {
- VOP_UNLOCK(dvp, 0, curp);
- cnp->cn_flags |= PDIRUNLOCK;
- }
- return (error);
-
- default:
- return (ENOTDIR);
- }
-
- return (cnp->cn_nameiop == LOOKUP ? ENOENT : EROFS);
-}
-
-int
-procfs_validfile(struct proc *p, struct mount *mp)
-{
-
- return (p->p_p->ps_textvp != NULLVP);
-}
-
-int
-procfs_validfile_linux(struct proc *p, struct mount *mp)
-{
- int flags;
-
- flags = VFSTOPROC(mp)->pmnt_flags;
- return ((flags & PROCFSMNT_LINUXCOMPAT) &&
- (p == NULL || procfs_validfile(p, mp)));
-}
-
-/*
- * readdir returns directory entries from pfsnode (vp).
- *
- * the strategy here with procfs is to generate a single
- * directory entry at a time (struct dirent) and then
- * copy that out to userland using uiomove. a more efficent
- * though more complex implementation, would try to minimize
- * the number of calls to uiomove(). for procfs, this is
- * hardly worth the added code complexity.
- *
- * this should just be done through read()
- */
-int
-procfs_readdir(void *v)
-{
- struct vop_readdir_args *ap = v;
- struct uio *uio = ap->a_uio;
- struct dirent d;
- struct pfsnode *pfs;
- struct vnode *vp;
- int i;
- int error;
-
- vp = ap->a_vp;
- pfs = VTOPFS(vp);
-
- if (uio->uio_resid < UIO_MX)
- return (EINVAL);
-
- error = 0;
- i = uio->uio_offset;
- if (i < 0)
- return (EINVAL);
- bzero(&d, UIO_MX);
- d.d_reclen = UIO_MX;
-
- switch (pfs->pfs_type) {
- /*
- * this is for the process-specific sub-directories.
- * all that is needed to is copy out all the entries
- * from the procent[] table (top of this file).
- */
- case Pproc: {
- struct proc *p;
- struct proc_target *pt;
-
- p = pfind(pfs->pfs_pid);
- if (p == NULL || (p->p_flag & P_THREAD))
- break;
-
- for (pt = &proc_targets[i];
- uio->uio_resid >= UIO_MX && i < nproc_targets; pt++, i++) {
- if (pt->pt_valid &&
- (*pt->pt_valid)(p, vp->v_mount) == 0)
- continue;
-
- d.d_fileno = PROCFS_FILENO(pfs->pfs_pid, pt->pt_pfstype);
- d.d_namlen = pt->pt_namlen;
- bcopy(pt->pt_name, d.d_name, pt->pt_namlen + 1);
- d.d_type = pt->pt_type;
-
- if ((error = uiomove(&d, UIO_MX, uio)) != 0)
- break;
- }
-
- break;
- }
-
- /*
- * this is for the root of the procfs filesystem
- * what is needed is a special entry for "curproc"
- * followed by an entry for each process on allprocess
-#ifdef PROCFS_ZOMBIE
- * and zombprocess.
-#endif
- */
-
- case Proot: {
-#ifdef PROCFS_ZOMBIE
- int doingzomb = 0;
-#endif
- int pcnt = i;
- volatile struct process *pr = LIST_FIRST(&allprocess);
-
- if (pcnt > 3)
- pcnt = 3;
-#ifdef PROCFS_ZOMBIE
- again:
-#endif
- for (; pr && uio->uio_resid >= UIO_MX; i++, pcnt++) {
- switch (i) {
- case 0: /* `.' */
- case 1: /* `..' */
- d.d_fileno = PROCFS_FILENO(0, Proot);
- d.d_namlen = i + 1;
- bcopy("..", d.d_name, d.d_namlen);
- d.d_name[i + 1] = '\0';
- d.d_type = DT_DIR;
- break;
-
- case 2:
- d.d_fileno = PROCFS_FILENO(0, Pcurproc);
- d.d_namlen = 7;
- bcopy("curproc", d.d_name, 8);
- d.d_type = DT_LNK;
- break;
-
- case 3:
- d.d_fileno = PROCFS_FILENO(0, Pself);
- d.d_namlen = 4;
- bcopy("self", d.d_name, 5);
- d.d_type = DT_LNK;
- break;
-
- case 4:
- if (VFSTOPROC(vp->v_mount)->pmnt_flags &
- PROCFSMNT_LINUXCOMPAT) {
- d.d_fileno = PROCFS_FILENO(0, Pcpuinfo);
- d.d_namlen = 7;
- bcopy("cpuinfo", d.d_name, 8);
- d.d_type = DT_REG;
- break;
- }
- /* fall through */
-
- case 5:
- if (VFSTOPROC(vp->v_mount)->pmnt_flags &
- PROCFSMNT_LINUXCOMPAT) {
- d.d_fileno = PROCFS_FILENO(0, Pmeminfo);
- d.d_namlen = 7;
- bcopy("meminfo", d.d_name, 8);
- d.d_type = DT_REG;
- break;
- }
- /* fall through */
-
- default:
- while (pcnt < i)
- pcnt++;
- d.d_fileno = PROCFS_FILENO(pr->ps_pid, Pproc);
- d.d_namlen = snprintf(d.d_name, sizeof(d.d_name),
- "%ld", (long)pr->ps_pid);
- d.d_type = DT_REG;
- break;
- }
-
- if ((error = uiomove(&d, UIO_MX, uio)) != 0)
- break;
- }
-#ifdef PROCFS_ZOMBIE
- if (pr == NULL && doingzomb == 0) {
- doingzomb = 1;
- pr = LIST_FIRST(&zombprocess);
- goto again;
- }
-#endif
-
- break;
-
- }
-
- default:
- error = ENOTDIR;
- break;
- }
-
- uio->uio_offset = i;
- return (error);
-}
-
-/*
- * readlink reads the link of `curproc'
- */
-int
-procfs_readlink(void *v)
-{
- struct vop_readlink_args *ap = v;
- char buf[16]; /* should be enough */
- int len;
-
- if (VTOPFS(ap->a_vp)->pfs_fileno == PROCFS_FILENO(0, Pcurproc))
- len = snprintf(buf, sizeof buf, "%ld", (long)curproc->p_pid);
- else if (VTOPFS(ap->a_vp)->pfs_fileno == PROCFS_FILENO(0, Pself))
- len = strlcpy(buf, "curproc", sizeof buf);
- else
- return (EINVAL);
- if (len == -1 || len >= sizeof buf)
- return (EINVAL);
-
- return (uiomove(buf, len, ap->a_uio));
-}
-
-/*
- * convert decimal ascii to pid_t
- */
-static pid_t
-atopid(const char *b, u_int len)
-{
- pid_t p = 0;
-
- while (len--) {
- char c = *b++;
- if (c < '0' || c > '9')
- return (NO_PID);
- p = 10 * p + (c - '0');
- if (p > PID_MAX)
- return (NO_PID);
- }
-
- return (p);
-}
-int
-procfs_poll(void *v)
-{
- struct vop_poll_args *ap = v;
-
- return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
-}