summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libc/gen/sysctl.39
-rw-r--r--sys/kern/kern_sysctl.c68
-rw-r--r--sys/kern/vfs_getcwd.c4
-rw-r--r--sys/sys/sysctl.h6
-rw-r--r--sys/sys/vnode.h3
5 files changed, 81 insertions, 9 deletions
diff --git a/lib/libc/gen/sysctl.3 b/lib/libc/gen/sysctl.3
index 0c0f7090c94..e9bed504790 100644
--- a/lib/libc/gen/sysctl.3
+++ b/lib/libc/gen/sysctl.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sysctl.3,v 1.209 2011/09/25 17:48:17 jmc Exp $
+.\" $OpenBSD: sysctl.3,v 1.210 2011/12/09 16:14:54 nicm Exp $
.\"
.\" Copyright (c) 1993
.\" The Regents of the University of California. All rights reserved.
@@ -27,7 +27,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd $Mdocdate: September 25 2011 $
+.Dd $Mdocdate: December 9 2011 $
.Dt SYSCTL 3
.Os
.Sh NAME
@@ -458,6 +458,7 @@ information.
.It Dv KERN_POSIX1 Ta "integer" Ta "no"
.It Dv KERN_PROC Ta "struct kinfo_proc" Ta "no"
.It Dv KERN_PROC_ARGS Ta "node" Ta "not applicable"
+.It Dv KERN_PROC_CWD Ta "string" Ta "not applicable"
.It Dv KERN_PROF Ta "node" Ta "not applicable"
.It Dv KERN_RAWPARTITION Ta "integer" Ta "no"
.It Dv KERN_RND Ta "struct rndstats" Ta "no"
@@ -762,6 +763,10 @@ followed by the strings themselves.
The last char pointer is a
.Dv NULL
pointer.
+.It Dv KERN_PROC_CWD
+Return the current working directory of a process.
+The third level name is the target process ID.
+A NUL-terminated string is returned.
.It Dv KERN_PROF
Return profiling information about the kernel.
If the kernel is not compiled for profiling,
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 780a79da71c..4e964d0008c 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sysctl.c,v 1.208 2011/09/18 13:23:38 miod Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.209 2011/12/09 16:14:54 nicm Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
@@ -117,6 +117,7 @@ extern void nmbclust_update(void);
int sysctl_diskinit(int, struct proc *);
int sysctl_proc_args(int *, u_int, void *, size_t *, struct proc *);
+int sysctl_proc_cwd(int *, u_int, void *, size_t *, struct proc *);
int sysctl_intrcnt(int *, u_int, void *, size_t *);
int sysctl_sensors(int *, u_int, void *, size_t *, void *, size_t);
int sysctl_emul(int *, u_int, void *, size_t *, void *, size_t);
@@ -282,6 +283,7 @@ kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
case KERN_TTY:
case KERN_POOL:
case KERN_PROC_ARGS:
+ case KERN_PROC_CWD:
case KERN_SYSVIPC_INFO:
case KERN_SEMINFO:
case KERN_SHMINFO:
@@ -367,6 +369,9 @@ kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
case KERN_PROC_ARGS:
return (sysctl_proc_args(name + 1, namelen - 1, oldp, oldlenp,
p));
+ case KERN_PROC_CWD:
+ return (sysctl_proc_cwd(name + 1, namelen - 1, oldp, oldlenp,
+ p));
case KERN_FILE2:
return (sysctl_file2(name + 1, namelen - 1, oldp, oldlenp, p));
#endif
@@ -1719,6 +1724,67 @@ out:
return (error);
}
+int
+sysctl_proc_cwd(int *name, u_int namelen, void *oldp, size_t *oldlenp,
+ struct proc *cp)
+{
+ struct proc *findp;
+ pid_t pid;
+ int error;
+ size_t lenused, len;
+ char *path, *bp, *bend;
+
+ if (namelen > 1)
+ return (ENOTDIR);
+ if (namelen < 1)
+ return (EINVAL);
+
+ pid = name[0];
+ if ((findp = pfind(pid)) == NULL)
+ return (ESRCH);
+
+ if (oldp == NULL) {
+ *oldlenp = MAXPATHLEN * 4;
+ return (0);
+ }
+
+ if (P_ZOMBIE(findp) || (findp->p_flag & P_SYSTEM))
+ return (EINVAL);
+
+ /* Only owner or root can get cwd */
+ if (findp->p_ucred->cr_uid != cp->p_ucred->cr_uid &&
+ (error = suser(cp, 0)) != 0)
+ return (error);
+
+ /* Exiting - don't bother, it will be gone soon anyway */
+ if (findp->p_flag & P_WEXIT)
+ return (ESRCH);
+
+ len = *oldlenp;
+ if (len > MAXPATHLEN * 4)
+ len = MAXPATHLEN * 4;
+ else if (len < 2)
+ return (ERANGE);
+ *oldlenp = 0;
+
+ path = malloc(len, M_TEMP, M_WAITOK);
+
+ bp = &path[len];
+ bend = bp;
+ *(--bp) = '\0';
+
+ /* Same as sys__getcwd */
+ error = vfs_getcwd_common(findp->p_fd->fd_cdir, NULL,
+ &bp, path, len / 2, GETCWD_CHECK_ACCESS, cp);
+ if (error == 0) {
+ *oldlenp = lenused = bend - bp;
+ error = copyout(bp, oldp, lenused);
+ }
+
+ free(path, M_TEMP);
+
+ return (error);
+}
#endif
/*
diff --git a/sys/kern/vfs_getcwd.c b/sys/kern/vfs_getcwd.c
index 4639dea989e..416a52044a5 100644
--- a/sys/kern/vfs_getcwd.c
+++ b/sys/kern/vfs_getcwd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_getcwd.c,v 1.17 2010/05/19 08:31:23 thib Exp $ */
+/* $OpenBSD: vfs_getcwd.c,v 1.18 2011/12/09 16:14:54 nicm Exp $ */
/* $NetBSD: vfs_getcwd.c,v 1.3.2.3 1999/07/11 10:24:09 sommerfeld Exp $ */
/*
@@ -260,8 +260,6 @@ vfs_getcwd_getcache(struct vnode **lvpp, struct vnode **uvpp, char **bpp,
return (error);
}
-#define GETCWD_CHECK_ACCESS 0x0001
-
/* Common routine shared by sys___getcwd() and vn_isunder() */
int
vfs_getcwd_common(struct vnode *lvp, struct vnode *rvp, char **bpp, char *bufp,
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index 4661df7a5c8..b7d220f605b 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysctl.h,v 1.117 2011/08/30 01:09:29 guenther Exp $ */
+/* $OpenBSD: sysctl.h,v 1.118 2011/12/09 16:14:54 nicm Exp $ */
/* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */
/*
@@ -189,7 +189,8 @@ struct ctlname {
#define KERN_CONSDEV 75 /* dev_t: console terminal device */
#define KERN_NETLIVELOCKS 76 /* int: number of network livelocks */
#define KERN_POOL_DEBUG 77 /* int: enable pool_debug */
-#define KERN_MAXID 78 /* number of valid kern ids */
+#define KERN_PROC_CWD 78 /* node: proc cwd */
+#define KERN_MAXID 79 /* number of valid kern ids */
#define CTL_KERN_NAMES { \
{ 0, 0 }, \
@@ -270,6 +271,7 @@ struct ctlname {
{ "consdev", CTLTYPE_STRUCT }, \
{ "netlivelocks", CTLTYPE_INT }, \
{ "pool_debug", CTLTYPE_INT }, \
+ { "proc_cwd", CTLTYPE_NODE }, \
}
/*
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 02572eca367..ff5c091428a 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vnode.h,v 1.109 2011/04/05 14:34:16 thib Exp $ */
+/* $OpenBSD: vnode.h,v 1.110 2011/12/09 16:14:54 nicm Exp $ */
/* $NetBSD: vnode.h,v 1.38 1996/02/29 20:59:05 cgd Exp $ */
/*
@@ -623,6 +623,7 @@ void vprint(char *, struct vnode *);
void copy_statfs_info(struct statfs *, const struct mount *);
/* vfs_getcwd.c */
+#define GETCWD_CHECK_ACCESS 0x0001
int vfs_getcwd_scandir(struct vnode **, struct vnode **, char **, char *,
struct proc *);
int vfs_getcwd_common(struct vnode *, struct vnode *, char **, char *, int,