-
Notifications
You must be signed in to change notification settings - Fork 18.7k
Closed
Labels
Description
What steps will reproduce the problem?
Compile and run this program:
package main
import "syscall"
import "exec"
import "log"
func main() {
p, err := exec.Run("cmd", []string{"/c", "dir"}, nil, "",
exec.DevNull, exec.DevNull, exec.DevNull)
if err != nil {
log.Exit(err)
}
syscall.Sleep(3000000000)
_, err = p.Wait(0)
if err != nil {
log.Exitf("Wait failed with error \"%s\"\n", err.String())
}
println("Success.")
}
What is the expected output?
Success.
What do you see instead?
2011/02/01 14:17:47 Wait failed with error "wait: The parameter is incorrect."
Please use labels and text to provide additional information.
The problem is pid is not reliable process identifier on windows, must use handle
returned by windows api CreateProcess instead. But current os interface doesn't support
that. To demonstrate, this is what is happening under covers for correspondent os
functions on Windows:
os.ForkExec(...) (pid):
handle, pid = CreateProcess(...) // create process
CloseHandle(handle) // close handle, we're not going to use it
return pid
os.Wait(pid) (rc):
handle := OpenProcess(pid) // find our process, convert pid into handle
WaitForSingleObject(handle) // wait for process to end
rc = GetExitCodeProcess(handle) // get exit code
CloseHandle(handle) // done with our process
return rc
Under certain conditions (on Windows 2000 much more often then others), OpenProcess
fails, because pid was reused or whatever, therefore we can't continue to retrieve exit
code.
The interface should be:
os.ForkExec(...) (handle, pid):
handle, pid = CreateProcess(...) // create process
return handle, pid
os.Wait(handle) (rc):
WaitForSingleObject(handle) // wait for process to end
rc = GetExitCodeProcess(handle) // get exit code
return rc
Close process handle once done:
CloseHandle(handle) // done with our process
This can be accommodated if we introduce os.Process structure to hide all os specific
implementation details. There is an issue
https://golang.org/issue/1004 about it. But I couldn't reproduce the
problem on non Windows 2000 os. Now, thanks to mattn, we've got a test case.