libthread: add threadspawnd

R=rsc
http://codereview.appspot.com/6742064
This commit is contained in:
Russ Cox 2012-10-22 12:32:09 -04:00
parent 81c2c5e775
commit 9e4b56e764
4 changed files with 28 additions and 6 deletions

View file

@ -175,6 +175,7 @@ long iowrite(Ioproc *io, int fd, void *a, long n);
void threadexec(Channel*, int[3], char*, char *[]); void threadexec(Channel*, int[3], char*, char *[]);
void threadexecl(Channel*, int[3], char*, ...); void threadexecl(Channel*, int[3], char*, ...);
int threadspawn(int[3], char*, char*[]); int threadspawn(int[3], char*, char*[]);
int threadspawnd(int[3], char*, char*[], char*);
int threadspawnl(int[3], char*, ...); int threadspawnl(int[3], char*, ...);
Channel* threadwaitchan(void); Channel* threadwaitchan(void);

View file

@ -42,6 +42,7 @@ threadsetgrp,
threadsetname, threadsetname,
threadsetstate, threadsetstate,
threadspawn, threadspawn,
threadspawnd,
threadspawnl, threadspawnl,
threadwaitchan, threadwaitchan,
yield \- thread and proc management yield \- thread and proc management
@ -124,6 +125,7 @@ int chanprint(Channel *c, char *fmt, ...)
.XX .XX
int threadspawnl(int fd[3], char *file, ...) int threadspawnl(int fd[3], char *file, ...)
int threadspawn(int fd[3], char *file, char *args[]) 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 threadexecl(Channel *cpid, int fd[3], char *file, ...)
int threadexec(Channel *cpid, int fd[3], char *file, char *args[]) int threadexec(Channel *cpid, int fd[3], char *file, char *args[])
Channel* threadwaitchan(void) Channel* threadwaitchan(void)
@ -240,6 +242,8 @@ Calls that do this are
.IR threadexecl , .IR threadexecl ,
.IR threadexits , .IR threadexits ,
.IR threadspawn , .IR threadspawn ,
.IR threadspawnd ,
.IR threadspawnl ,
.IR alt , .IR alt ,
.IR send , .IR send ,
and and
@ -419,6 +423,13 @@ and
but do not replace the current thread. but do not replace the current thread.
They return the pid of the invoked program on success, or They return the pid of the invoked program on success, or
\-1 on error. \-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 .PP
.I Threadwaitchan .I Threadwaitchan
returns a channel of pointers to returns a channel of pointers to

View file

@ -12,7 +12,7 @@ execproc(void *v)
Waitmsg *w; Waitmsg *w;
e = v; e = v;
pid = _threadspawn(e->fd, e->cmd, e->argv); pid = _threadspawn(e->fd, e->cmd, e->argv, e->dir);
sendul(e->c, pid); sendul(e->c, pid);
if(pid > 0){ if(pid > 0){
w = waitfor(pid); w = waitfor(pid);
@ -25,7 +25,7 @@ execproc(void *v)
} }
int int
_runthreadspawn(int *fd, char *cmd, char **argv) _runthreadspawn(int *fd, char *cmd, char **argv, char *dir)
{ {
int pid; int pid;
Execjob e; Execjob e;
@ -33,6 +33,7 @@ _runthreadspawn(int *fd, char *cmd, char **argv)
e.fd = fd; e.fd = fd;
e.cmd = cmd; e.cmd = cmd;
e.argv = argv; e.argv = argv;
e.dir = dir;
e.c = chancreate(sizeof(void*), 0); e.c = chancreate(sizeof(void*), 0);
proccreate(execproc, &e, 65536); proccreate(execproc, &e, 65536);
pid = recvul(e.c); pid = recvul(e.c);
@ -57,7 +58,7 @@ threadwaitchan(void)
} }
int 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; int i, n, p[2], pid;
char exitstr[100]; char exitstr[100];
@ -77,6 +78,8 @@ _threadspawn(int fd[3], char *cmd, char *argv[])
return -1; return -1;
case 0: case 0:
/* can't RFNOTEG - will lose tty */ /* can't RFNOTEG - will lose tty */
if(dir != nil )
chdir(dir); /* best effort */
dup2(fd[0], 0); dup2(fd[0], 0);
dup2(fd[1], 1); dup2(fd[1], 1);
dup2(fd[2], 2); dup2(fd[2], 2);
@ -112,7 +115,13 @@ _threadspawn(int fd[3], char *cmd, char *argv[])
int int
threadspawn(int fd[3], char *cmd, char *argv[]) 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 int

View file

@ -121,6 +121,7 @@ struct Execjob
int *fd; int *fd;
char *cmd; char *cmd;
char **argv; char **argv;
char *dir;
Channel *c; Channel *c;
}; };
@ -203,8 +204,8 @@ extern void _threadsetproc(Proc*);
extern int _threadlock(Lock*, int, ulong); extern int _threadlock(Lock*, int, ulong);
extern void _threadunlock(Lock*, ulong); extern void _threadunlock(Lock*, ulong);
extern void _pthreadinit(void); extern void _pthreadinit(void);
extern int _threadspawn(int*, char*, char**); extern int _threadspawn(int*, char*, char**, char*);
extern int _runthreadspawn(int*, char*, char**); extern int _runthreadspawn(int*, char*, char**, char*);
extern void _threadsetupdaemonize(void); extern void _threadsetupdaemonize(void);
extern void _threaddodaemonize(char*); extern void _threaddodaemonize(char*);
extern void _threadpexit(void); extern void _threadpexit(void);