diff options
author | jasoni <jasoni@cvs.openbsd.org> | 2000-08-12 04:29:25 +0000 |
---|---|---|
committer | jasoni <jasoni@cvs.openbsd.org> | 2000-08-12 04:29:25 +0000 |
commit | 425b4a2edc12954026ad361688bdcc279aa67e2c (patch) | |
tree | a88c6ed69c10b982e02c49a7abaa0363a08fa230 /sys/miscfs | |
parent | 5a9a2b68f6517ae67b78d59352cf81d7d0bd878a (diff) |
Add procfs/cmdline; to help with linux emulation.
From NetBSD.
Diffstat (limited to 'sys/miscfs')
-rw-r--r-- | sys/miscfs/procfs/procfs.h | 6 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_cmdline.c | 215 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_subr.c | 6 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_vnops.c | 7 |
4 files changed, 230 insertions, 4 deletions
diff --git a/sys/miscfs/procfs/procfs.h b/sys/miscfs/procfs/procfs.h index 5741a9349df..397872f18e5 100644 --- a/sys/miscfs/procfs/procfs.h +++ b/sys/miscfs/procfs/procfs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: procfs.h,v 1.8 1997/11/06 05:58:42 csapuntz Exp $ */ +/* $OpenBSD: procfs.h,v 1.9 2000/08/12 04:29:24 jasoni Exp $ */ /* $NetBSD: procfs.h,v 1.17 1996/02/12 15:01:41 christos Exp $ */ /* @@ -54,7 +54,8 @@ typedef enum { Pctl, /* process control */ Pstatus, /* process status */ Pnote, /* process notifier */ - Pnotepg /* process group notifier */ + Pnotepg, /* process group notifier */ + Pcmdline /* process command line args */ } pfstype; /* @@ -112,6 +113,7 @@ int procfs_domem __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct int procfs_donote __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); int procfs_doregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); int procfs_dostatus __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int procfs_docmdline __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); struct vnode *procfs_findtextvp __P((struct proc *)); int procfs_freevp __P((struct vnode *)); diff --git a/sys/miscfs/procfs/procfs_cmdline.c b/sys/miscfs/procfs/procfs_cmdline.c new file mode 100644 index 00000000000..0189e3e9c28 --- /dev/null +++ b/sys/miscfs/procfs/procfs_cmdline.c @@ -0,0 +1,215 @@ +/* $OpenBSD: procfs_cmdline.c,v 1.1 2000/08/12 04:29:24 jasoni 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> +#include <vm/vm.h> + +#if defined(UVM) +#include <uvm/uvm_extern.h> +#endif + +/* + * code for returning process's command line arguments + */ +int +procfs_docmdline(curp, p, pfs, uio) + struct proc *curp; + struct proc *p; + struct pfsnode *pfs; + struct uio *uio; +{ + struct ps_strings pss; + int count, error, i; + size_t len, xlen, upper_bound; + struct uio auio; + struct iovec aiov; + 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 (P_ZOMBIE(p) || (p->p_flag & P_SYSTEM) != 0) { + len = snprintf(arg, PAGE_SIZE, "(%s)", p->p_comm); + xlen = len - uio->uio_offset; + if (xlen <= 0) + error = 0; + else + error = uiomove(arg, xlen, uio); + + free(arg, M_TEMP); + return (error); + } + + /* + * NOTE: Don't bother doing a procfs_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. + */ +#if defined(UVM) + /* XXXCDC: how should locking work here? */ + if ((p->p_flag & P_WEXIT) || (p->p_vmspace->vm_refcnt < 1)) { + free(arg, M_TEMP); + return (EFAULT); + } + PHOLD(p); + p->p_vmspace->vm_refcnt++; /* XXX */ +#else + PHOLD(p); +#endif + + /* + * 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; +#if defined(UVM) + error = uvm_io(&p->p_vmspace->vm_map, &auio); +#else + error = procfs_rwmem(p, &auio); +#endif + 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; +#if defined(UVM) + error = uvm_io(&p->p_vmspace->vm_map, &auio); +#else + error = procfs_rwmem(p, &auio); +#endif + 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; +#if defined(UVM) + error = uvm_io(&p->p_vmspace->vm_map, &auio); +#else + error = procfs_rwmem(p, &auio); +#endif + 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: +#if defined(UVM) + PRELE(p); + uvmspace_free(p->p_vmspace); +#else + PRELE(p); +#endif + free(arg, M_TEMP); + return (error); +} diff --git a/sys/miscfs/procfs/procfs_subr.c b/sys/miscfs/procfs/procfs_subr.c index 46642a7c980..2c98efb0a8b 100644 --- a/sys/miscfs/procfs/procfs_subr.c +++ b/sys/miscfs/procfs/procfs_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: procfs_subr.c,v 1.11 1997/11/06 05:58:43 csapuntz Exp $ */ +/* $OpenBSD: procfs_subr.c,v 1.12 2000/08/12 04:29:24 jasoni Exp $ */ /* $NetBSD: procfs_subr.c,v 1.15 1996/02/12 15:01:42 christos Exp $ */ /* @@ -172,6 +172,7 @@ loop: break; case Pstatus: /* /proc/N/status = -r--r--r-- */ + case Pcmdline: pfs->pfs_mode = S_IRUSR|S_IRGRP|S_IROTH; vp->v_type = VREG; break; @@ -244,6 +245,9 @@ procfs_rw(v) case Pmem: return (procfs_domem(curp, p, pfs, uio)); + case Pcmdline: + return (procfs_docmdline(curp, p, pfs, uio)); + default: return (EOPNOTSUPP); } diff --git a/sys/miscfs/procfs/procfs_vnops.c b/sys/miscfs/procfs/procfs_vnops.c index 3472f7c6437..1b70e078403 100644 --- a/sys/miscfs/procfs/procfs_vnops.c +++ b/sys/miscfs/procfs/procfs_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: procfs_vnops.c,v 1.14 1999/08/13 07:05:46 csapuntz Exp $ */ +/* $OpenBSD: procfs_vnops.c,v 1.15 2000/08/12 04:29:24 jasoni Exp $ */ /* $NetBSD: procfs_vnops.c,v 1.40 1996/03/16 23:52:55 christos Exp $ */ /* @@ -93,6 +93,7 @@ struct proc_target { { DT_REG, N("status"), Pstatus, NULL }, { DT_REG, N("note"), Pnote, NULL }, { DT_REG, N("notepg"), Pnotepg, NULL }, + { DT_REG, N("cmdline"), Pcmdline, NULL }, #undef N }; static int nproc_targets = sizeof(proc_targets) / sizeof(proc_targets[0]); @@ -278,6 +279,7 @@ procfs_close(v) case Pfile: case Pregs: case Pfpregs: + case Pcmdline: break; } @@ -555,6 +557,7 @@ procfs_getattr(v) 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; @@ -631,6 +634,8 @@ procfs_getattr(v) case Pstatus: case Pnote: case Pnotepg: + case Pcmdline: + vap->va_bytes = vap->va_size = 0; break; default: |