diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-02-22 22:25:21 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-02-22 22:25:21 +0100 |
commit | 258fe87faf0a64947bb91c8ed93f8ea378a36f83 (patch) | |
tree | c0e683a2e9f080ac67f7fd6947483cde52deb4bd /sys/src/cmd/rc/haventfork.c | |
parent | a9639c68947a9872cacd8a9629df097fe009503b (diff) |
rc: terminate rc when exec fails, cleanup
The execexec() function should never return, as it irreversably changes
the filedescriptor table for the new program. This means rc's internal
filedesciptors for reading the script get implicitely closed and we cannot
continue the rc interpreter when Execute() fails. So Execute() now sets the
error status, and execexec() runs Xexit() in case Execute() returns.
Diffstat (limited to 'sys/src/cmd/rc/haventfork.c')
-rw-r--r-- | sys/src/cmd/rc/haventfork.c | 29 |
1 files changed, 13 insertions, 16 deletions
diff --git a/sys/src/cmd/rc/haventfork.c b/sys/src/cmd/rc/haventfork.c index aa97f5c58..1e5aa0dc9 100644 --- a/sys/src/cmd/rc/haventfork.c +++ b/sys/src/cmd/rc/haventfork.c @@ -189,30 +189,27 @@ execforkexec(void) { char **argv; char file[1024]; - int nc; + int nc, mc; word *path; int pid; if(runq->argv->words==0) return -1; argv = mkargv(runq->argv->words); - + mc = strlen(argv[1])+1; for(path = searchpath(runq->argv->words->word);path;path = path->next){ nc = strlen(path->word); - if(nc < sizeof file - 1){ /* 1 for / */ - strcpy(file, path->word); - if(file[0]){ - strcat(file, "/"); - nc++; - } - if(nc+strlen(argv[1])<sizeof(file)){ - strcat(file, argv[1]); - pid = ForkExecute(file, argv+1, mapfd(0), mapfd(1), mapfd(2)); - if(pid >= 0){ - free(argv); - return pid; - } - } + if(nc + mc >= sizeof file - 1) /* 1 for / */ + continue; + if(nc > 0){ + memmove(file, path->word, nc); + file[nc++] = '/'; + } + memmove(file+nc, argv[1], mc); + pid = ForkExecute(file, argv+1, mapfd(0), mapfd(1), mapfd(2)); + if(pid >= 0){ + free(argv); + return pid; } } free(argv); |