if err != nil {
fatal("%s", err)
}
- pid, err := os.ForkExec(cmd, argv, os.Environ(), "", []*os.File{r0, w1, w2})
+ p, err := os.StartProcess(cmd, argv, os.Environ(), "", []*os.File{r0, w1, w2})
if err != nil {
fatal("%s", err)
}
+ defer p.Release()
r0.Close()
w1.Close()
w2.Close()
<-c
<-c
- w, err := os.Wait(pid, 0)
+ w, err := p.Wait(0)
if err != nil {
fatal("%s", err)
}
if *verbose {
log.Printf("executing %v", args)
}
- pid, err := os.ForkExec(bin, args, os.Environ(), *goroot, fds)
+ p, err := os.StartProcess(bin, args, os.Environ(), *goroot, fds)
defer r.Close()
w.Close()
if err != nil {
- log.Printf("os.ForkExec(%q): %v", bin, err)
+ log.Printf("os.StartProcess(%q): %v", bin, err)
return 2
}
+ defer p.Release()
var buf bytes.Buffer
io.Copy(&buf, r)
- wait, err := os.Wait(pid, 0)
+ wait, err := p.Wait(0)
if err != nil {
os.Stderr.Write(buf.Bytes())
- log.Printf("os.Wait(%d, 0): %v", pid, err)
+ log.Printf("os.Wait(%d, 0): %v", p.Pid, err)
return 2
}
status = wait.ExitStatus()
// Stdin, Stdout, and Stderr are Files representing pipes
// connected to the running command's standard input, output, and error,
// or else nil, depending on the arguments to Run.
-// Pid is the running command's operating system process ID.
+// Process represents the underlying operating system process.
type Cmd struct {
- Stdin *os.File
- Stdout *os.File
- Stderr *os.File
- Pid int
+ Stdin *os.File
+ Stdout *os.File
+ Stderr *os.File
+ Process *os.Process
}
// PathError records the name of a binary that was not
// If a parameter is Pipe, then the corresponding field (Stdin, Stdout, Stderr)
// of the returned Cmd is the other end of the pipe.
// Otherwise the field in Cmd is nil.
-func Run(name string, argv, envv []string, dir string, stdin, stdout, stderr int) (p *Cmd, err os.Error) {
- p = new(Cmd)
+func Run(name string, argv, envv []string, dir string, stdin, stdout, stderr int) (c *Cmd, err os.Error) {
+ c = new(Cmd)
var fd [3]*os.File
- if fd[0], p.Stdin, err = modeToFiles(stdin, 0); err != nil {
+ if fd[0], c.Stdin, err = modeToFiles(stdin, 0); err != nil {
goto Error
}
- if fd[1], p.Stdout, err = modeToFiles(stdout, 1); err != nil {
+ if fd[1], c.Stdout, err = modeToFiles(stdout, 1); err != nil {
goto Error
}
if stderr == MergeWithStdout {
fd[2] = fd[1]
- } else if fd[2], p.Stderr, err = modeToFiles(stderr, 2); err != nil {
+ } else if fd[2], c.Stderr, err = modeToFiles(stderr, 2); err != nil {
goto Error
}
// Run command.
- p.Pid, err = os.ForkExec(name, argv, envv, dir, fd[0:])
+ c.Process, err = os.StartProcess(name, argv, envv, dir, fd[0:])
if err != nil {
goto Error
}
if fd[2] != os.Stderr && fd[2] != fd[1] {
fd[2].Close()
}
- return p, nil
+ return c, nil
Error:
if fd[0] != os.Stdin && fd[0] != nil {
if fd[2] != os.Stderr && fd[2] != nil && fd[2] != fd[1] {
fd[2].Close()
}
- if p.Stdin != nil {
- p.Stdin.Close()
+ if c.Stdin != nil {
+ c.Stdin.Close()
}
- if p.Stdout != nil {
- p.Stdout.Close()
+ if c.Stdout != nil {
+ c.Stdout.Close()
}
- if p.Stderr != nil {
- p.Stderr.Close()
+ if c.Stderr != nil {
+ c.Stderr.Close()
+ }
+ if c.Process != nil {
+ c.Process.Release()
}
return nil, err
}
-// Wait waits for the running command p,
-// returning the Waitmsg returned by os.Wait and an error.
-// The options are passed through to os.Wait.
-// Setting options to 0 waits for p to exit;
+// Wait waits for the running command c,
+// returning the Waitmsg returned when the process exits.
+// The options are passed to the process's Wait method.
+// Setting options to 0 waits for c to exit;
// other options cause Wait to return for other
// process events; see package os for details.
-func (p *Cmd) Wait(options int) (*os.Waitmsg, os.Error) {
- if p.Pid <= 0 {
+func (c *Cmd) Wait(options int) (*os.Waitmsg, os.Error) {
+ if c.Process == nil {
return nil, os.ErrorString("exec: invalid use of Cmd.Wait")
}
- w, err := os.Wait(p.Pid, options)
+ w, err := c.Process.Wait(options)
if w != nil && (w.Exited() || w.Signaled()) {
- p.Pid = -1
+ c.Process.Release()
+ c.Process = nil
}
return w, err
}
-// Close waits for the running command p to exit,
+// Close waits for the running command c to exit,
// if it hasn't already, and then closes the non-nil file descriptors
-// p.Stdin, p.Stdout, and p.Stderr.
-func (p *Cmd) Close() os.Error {
- if p.Pid > 0 {
+// c.Stdin, c.Stdout, and c.Stderr.
+func (c *Cmd) Close() os.Error {
+ if c.Process != nil {
// Loop on interrupt, but
// ignore other errors -- maybe
// caller has already waited for pid.
- _, err := p.Wait(0)
+ _, err := c.Wait(0)
for err == os.EINTR {
- _, err = p.Wait(0)
+ _, err = c.Wait(0)
}
}
// Close the FDs that are still open.
var err os.Error
- if p.Stdin != nil && p.Stdin.Fd() >= 0 {
- if err1 := p.Stdin.Close(); err1 != nil {
+ if c.Stdin != nil && c.Stdin.Fd() >= 0 {
+ if err1 := c.Stdin.Close(); err1 != nil {
err = err1
}
}
- if p.Stdout != nil && p.Stdout.Fd() >= 0 {
- if err1 := p.Stdout.Close(); err1 != nil && err != nil {
+ if c.Stdout != nil && c.Stdout.Fd() >= 0 {
+ if err1 := c.Stdout.Close(); err1 != nil && err != nil {
err = err1
}
}
- if p.Stderr != nil && p.Stderr != p.Stdout && p.Stderr.Fd() >= 0 {
- if err1 := p.Stderr.Close(); err1 != nil && err != nil {
+ if c.Stderr != nil && c.Stderr != c.Stdout && c.Stderr.Fd() >= 0 {
+ if err1 := c.Stderr.Close(); err1 != nil && err != nil {
err = err1
}
}
fmt.Fprintf(rw, "pipe: %s\n", err)
return
}
- pid, err := os.ForkExec("/bin/date", []string{"date"}, os.Environ(), "", []*os.File{nil, w, w})
+ p, err := os.StartProcess("/bin/date", []string{"date"}, os.Environ(), "", []*os.File{nil, w, w})
defer r.Close()
w.Close()
if err != nil {
fmt.Fprintf(rw, "fork/exec: %s\n", err)
return
}
+ defer p.Release()
io.Copy(rw, r)
- wait, err := os.Wait(pid, 0)
+ wait, err := p.Wait(0)
if err != nil {
fmt.Fprintf(rw, "wait: %s\n", err)
return
env_unix.go\
file_unix.go\
sys_bsd.go\
+ exec_unix.go\
GOFILES_darwin=\
env_unix.go\
file_unix.go\
sys_bsd.go\
+ exec_unix.go\
GOFILES_linux=\
env_unix.go\
file_unix.go\
sys_linux.go\
+ exec_unix.go\
GOFILES_windows=\
env_windows.go\
file_windows.go\
sys_windows.go\
+ exec_windows.go\
GOFILES+=$(GOFILES_$(GOOS))
package os
import (
+ "runtime"
"syscall"
)
-// ForkExec forks the current process and invokes Exec with the program, arguments,
-// and environment specified by name, argv, and envv. It returns the process
-// id of the forked process and an Error, if any. The fd array specifies the
+// Process stores the information about a process created by StartProcess.
+type Process struct {
+ Pid int
+ handle int
+}
+
+func newProcess(pid, handle int) *Process {
+ p := &Process{pid, handle}
+ runtime.SetFinalizer(p, (*Process).Release)
+ return p
+}
+
+// StartProcess starts a new process with the program, arguments,
+// and environment specified by name, argv, and envv. The fd array specifies the
// 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.
// If dir is not empty, the child chdirs into the directory before execing the program.
-func ForkExec(name string, argv []string, envv []string, dir string, fd []*File) (pid int, err Error) {
+func StartProcess(name string, argv []string, envv []string, dir string, fd []*File) (p *Process, err Error) {
if envv == nil {
envv = Environ()
}
}
}
- p, e := syscall.ForkExec(name, argv, envv, dir, intfd)
+ pid, h, e := syscall.StartProcess(name, argv, envv, dir, intfd)
if e != 0 {
- return 0, &PathError{"fork/exec", name, Errno(e)}
+ return nil, &PathError{"fork/exec", name, Errno(e)}
}
- return p, nil
+ return newProcess(pid, h), nil
}
// Exec replaces the current process with an execution of the
// named binary, with arguments argv and environment envv.
// If successful, Exec never returns. If it fails, it returns an Error.
-// ForkExec is almost always a better way to execute a program.
+// StartProcess is almost always a better way to execute a program.
func Exec(name string, argv []string, envv []string) Error {
if envv == nil {
envv = Environ()
Rusage *syscall.Rusage // System-dependent resource usage info.
}
-// Options for Wait.
-const (
- WNOHANG = syscall.WNOHANG // Don't wait if no process has exited.
- WSTOPPED = syscall.WSTOPPED // If set, status of stopped subprocesses is also reported.
- WUNTRACED = syscall.WUNTRACED // Usually an alias for WSTOPPED.
- WRUSAGE = 1 << 20 // Record resource usage.
-)
-
-// WRUSAGE must not be too high a bit, to avoid clashing with Linux's
-// WCLONE, WALL, and WNOTHREAD flags, which sit in the top few bits of
-// the options
-
// Wait waits for process pid to exit or stop, and then returns a
// Waitmsg describing its status and an Error, if any. The options
// (WNOHANG etc.) affect the behavior of the Wait call.
+// Wait is equivalent to calling FindProcess and then Wait
+// and Release on the result.
func Wait(pid int, options int) (w *Waitmsg, err Error) {
- var status syscall.WaitStatus
- var rusage *syscall.Rusage
- if options&WRUSAGE != 0 {
- rusage = new(syscall.Rusage)
- options ^= WRUSAGE
- }
- pid1, e := syscall.Wait4(pid, &status, options, rusage)
- if e != 0 {
- return nil, NewSyscallError("wait", e)
+ p, e := FindProcess(pid)
+ if e != nil {
+ return nil, e
}
- w = new(Waitmsg)
- w.Pid = pid1
- w.WaitStatus = status
- w.Rusage = rusage
- return w, nil
+ defer p.Release()
+ return p.Wait(options)
}
// Convert i to decimal string.
--- /dev/null
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os
+
+import (
+ "runtime"
+ "syscall"
+)
+
+// Options for Wait.
+const (
+ WNOHANG = syscall.WNOHANG // Don't wait if no process has exited.
+ WSTOPPED = syscall.WSTOPPED // If set, status of stopped subprocesses is also reported.
+ WUNTRACED = syscall.WUNTRACED // Usually an alias for WSTOPPED.
+ WRUSAGE = 1 << 20 // Record resource usage.
+)
+
+// WRUSAGE must not be too high a bit, to avoid clashing with Linux's
+// WCLONE, WALL, and WNOTHREAD flags, which sit in the top few bits of
+// the options
+
+// Wait waits for the Process to exit or stop, and then returns a
+// Waitmsg describing its status and an Error, if any. The options
+// (WNOHANG etc.) affect the behavior of the Wait call.
+func (p *Process) Wait(options int) (w *Waitmsg, err Error) {
+ if p.Pid == -1 {
+ return nil, EINVAL
+ }
+ var status syscall.WaitStatus
+ var rusage *syscall.Rusage
+ if options&WRUSAGE != 0 {
+ rusage = new(syscall.Rusage)
+ options ^= WRUSAGE
+ }
+ pid1, e := syscall.Wait4(p.Pid, &status, options, rusage)
+ if e != 0 {
+ return nil, NewSyscallError("wait", e)
+ }
+ w = new(Waitmsg)
+ w.Pid = pid1
+ w.WaitStatus = status
+ w.Rusage = rusage
+ return w, nil
+}
+
+// Release releases any resources associated with the Process.
+func (p *Process) Release() Error {
+ // NOOP for unix.
+ p.Pid = -1
+ // no need for a finalizer anymore
+ runtime.SetFinalizer(p, nil)
+ return nil
+}
+
+// FindProcess looks for a running process by its pid.
+// The Process it returns can be used to obtain information
+// about the underlying operating system process.
+func FindProcess(pid int) (p *Process, err Error) {
+ // NOOP for unix.
+ return newProcess(pid, 0), nil
+}
--- /dev/null
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os
+
+import (
+ "runtime"
+ "syscall"
+)
+
+func (p *Process) Wait(options int) (w *Waitmsg, err Error) {
+ s, e := syscall.WaitForSingleObject(int32(p.handle), syscall.INFINITE)
+ switch s {
+ case syscall.WAIT_OBJECT_0:
+ break
+ case syscall.WAIT_FAILED:
+ return nil, NewSyscallError("WaitForSingleObject", e)
+ default:
+ return nil, ErrorString("os: unexpected result from WaitForSingleObject")
+ }
+ var ec uint32
+ if ok, e := syscall.GetExitCodeProcess(uint32(p.handle), &ec); !ok {
+ return nil, NewSyscallError("GetExitCodeProcess", e)
+ }
+ return &Waitmsg{p.Pid, syscall.WaitStatus{s, ec}, new(syscall.Rusage)}, nil
+}
+
+func (p *Process) Release() Error {
+ if p.handle == -1 {
+ return EINVAL
+ }
+ if ok, e := syscall.CloseHandle(int32(p.handle)); !ok {
+ return NewSyscallError("CloseHandle", e)
+ }
+ p.handle = -1
+ // no need for a finalizer anymore
+ runtime.SetFinalizer(p, nil)
+ return nil
+}
+
+func FindProcess(pid int) (p *Process, err Error) {
+ const da = syscall.STANDARD_RIGHTS_READ |
+ syscall.PROCESS_QUERY_INFORMATION | syscall.SYNCHRONIZE
+ h, e := syscall.OpenProcess(da, false, uint32(pid))
+ if e != 0 {
+ return nil, NewSyscallError("OpenProcess", e)
+ }
+ return newProcess(pid, int(h)), nil
+}
adir = "/"
expect = "/\n"
}
- pid, err := ForkExec(cmd, args, nil, adir, []*File{nil, w, Stderr})
+ p, err := StartProcess(cmd, args, nil, adir, []*File{nil, w, Stderr})
if err != nil {
- t.Fatalf("ForkExec: %v", err)
+ t.Fatalf("StartProcess: %v", err)
}
+ defer p.Release()
w.Close()
var b bytes.Buffer
args[0] = cmd
t.Errorf("exec %q returned %q wanted %q", strings.Join(args, " "), output, expect)
}
- Wait(pid, 0)
+ p.Wait(0)
}
func checkMode(t *testing.T, path string, mode uint32) {
if err != nil {
t.Fatal(err)
}
- pid, err := ForkExec("/bin/hostname", []string{"hostname"}, nil, "/", []*File{nil, w, Stderr})
+ p, err := StartProcess("/bin/hostname", []string{"hostname"}, nil, "/", []*File{nil, w, Stderr})
if err != nil {
t.Fatal(err)
}
+ defer p.Release()
w.Close()
var b bytes.Buffer
io.Copy(&b, r)
- Wait(pid, 0)
+ p.Wait(0)
output := b.String()
if n := len(output); n > 0 && output[n-1] == '\n' {
output = output[0 : n-1]
uintptr(unsafe.Pointer(&StringArrayPtr(envv)[0])))
return int(err1)
}
+
+// StartProcess wraps ForkExec for package os.
+func StartProcess(argv0 string, argv []string, envv []string, dir string, fd []int) (pid, handle int, err int) {
+ pid, err = forkExec(argv0, argv, envv, false, dir, fd)
+ return pid, 0, err
+}
// TODO(kardia): Add trace
//The command and arguments are passed via the Command line parameter.
-func forkExec(argv0 string, argv []string, envv []string, traceme bool, dir string, fd []int) (pid int, err int) {
- if traceme == true {
- return 0, EWINDOWS
- }
-
+func StartProcess(argv0 string, argv []string, envv []string, dir string, fd []int) (pid, handle int, err int) {
if len(fd) > 3 {
- return 0, EWINDOWS
+ return 0, 0, EWINDOWS
}
//CreateProcess will throw an error if the dir is not set to a valid dir
var currentProc, _ = GetCurrentProcess()
if len(fd) > 0 && fd[0] > 0 {
if ok, err := DuplicateHandle(currentProc, int32(fd[0]), currentProc, &startupInfo.StdInput, 0, true, DUPLICATE_SAME_ACCESS); !ok {
- return 0, err
+ return 0, 0, err
}
defer CloseHandle(int32(startupInfo.StdInput))
}
if len(fd) > 1 && fd[1] > 0 {
if ok, err := DuplicateHandle(currentProc, int32(fd[1]), currentProc, &startupInfo.StdOutput, 0, true, DUPLICATE_SAME_ACCESS); !ok {
- return 0, err
+ return 0, 0, err
}
defer CloseHandle(int32(startupInfo.StdOutput))
}
if len(fd) > 2 && fd[2] > 0 {
if ok, err := DuplicateHandle(currentProc, int32(fd[2]), currentProc, &startupInfo.StdErr, 0, true, DUPLICATE_SAME_ACCESS); !ok {
- return 0, err
+ return 0, 0, err
}
defer CloseHandle(int32(startupInfo.StdErr))
}
if ok {
pid = int(processInfo.ProcessId)
- CloseHandle(processInfo.Process)
+ handle = int(processInfo.Process)
CloseHandle(processInfo.Thread)
}
return
}
-func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int) (pid int, err int) {
- return forkExec(argv0, argv, envv, false, dir, fd)
-}
-
-// PtraceForkExec is like ForkExec, but starts the child in a traced state.
-func PtraceForkExec(argv0 string, argv []string, envv []string, dir string, fd []int) (pid int, err int) {
- return forkExec(argv0, argv, envv, true, dir, fd)
-}
-
// Ordinary exec.
func Exec(argv0 string, argv []string, envv []string) (err int) {
return EWINDOWS
//sys GetQueuedCompletionStatus(cphandle int32, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (ok bool, errno int)
//sys CancelIo(s uint32) (ok bool, errno int)
//sys CreateProcess(appName *int16, commandLine *uint16, procSecurity *int16, threadSecurity *int16, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (ok bool, errno int) = CreateProcessW
+//sys OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle uint32, errno int)
+//sys GetExitCodeProcess(handle uint32, exitcode *uint32) (ok bool, errno int)
//sys GetStartupInfo(startupInfo *StartupInfo) (ok bool, errno int) = GetStartupInfoW
//sys GetCurrentProcess() (pseudoHandle int32, errno int)
//sys DuplicateHandle(hSourceProcessHandle int32, hSourceHandle int32, hTargetProcessHandle int32, lpTargetHandle *int32, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (ok bool, errno int)
//sys CryptAcquireContext(provhandle *uint32, container *uint16, provider *uint16, provtype uint32, flags uint32) (ok bool, errno int) = advapi32.CryptAcquireContextW
//sys CryptReleaseContext(provhandle uint32, flags uint32) (ok bool, errno int) = advapi32.CryptReleaseContext
//sys CryptGenRandom(provhandle uint32, buflen uint32, buf *byte) (ok bool, errno int) = advapi32.CryptGenRandom
-//sys OpenProcess(da uint32,b int, pid uint32) (handle uint32, errno int)
-//sys GetExitCodeProcess(h uint32, c *uint32) (ok bool, errno int)
//sys GetEnvironmentStrings() (envs *uint16, errno int) [failretval==nil] = kernel32.GetEnvironmentStringsW
//sys FreeEnvironmentStrings(envs *uint16) (ok bool, errno int) = kernel32.FreeEnvironmentStringsW
//sys GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, errno int) = kernel32.GetEnvironmentVariableW
return
}
+// Invented structures to support what package os expects.
+type Rusage struct{}
+
+type WaitStatus struct {
+ Status uint32
+ ExitCode uint32
+}
+
+func (w WaitStatus) Exited() bool { return true }
+
+func (w WaitStatus) ExitStatus() int { return int(w.ExitCode) }
+
+func (w WaitStatus) Signal() int { return -1 }
+
+func (w WaitStatus) CoreDump() bool { return false }
+
+func (w WaitStatus) Stopped() bool { return false }
+
+func (w WaitStatus) Continued() bool { return false }
+
+func (w WaitStatus) StopSignal() int { return -1 }
+
+func (w WaitStatus) Signaled() bool { return true }
+
+func (w WaitStatus) TrapCause() int { return -1 }
+
// TODO(brainman): fix all needed for net
func Accept(fd int) (nfd int, sa Sockaddr, errno int) { return 0, nil, EWINDOWS }
SYS_EXIT
SYS_READ
)
-
-type Rusage struct {
- Utime Timeval
- Stime Timeval
- Maxrss int32
- Ixrss int32
- Idrss int32
- Isrss int32
- Minflt int32
- Majflt int32
- Nswap int32
- Inblock int32
- Oublock int32
- Msgsnd int32
- Msgrcv int32
- Nsignals int32
- Nvcsw int32
- Nivcsw int32
-}
-
-type WaitStatus struct {
- Status uint32
- ExitCode uint32
-}
-
-func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, errno int) {
- const da = STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | SYNCHRONIZE
- handle, errno := OpenProcess(da, 0, uint32(pid))
- if errno != 0 {
- return 0, errno
- }
- defer CloseHandle(int32(handle))
- e, errno := WaitForSingleObject(int32(handle), INFINITE)
- var c uint32
- if ok, errno := GetExitCodeProcess(handle, &c); !ok {
- return 0, errno
- }
- *wstatus = WaitStatus{e, c}
- return pid, 0
-}
-
-
-func (w WaitStatus) Exited() bool { return w.Status == WAIT_OBJECT_0 }
-
-func (w WaitStatus) ExitStatus() int {
- if w.Status == WAIT_OBJECT_0 {
- return int(w.ExitCode)
- }
- return -1
-}
-
-func (WaitStatus) Signal() int { return -1 }
-
-func (WaitStatus) CoreDump() bool { return false }
-
-func (WaitStatus) Stopped() bool { return false }
-
-func (WaitStatus) Continued() bool { return false }
-
-func (WaitStatus) StopSignal() int { return -1 }
-
-func (w WaitStatus) Signaled() bool { return w.Status == WAIT_OBJECT_0 }
-
-func (WaitStatus) TrapCause() int { return -1 }
procGetQueuedCompletionStatus = getSysProcAddr(modkernel32, "GetQueuedCompletionStatus")
procCancelIo = getSysProcAddr(modkernel32, "CancelIo")
procCreateProcessW = getSysProcAddr(modkernel32, "CreateProcessW")
+ procOpenProcess = getSysProcAddr(modkernel32, "OpenProcess")
+ procGetExitCodeProcess = getSysProcAddr(modkernel32, "GetExitCodeProcess")
procGetStartupInfoW = getSysProcAddr(modkernel32, "GetStartupInfoW")
procGetCurrentProcess = getSysProcAddr(modkernel32, "GetCurrentProcess")
procDuplicateHandle = getSysProcAddr(modkernel32, "DuplicateHandle")
procCryptAcquireContextW = getSysProcAddr(modadvapi32, "CryptAcquireContextW")
procCryptReleaseContext = getSysProcAddr(modadvapi32, "CryptReleaseContext")
procCryptGenRandom = getSysProcAddr(modadvapi32, "CryptGenRandom")
- procOpenProcess = getSysProcAddr(modkernel32, "OpenProcess")
- procGetExitCodeProcess = getSysProcAddr(modkernel32, "GetExitCodeProcess")
procGetEnvironmentStringsW = getSysProcAddr(modkernel32, "GetEnvironmentStringsW")
procFreeEnvironmentStringsW = getSysProcAddr(modkernel32, "FreeEnvironmentStringsW")
procGetEnvironmentVariableW = getSysProcAddr(modkernel32, "GetEnvironmentVariableW")
return
}
+func OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle uint32, errno int) {
+ var _p0 uint32
+ if inheritHandle {
+ _p0 = 1
+ } else {
+ _p0 = 0
+ }
+ r0, _, e1 := Syscall(procOpenProcess, 3, uintptr(da), uintptr(_p0), uintptr(pid))
+ handle = uint32(r0)
+ if handle == 0 {
+ if e1 != 0 {
+ errno = int(e1)
+ } else {
+ errno = EINVAL
+ }
+ } else {
+ errno = 0
+ }
+ return
+}
+
+func GetExitCodeProcess(handle uint32, exitcode *uint32) (ok bool, errno int) {
+ r0, _, e1 := Syscall(procGetExitCodeProcess, 2, uintptr(handle), uintptr(unsafe.Pointer(exitcode)), 0)
+ ok = bool(r0 != 0)
+ if !ok {
+ if e1 != 0 {
+ errno = int(e1)
+ } else {
+ errno = EINVAL
+ }
+ } else {
+ errno = 0
+ }
+ return
+}
+
func GetStartupInfo(startupInfo *StartupInfo) (ok bool, errno int) {
r0, _, e1 := Syscall(procGetStartupInfoW, 1, uintptr(unsafe.Pointer(startupInfo)), 0, 0)
ok = bool(r0 != 0)
return
}
-func OpenProcess(da uint32, b int, pid uint32) (handle uint32, errno int) {
- r0, _, e1 := Syscall(procOpenProcess, 3, uintptr(da), uintptr(b), uintptr(pid))
- handle = uint32(r0)
- if handle == 0 {
- if e1 != 0 {
- errno = int(e1)
- } else {
- errno = EINVAL
- }
- } else {
- errno = 0
- }
- return
-}
-
-func GetExitCodeProcess(h uint32, c *uint32) (ok bool, errno int) {
- r0, _, e1 := Syscall(procGetExitCodeProcess, 2, uintptr(h), uintptr(unsafe.Pointer(c)), 0)
- ok = bool(r0 != 0)
- if !ok {
- if e1 != 0 {
- errno = int(e1)
- } else {
- errno = EINVAL
- }
- } else {
- errno = 0
- }
- return
-}
-
func GetEnvironmentStrings() (envs *uint16, errno int) {
r0, _, e1 := Syscall(procGetEnvironmentStringsW, 0, 0, 0, 0)
envs = (*uint16)(unsafe.Pointer(r0))