From 9e4b56e7645e08311590355824863ecf9f334f0c Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 22 Oct 2012 12:32:09 -0400 Subject: libthread: add threadspawnd R=rsc http://codereview.appspot.com/6742064 --- include/thread.h | 1 + man/man3/thread.3 | 11 +++++++++++ src/libthread/exec.c | 17 +++++++++++++---- src/libthread/threadimpl.h | 5 +++-- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/include/thread.h b/include/thread.h index 43c35bf3..c01cd516 100644 --- a/include/thread.h +++ b/include/thread.h @@ -175,6 +175,7 @@ long iowrite(Ioproc *io, int fd, void *a, long n); void threadexec(Channel*, int[3], char*, char *[]); void threadexecl(Channel*, int[3], char*, ...); int threadspawn(int[3], char*, char*[]); +int threadspawnd(int[3], char*, char*[], char*); int threadspawnl(int[3], char*, ...); Channel* threadwaitchan(void); diff --git a/man/man3/thread.3 b/man/man3/thread.3 index 7f5cd69c..0ebbddd0 100644 --- a/man/man3/thread.3 +++ b/man/man3/thread.3 @@ -42,6 +42,7 @@ threadsetgrp, threadsetname, threadsetstate, threadspawn, +threadspawnd, threadspawnl, threadwaitchan, yield \- thread and proc management @@ -124,6 +125,7 @@ int chanprint(Channel *c, char *fmt, ...) .XX int threadspawnl(int fd[3], char *file, ...) int threadspawn(int fd[3], char *file, char *args[]) +int threadspawnd(int fd[3], char *file, char *args[], char *dir) int threadexecl(Channel *cpid, int fd[3], char *file, ...) int threadexec(Channel *cpid, int fd[3], char *file, char *args[]) Channel* threadwaitchan(void) @@ -240,6 +242,8 @@ Calls that do this are .IR threadexecl , .IR threadexits , .IR threadspawn , +.IR threadspawnd , +.IR threadspawnl , .IR alt , .IR send , and @@ -419,6 +423,13 @@ and but do not replace the current thread. They return the pid of the invoked program on success, or \-1 on error. +.I Threadspawnd +is like +.I threadspawn +but takes as its final argument the directory in which to run the invoked program. +The child will attempt to change into that directory before running the program, +but it is only best effort: failure to change into the directory does not +stop the running of the program. .PP .I Threadwaitchan returns a channel of pointers to diff --git a/src/libthread/exec.c b/src/libthread/exec.c index 1875eb98..62805ba2 100644 --- a/src/libthread/exec.c +++ b/src/libthread/exec.c @@ -12,7 +12,7 @@ execproc(void *v) Waitmsg *w; e = v; - pid = _threadspawn(e->fd, e->cmd, e->argv); + pid = _threadspawn(e->fd, e->cmd, e->argv, e->dir); sendul(e->c, pid); if(pid > 0){ w = waitfor(pid); @@ -25,7 +25,7 @@ execproc(void *v) } int -_runthreadspawn(int *fd, char *cmd, char **argv) +_runthreadspawn(int *fd, char *cmd, char **argv, char *dir) { int pid; Execjob e; @@ -33,6 +33,7 @@ _runthreadspawn(int *fd, char *cmd, char **argv) e.fd = fd; e.cmd = cmd; e.argv = argv; + e.dir = dir; e.c = chancreate(sizeof(void*), 0); proccreate(execproc, &e, 65536); pid = recvul(e.c); @@ -57,7 +58,7 @@ threadwaitchan(void) } int -_threadspawn(int fd[3], char *cmd, char *argv[]) +_threadspawn(int fd[3], char *cmd, char *argv[], char *dir) { int i, n, p[2], pid; char exitstr[100]; @@ -77,6 +78,8 @@ _threadspawn(int fd[3], char *cmd, char *argv[]) return -1; case 0: /* can't RFNOTEG - will lose tty */ + if(dir != nil ) + chdir(dir); /* best effort */ dup2(fd[0], 0); dup2(fd[1], 1); dup2(fd[2], 2); @@ -112,7 +115,13 @@ _threadspawn(int fd[3], char *cmd, char *argv[]) int threadspawn(int fd[3], char *cmd, char *argv[]) { - return _runthreadspawn(fd, cmd, argv); + return _runthreadspawn(fd, cmd, argv, nil); +} + +int +threadspawnd(int fd[3], char *cmd, char *argv[], char *dir) +{ + return _runthreadspawn(fd, cmd, argv, dir); } int diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h index 9518f785..144a2136 100644 --- a/src/libthread/threadimpl.h +++ b/src/libthread/threadimpl.h @@ -121,6 +121,7 @@ struct Execjob int *fd; char *cmd; char **argv; + char *dir; Channel *c; }; @@ -203,8 +204,8 @@ extern void _threadsetproc(Proc*); extern int _threadlock(Lock*, int, ulong); extern void _threadunlock(Lock*, ulong); extern void _pthreadinit(void); -extern int _threadspawn(int*, char*, char**); -extern int _runthreadspawn(int*, char*, char**); +extern int _threadspawn(int*, char*, char**, char*); +extern int _runthreadspawn(int*, char*, char**, char*); extern void _threadsetupdaemonize(void); extern void _threaddodaemonize(char*); extern void _threadpexit(void); -- cgit v1.2.3