mirror of
https://github.com/golang/go
synced 2024-11-25 22:17:58 -07:00
add directory argument to os.ForkExec
R=iant DELTA=41 (35 added, 0 deleted, 6 changed) OCL=28892 CL=28895
This commit is contained in:
parent
a854c7f993
commit
b725e32c99
@ -96,7 +96,7 @@ func Run(argv0 string, argv, envv []string, stdin, stdout, stderr int) (p *Cmd,
|
||||
}
|
||||
|
||||
// Run command.
|
||||
p.Pid, err = os.ForkExec(argv0, argv, envv, &fd);
|
||||
p.Pid, err = os.ForkExec(argv0, argv, envv, "", &fd);
|
||||
if err != nil {
|
||||
goto Error;
|
||||
}
|
||||
|
@ -15,7 +15,8 @@ import (
|
||||
// file descriptors to be set up in the new process: fd[0] will be Unix file
|
||||
// descriptor 0 (standard input), fd[1] descriptor 1, and so on. A nil entry
|
||||
// will cause the child to have no open file descriptor with that index.
|
||||
func ForkExec(argv0 string, argv []string, envv []string, fd []*File)
|
||||
// If dir is not empty, the child chdirs into the directory before execing the program.
|
||||
func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []*File)
|
||||
(pid int, err Error)
|
||||
{
|
||||
// Create array of integer (system) fds.
|
||||
@ -28,7 +29,7 @@ func ForkExec(argv0 string, argv []string, envv []string, fd []*File)
|
||||
}
|
||||
}
|
||||
|
||||
p, e := syscall.ForkExec(argv0, argv, envv, intfd);
|
||||
p, e := syscall.ForkExec(argv0, argv, envv, dir, intfd);
|
||||
return int(p), ErrnoToError(e);
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ package os
|
||||
|
||||
import (
|
||||
"fmt";
|
||||
"io";
|
||||
"os";
|
||||
"testing";
|
||||
)
|
||||
@ -299,3 +300,24 @@ func TestLongSymlink(t *testing.T) {
|
||||
t.Fatalf("after symlink %q != %q", r, s);
|
||||
}
|
||||
}
|
||||
|
||||
func TestForkExec(t *testing.T) {
|
||||
r, w, err := Pipe();
|
||||
if err != nil {
|
||||
t.Fatalf("Pipe: %v", err);
|
||||
}
|
||||
pid, err := ForkExec("/bin/pwd", []string{"pwd"}, nil, "/", []*File{nil, w, os.Stderr});
|
||||
if err != nil {
|
||||
t.Fatalf("ForkExec: %v", err);
|
||||
}
|
||||
w.Close();
|
||||
|
||||
var b io.ByteBuffer;
|
||||
io.Copy(r, &b);
|
||||
output := string(b.Data());
|
||||
expect := "/\n";
|
||||
if output != expect {
|
||||
t.Errorf("exec /bin/pwd returned %q wanted %q", output, expect);
|
||||
}
|
||||
Wait(pid, 0);
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ func Wait4(pid int64, wstatus *WaitStatus, options int64, rusage *Rusage)
|
||||
// no rescheduling, no malloc calls, and no new stack segments.
|
||||
// The calls to RawSyscall are okay because they are assembly
|
||||
// functions that do not grow the stack.
|
||||
func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, fd []int64, pipe int64)
|
||||
func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, dir *byte, fd []int64, pipe int64)
|
||||
(pid int64, err int64)
|
||||
{
|
||||
// Declare all variables at top in case any
|
||||
@ -132,6 +132,14 @@ func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, fd []int64, pip
|
||||
|
||||
// Fork succeeded, now in child.
|
||||
|
||||
// Chdir
|
||||
if dir != nil {
|
||||
r1, r2, err = RawSyscall(SYS_CHDIR, int64(uintptr(unsafe.Pointer(dir))), 0, 0);
|
||||
if err != 0 {
|
||||
goto childerror;
|
||||
}
|
||||
}
|
||||
|
||||
// Pass 1: look for fd[i] < i and move those up above len(fd)
|
||||
// so that pass 2 won't stomp on an fd it needs later.
|
||||
nextfd = int64(len(fd));
|
||||
@ -210,7 +218,7 @@ childerror:
|
||||
}
|
||||
|
||||
// Combination of fork and exec, careful to be thread safe.
|
||||
func ForkExec(argv0 string, argv []string, envv []string, fd []int64)
|
||||
func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int64)
|
||||
(pid int64, err int64)
|
||||
{
|
||||
var p [2]int64;
|
||||
@ -225,6 +233,10 @@ func ForkExec(argv0 string, argv []string, envv []string, fd []int64)
|
||||
argv0p := StringBytePtr(argv0);
|
||||
argvp := StringArrayPtr(argv);
|
||||
envvp := StringArrayPtr(envv);
|
||||
var dirp *byte;
|
||||
if len(dir) > 0 {
|
||||
dirp = StringBytePtr(dir);
|
||||
}
|
||||
|
||||
// Acquire the fork lock so that no other threads
|
||||
// create new fds that are not yet close-on-exec
|
||||
@ -243,7 +255,7 @@ func ForkExec(argv0 string, argv []string, envv []string, fd []int64)
|
||||
}
|
||||
|
||||
// Kick off child.
|
||||
pid, err = forkAndExecInChild(argv0p, argvp, envvp, fd, p[1]);
|
||||
pid, err = forkAndExecInChild(argv0p, argvp, envvp, dirp, fd, p[1]);
|
||||
if err != 0 {
|
||||
error:
|
||||
if p[0] >= 0 {
|
||||
|
Loading…
Reference in New Issue
Block a user