Add "cwd" and "root" symlinks to each process's directory. The cwd

link points to the process's current working directory, and the root
link points to the process's root directory.  What else would you
expect?

For directories that are out of reach (caller is in a chroot, target
process is in a different chroot, etc), the links point to "/"
instead.
This commit is contained in:
atatat 2005-10-01 03:17:37 +00:00
parent 97776d231d
commit fca6393ad4
4 changed files with 127 additions and 10 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: mount_procfs.8,v 1.26 2005/01/31 05:19:19 erh Exp $
.\" $NetBSD: mount_procfs.8,v 1.27 2005/10/01 03:17:37 atatat Exp $
.\"
.\" Copyright (c) 1992, 1993
.\" The Regents of the University of California. All rights reserved.
@ -130,6 +130,13 @@ prefix,
in which case that signal is delivered to the process
(see
.Xr sigaction 2 ) .
.It Pa cwd
A symbolic link that points to the current working directory of the
process.
If the target process's current working directory is not available or
is not at or below the current process's root directory, this link
will point to
.Dq / .
.It Pa file
A reference to the vnode from which the process text was read.
This can be used to gain access to the process' symbol table,
@ -169,6 +176,11 @@ in
.Pa fpregs
is only implemented on machines which have distinct general
purpose and floating point register sets.
.It Pa root
A symbolic link that points to the root directory of the process.
If the target process's root directory is not available or is not at
or below the current process's root directory, this link will point to
.Dq / .
.It Pa status
The process status.
This file is readonly and returns a single line containing

View File

@ -1,4 +1,4 @@
/* $NetBSD: procfs.h,v 1.57 2005/08/30 20:08:01 xtraeme Exp $ */
/* $NetBSD: procfs.h,v 1.58 2005/10/01 03:17:37 atatat Exp $ */
/*
* Copyright (c) 1993
@ -100,6 +100,8 @@ typedef enum {
PFSfd, /* a directory containing the processes open fd's */
PFSuptime, /* elapsed time since (if -o linux) */
PFSmounts, /* mounted filesystems (if -o linux) */
PFScwd, /* the process's current working directory */
PFSchroot, /* the process's current root directory */
#ifdef __HAVE_PROCFS_MACHDEP
PROCFS_MACHDEP_NODE_TYPES
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: procfs_subr.c,v 1.65 2005/08/30 20:08:01 xtraeme Exp $ */
/* $NetBSD: procfs_subr.c,v 1.66 2005/10/01 03:17:37 atatat Exp $ */
/*
* Copyright (c) 1993
@ -73,7 +73,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: procfs_subr.c,v 1.65 2005/08/30 20:08:01 xtraeme Exp $");
__KERNEL_RCSID(0, "$NetBSD: procfs_subr.c,v 1.66 2005/10/01 03:17:37 atatat Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -169,6 +169,8 @@ procfs_allocvp(mp, vpp, pid, pfs_type, fd)
case PFScurproc: /* /proc/curproc = lr-xr-xr-x */
case PFSself: /* /proc/self = lr-xr-xr-x */
case PFScwd: /* /proc/N/cwd = lr-xr-xr-x */
case PFSchroot: /* /proc/N/chroot = lr-xr-xr-x */
pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
vp->v_type = VLNK;
break;

View File

@ -1,4 +1,4 @@
/* $NetBSD: procfs_vnops.c,v 1.125 2005/09/11 20:15:53 elad Exp $ */
/* $NetBSD: procfs_vnops.c,v 1.126 2005/10/01 03:17:37 atatat Exp $ */
/*
* Copyright (c) 1993, 1995
@ -76,7 +76,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.125 2005/09/11 20:15:53 elad Exp $");
__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.126 2005/10/01 03:17:37 atatat Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -109,6 +109,8 @@ __KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.125 2005/09/11 20:15:53 elad Exp
static int procfs_validfile_linux(struct proc *, struct mount *);
static int procfs_root_readdir_callback(struct proc *, void *);
static struct vnode *procfs_dir(pfstype, struct proc *, struct proc *,
char **, char *, int);
/*
* This is a list of the valid names in the
@ -140,6 +142,8 @@ static const struct proc_target {
{ DT_REG, N("maps"), PFSmaps, procfs_validmap },
{ DT_REG, N("cmdline"), PFScmdline, NULL },
{ DT_REG, N("exe"), PFSfile, procfs_validfile_linux },
{ DT_LNK, N("cwd"), PFScwd, NULL },
{ DT_LNK, N("root"), PFSchroot, NULL },
#ifdef __HAVE_PROCFS_MACHDEP
PROCFS_MACHDEP_NODETYPE_DEFNS
#endif
@ -487,6 +491,50 @@ procfs_symlink(v)
return (EROFS);
}
/*
* Works out the path to (and vnode of) the target process's current
* working directory or chroot. If the caller is in a chroot and
* can't "reach" the target's cwd or root (or some other error
* occurs), a "/" is returned for the path and a NULL pointer is
* returned for the vnode.
*/
static struct vnode *
procfs_dir(pfstype t, struct proc *caller, struct proc *target,
char **bpp, char *path, int len)
{
struct vnode *vp, *rvp = caller->p_cwdi->cwdi_rdir;
char *bp;
bp = bpp ? *bpp : NULL;
switch (t) {
case PFScwd:
vp = target->p_cwdi->cwdi_cdir;
break;
case PFSchroot:
vp = target->p_cwdi->cwdi_rdir;
break;
default:
return (NULL);
}
if (rvp == NULL)
rvp = rootvnode;
if (vp == NULL || getcwd_common(vp, rvp, bp ? &bp : NULL, path,
len / 2, 0, caller) != 0) {
vp = NULL;
if (bpp) {
bp = *bpp;
*--bp = '/';
}
}
if (bpp)
*bpp = bp;
return (vp);
}
/*
* Invent attributes for pfsnode (vp) and store
* them in (vap).
@ -550,13 +598,18 @@ procfs_getattr(v)
* don't actually need to be THAT sure the access is atomic.
*
* It would be possible to get the process start
* time from the p_stat structure, but there's
* time from the p_stats structure, but there's
* no "file creation" time stamp anyway, and the
* p_stat structure is not addressible if u. gets
* p_stats structure is not addressable if u. gets
* swapped out for that process.
*/
TIMEVAL_TO_TIMESPEC(&time, &vap->va_ctime);
vap->va_atime = vap->va_mtime = vap->va_ctime;
if (procp)
TIMEVAL_TO_TIMESPEC(&procp->p_stats->p_start,
&vap->va_birthtime);
else
TIMEVAL_TO_TIMESPEC(&boottime, &vap->va_birthtime);
switch (pfs->pfs_type) {
case PFSmem:
@ -711,6 +764,26 @@ procfs_getattr(v)
vap->va_bytes = vap->va_size = 0;
break;
case PFScwd:
case PFSchroot: {
char *path, *bp;
MALLOC(path, char *, MAXPATHLEN + 4, M_TEMP,
M_WAITOK|M_CANFAIL);
if (path == NULL)
return (ENOMEM);
vap->va_nlink = 1;
vap->va_uid = 0;
vap->va_gid = 0;
bp = path + MAXPATHLEN;
*--bp = '\0';
(void)procfs_dir(pfs->pfs_type, curproc, procp, &bp, path,
MAXPATHLEN);
vap->va_bytes = vap->va_size = strlen(bp);
free(path, M_TEMP);
break;
}
#ifdef __HAVE_PROCFS_MACHDEP
PROCFS_MACHDEP_NODETYPE_CASES
error = procfs_machdep_getattr(ap->a_vp, vap, procp);
@ -1332,7 +1405,7 @@ procfs_readdir(v)
}
/*
* readlink reads the link of `curproc'
* readlink reads the link of `curproc' and others
*/
int
procfs_readlink(v)
@ -1345,14 +1418,42 @@ procfs_readlink(v)
int len;
int error = 0;
struct pfsnode *pfs = VTOPFS(ap->a_vp);
struct proc *pown;
if (pfs->pfs_fileno == PROCFS_FILENO(0, PFScurproc, -1))
len = snprintf(bf, sizeof(bf), "%ld", (long)curproc->p_pid);
else if (pfs->pfs_fileno == PROCFS_FILENO(0, PFSself, -1))
len = snprintf(bf, sizeof(bf), "%s", "curproc");
else if (pfs->pfs_fileno == PROCFS_FILENO(pfs->pfs_pid, PFScwd, -1)) {
pown = PFIND(pfs->pfs_pid);
if (pown == NULL)
return (ESRCH);
MALLOC(path, char *, MAXPATHLEN + 4, M_TEMP,
M_WAITOK|M_CANFAIL);
if (path == NULL)
return (ENOMEM);
bp = path + MAXPATHLEN;
*--bp = '\0';
(void)procfs_dir(PFScwd, curproc, pown, &bp, path,
MAXPATHLEN);
len = strlen(bp);
}
else if (pfs->pfs_fileno == PROCFS_FILENO(pfs->pfs_pid, PFSchroot, -1)) {
pown = PFIND(pfs->pfs_pid);
if (pown == NULL)
return (ESRCH);
MALLOC(path, char *, MAXPATHLEN + 4, M_TEMP,
M_WAITOK|M_CANFAIL);
if (path == NULL)
return (ENOMEM);
bp = path + MAXPATHLEN;
*--bp = '\0';
(void)procfs_dir(PFSchroot, curproc, pown, &bp, path,
MAXPATHLEN);
len = strlen(bp);
}
else {
struct file *fp;
struct proc *pown;
struct vnode *vxp, *vp;
if ((error = procfs_getfp(pfs, &pown, &fp)) != 0)