Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
b725e32c
Commit
b725e32c
authored
May 15, 2009
by
Russ Cox
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add directory argument to os.ForkExec
R=iant DELTA=41 (35 added, 0 deleted, 6 changed) OCL=28892 CL=28895
parent
a854c7f9
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
41 additions
and
6 deletions
+41
-6
exec.go
src/lib/exec/exec.go
+1
-1
exec.go
src/lib/os/exec.go
+3
-2
os_test.go
src/lib/os/os_test.go
+22
-0
exec.go
src/lib/syscall/exec.go
+15
-3
No files found.
src/lib/exec/exec.go
View file @
b725e32c
...
...
@@ -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
;
}
...
...
src/lib/os/exec.go
View file @
b725e32c
...
...
@@ -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
);
}
...
...
src/lib/os/os_test.go
View file @
b725e32c
...
...
@@ -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
);
}
src/lib/syscall/exec.go
View file @
b725e32c
...
...
@@ -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
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment