summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>1999-08-19 19:41:08 +0000
committermarcel <marcel@FreeBSD.org>1999-08-19 19:41:08 +0000
commit44e41869e36742b8a05e2d7ed3409e5dfcf76b06 (patch)
treea2c81fb806b78264ce708463c2c6c5c0643caa24 /sys/fs
parent4f537e1f79af81dbd74c8715df819754bd55091a (diff)
downloadFreeBSD-src-44e41869e36742b8a05e2d7ed3409e5dfcf76b06.zip
FreeBSD-src-44e41869e36742b8a05e2d7ed3409e5dfcf76b06.tar.gz
Let processes retrieve their argv through procfs. Revert to the original
behaviour in all other cases. Submitted by: Andrew Gordon <arg@arg1.demon.co.uk>
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/procfs/procfs_status.c49
1 files changed, 41 insertions, 8 deletions
diff --git a/sys/fs/procfs/procfs_status.c b/sys/fs/procfs/procfs_status.c
index d34e215..2c8cb69 100644
--- a/sys/fs/procfs/procfs_status.c
+++ b/sys/fs/procfs/procfs_status.c
@@ -37,7 +37,7 @@
* @(#)procfs_status.c 8.4 (Berkeley) 6/15/94
*
* From:
- * $Id: procfs_status.c,v 1.13 1999/04/28 11:37:20 phk Exp $
+ * $Id: procfs_status.c,v 1.14 1999/05/22 20:10:26 dt Exp $
*/
#include <sys/param.h>
@@ -49,6 +49,11 @@
#include <sys/resourcevar.h>
#include <miscfs/procfs/procfs.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_param.h>
+#include <sys/exec.h>
+
int
procfs_dostatus(curp, p, pfs, uio)
struct proc *curp;
@@ -160,19 +165,47 @@ procfs_docmdline(curp, p, pfs, uio)
int error;
char psbuf[256];
+ struct ps_strings pstr;
+ int i;
+ size_t bytes_left, done;
+
if (uio->uio_rw != UIO_READ)
return (EOPNOTSUPP);
/*
- * For now, this is a hack. To implement this fully would require
- * groping around in the process address space to follow argv etc.
+ * This is a hack: the correct behaviour is only implemented for
+ * the case of the current process enquiring about its own argv
+ * (due to the difficulty of accessing other processes' address space).
+ * For other cases, we cop out and just return argv[0] from p->p_comm.
+ * Note that if the argv is no longer available, we deliberately
+ * don't fall back on p->p_comm or return an error: the authentic
+ * Linux behaviour is to return zero-length in this case.
*/
- ps = psbuf;
- bcopy(p->p_comm, ps, MAXCOMLEN);
- ps[MAXCOMLEN] = '\0';
- ps += strlen(ps);
- ps += sprintf(ps, "\n");
+ if (curproc == p) {
+ error = copyin((void*)PS_STRINGS, &pstr, sizeof(pstr));
+ if (error)
+ return (error);
+ bytes_left = sizeof(psbuf);
+ ps = psbuf;
+ for (i = 0; bytes_left && (i < pstr.ps_nargvstr); i++) {
+ error = copyinstr(pstr.ps_argvstr[i], ps,
+ bytes_left, &done);
+ /* If too long or malformed, just truncate */
+ if (error) {
+ error = 0;
+ break;
+ }
+ ps += done;
+ bytes_left -= done;
+ }
+ }
+ else {
+ ps = psbuf;
+ bcopy(p->p_comm, ps, MAXCOMLEN);
+ ps[MAXCOMLEN] = '\0';
+ ps += strlen(ps);
+ }
xlen = ps - psbuf;
xlen -= uio->uio_offset;
OpenPOWER on IntegriCloud