@@ 9,6 9,7 @@
enum
{
Qctl,
+ Qargs,
Qdir,
Qfd,
Qfpregs,
@@ 30,6 31,7 @@ enum
#define STATSIZE (2*NAMELEN+12+9*12)
Dirtab procdir[] =
{
+ "args", {Qargs}, 0, 0440,
"ctl", {Qctl}, 0, 0000,
"fd", {Qfd}, 0, 0000,
"fpregs", {Qfpregs}, sizeof(FPsave), 0000,
@@ 233,6 235,7 @@ procopen(Chan *c, int omode)
error(Eperm);
break;
+ case Qargs:
case Qctl:
case Qnote:
case Qnoteid:
@@ 405,6 408,28 @@ int2flag(int flag, char *s)
*s = '\0';
}
+static int
+procargs(Proc *p, char *buf, int nbuf)
+{
+ int j, k, m;
+ char *a;
+ int n;
+
+ a = p->args;
+ n = p->nargs;
+ for(j = 0; j < nbuf - 1; j += m){
+ if(n == 0)
+ break;
+ if(j != 0)
+ buf[j++] = ' ';
+ m = snprint(buf+j, nbuf-j, "%q", a);
+ k = strlen(a) + 1;
+ a += k;
+ n -= k;
+ }
+ return j;
+}
+
static long
procread(Chan *c, void *va, long n, vlong off)
{
@@ 428,6 453,15 @@ procread(Chan *c, void *va, long n, vlong off)
error(Eprocdied);
switch(QID(c->qid)){
+ case Qargs:
+ j = procargs(p, statbuf, sizeof statbuf);
+ if(offset >= j)
+ return 0;
+ if(offset+n > j)
+ n = j-offset;
+ memmove(a, &statbuf[offset], n);
+ return n;
+
case Qmem:
if(offset < KZERO
|| (offset >= USTKTOP-USTKSIZE && offset < USTKTOP))
@@ 534,6 534,8 @@ struct Proc
Mach *mach; /* machine running this proc */
char text[NAMELEN];
char user[NAMELEN];
+ char *args;
+ int nargs; /* number of bytes of args */
Proc *rnext; /* next process in run queue */
Proc *qnext; /* next process on queue for a QLock */
QLock *qlock; /* addrof qlock being queued for DEBUG */
@@ 753,6 755,7 @@ extern int nsyscall;
#pragma varargck type "e" double
#pragma varargck type "g" double
#pragma varargck type "s" char*
+#pragma varargck type "q" char*
#pragma varargck type "S" Rune*
#pragma varargck type "r" void
#pragma varargck type "%" void
@@ 214,7 214,7 @@ sysexec(ulong *arg)
int i;
Chan *tc;
char **argv, **argp;
- char *a, *charp, *file;
+ char *a, *charp, *args, *file;
char *progarg[sizeof(Exec)/2+1], elem[NAMELEN];
ulong ssize, spage, nargs, nbytes, n, bssend;
int indir;
@@ 334,6 334,7 @@ sysexec(ulong *arg)
*/
argv = (char**)(TSTKTOP - ssize);
charp = (char*)(TSTKTOP - nbytes);
+ args = charp;
if(indir)
argp = progarg;
else
@@ 352,6 353,26 @@ sysexec(ulong *arg)
memmove(up->text, elem, NAMELEN);
+ /* copy args; easiest from new process's stack */
+ n = charp - args;
+ if(n > 128) /* don't waste too much space on huge arg lists */
+ n = 128;
+ a = up->args;
+ up->args = nil;
+ free(a);
+ up->args = smalloc(n);
+ memmove(up->args, args, n);
+ if(n>0 && up->args[n-1]!='\0'){
+ /* make sure last arg is NUL-terminated */
+ /* put NUL at UTF-8 character boundary */
+ for(i=n-1; i>0; --i)
+ if(fullrune(up->args+i, n-i))
+ break;
+ up->args[i] = 0;
+ n = i+1;
+ }
+ up->nargs = n;
+
/*
* Committed.
* Free old memory.