func (t *Interface) Write(ch chan []byte) (err error) { tx := syscall.Overlapped{} var hevent windows.Handle hevent, err = windows.CreateEvent(nil, 0, 0, nil) if err != nil { return } tx.HEvent = syscall.Handle(hevent) for { select { case data := <-ch: var l uint32 syscall.WriteFile(t.file, data, &l, &tx) syscall.WaitForSingleObject(tx.HEvent, syscall.INFINITE) tx.Offset += uint32(len(data)) } } }
func BenchmarkSyscallToSyscallPing(b *testing.B) { n := b.N event1, err := createEvent() if err != nil { b.Fatal(err) } event2, err := createEvent() if err != nil { b.Fatal(err) } go func() { for i := 0; i < n; i++ { syscall.WaitForSingleObject(event1, syscall.INFINITE) err := setEvent(event2) if err != nil { b.Fatal(err) } } }() for i := 0; i < n; i++ { err := setEvent(event1) if err != nil { b.Fatal(err) } syscall.WaitForSingleObject(event2, syscall.INFINITE) } }
func (sub *Subprocess) BottomHalf(d *SubprocessData, sig chan *SubprocessResult) { hProcess := d.platformData.hProcess hJob := d.platformData.hJob result := &SubprocessResult{} var waitResult uint32 waitResult = syscall.WAIT_TIMEOUT var runState runningState for result.SuccessCode == 0 && waitResult == syscall.WAIT_TIMEOUT { waitResult, _ = syscall.WaitForSingleObject(hProcess, uint32(sub.TimeQuantum.Nanoseconds()/1000000)) if waitResult != syscall.WAIT_TIMEOUT { break } _ = UpdateProcessTimes(&d.platformData, result, false) if sub.MemoryLimit > 0 { UpdateProcessMemory(&d.platformData, result) } runState.Update(sub, result) } switch waitResult { case syscall.WAIT_OBJECT_0: _ = syscall.GetExitCodeProcess(hProcess, &result.ExitCode) case syscall.WAIT_TIMEOUT: for waitResult == syscall.WAIT_TIMEOUT { syscall.TerminateProcess(hProcess, 0) waitResult, _ = syscall.WaitForSingleObject(hProcess, 100) } } _ = UpdateProcessTimes(&d.platformData, result, true) UpdateProcessMemory(&d.platformData, result) syscall.CloseHandle(hProcess) if hJob != syscall.InvalidHandle { syscall.CloseHandle(hJob) } sub.SetPostLimits(result) for _ = range d.startAfterStart { err := <-d.bufferChan if err != nil { log.Error(err) } } if d.stdOut.Len() > 0 { result.Output = d.stdOut.Bytes() } if d.stdErr.Len() > 0 { result.Error = d.stdErr.Bytes() } sig <- result }
func (process *jobProcess) Wait() (int, error) { s, e := syscall.WaitForSingleObject(syscall.Handle(process.processHandle), syscall.INFINITE) switch s { case syscall.WAIT_OBJECT_0: break case syscall.WAIT_FAILED: return -1, os.NewSyscallError("WaitForSingleObject", e) default: return -1, errors.New("os: unexpected result from WaitForSingleObject") } var ec uint32 e = syscall.GetExitCodeProcess(syscall.Handle(process.processHandle), &ec) if e != nil { return -1, os.NewSyscallError("GetExitCodeProcess", e) } var u syscall.Rusage e = syscall.GetProcessTimes(syscall.Handle(process.processHandle), &u.CreationTime, &u.ExitTime, &u.KernelTime, &u.UserTime) if e != nil { return -1, os.NewSyscallError("GetProcessTimes", e) } // NOTE(brainman): It seems that sometimes process is not dead // when WaitForSingleObject returns. But we do not know any // other way to wait for it. Sleeping for a while seems to do // the trick sometimes. So we will sleep and smell the roses. defer time.Sleep(5 * time.Millisecond) defer syscall.CloseHandle(syscall.Handle(process.processHandle)) return int(ec), nil }
func terminateProcessLoop(process syscall.Handle) error { for waitResult := uint32(syscall.WAIT_TIMEOUT); waitResult == syscall.WAIT_TIMEOUT; { syscall.TerminateProcess(process, 0) waitResult, _ = syscall.WaitForSingleObject(process, 100) } return nil }
func (p *Process) wait() (ps *ProcessState, err error) { handle := atomic.LoadUintptr(&p.handle) s, e := syscall.WaitForSingleObject(syscall.Handle(handle), syscall.INFINITE) switch s { case syscall.WAIT_OBJECT_0: break case syscall.WAIT_FAILED: return nil, NewSyscallError("WaitForSingleObject", e) default: return nil, errors.New("os: unexpected result from WaitForSingleObject") } var ec uint32 e = syscall.GetExitCodeProcess(syscall.Handle(handle), &ec) if e != nil { return nil, NewSyscallError("GetExitCodeProcess", e) } var u syscall.Rusage e = syscall.GetProcessTimes(syscall.Handle(handle), &u.CreationTime, &u.ExitTime, &u.KernelTime, &u.UserTime) if e != nil { return nil, NewSyscallError("GetProcessTimes", e) } p.setDone() // NOTE(brainman): It seems that sometimes process is not dead // when WaitForSingleObject returns. But we do not know any // other way to wait for it. Sleeping for a while seems to do // the trick sometimes. So we will sleep and smell the roses. defer time.Sleep(5 * time.Millisecond) defer p.Release() return &ProcessState{p.Pid, syscall.WaitStatus{ExitCode: ec}, &u}, nil }
func setupDumpStackTrap(root string) { // Windows does not support signals like *nix systems. So instead of // trapping on SIGUSR1 to dump stacks, we wait on a Win32 event to be // signaled. ACL'd to builtin administrators and local system ev := "Global\\docker-daemon-" + fmt.Sprint(os.Getpid()) sd, err := winio.SddlToSecurityDescriptor("D:P(A;;GA;;;BA)(A;;GA;;;SY)") if err != nil { logrus.Errorf("failed to get security descriptor for debug stackdump event %s: %s", ev, err.Error()) return } var sa syscall.SecurityAttributes sa.Length = uint32(unsafe.Sizeof(sa)) sa.InheritHandle = 1 sa.SecurityDescriptor = uintptr(unsafe.Pointer(&sd[0])) h, err := system.CreateEvent(&sa, false, false, ev) if h == 0 || err != nil { logrus.Errorf("failed to create debug stackdump event %s: %s", ev, err.Error()) return } go func() { logrus.Debugf("Stackdump - waiting signal at %s", ev) for { syscall.WaitForSingleObject(h, syscall.INFINITE) signal.DumpStacks(root) } }() }
func (t *tun) Read(ch chan []byte) (err error) { overlappedRx := syscall.Overlapped{} var hevent windows.Handle hevent, err = windows.CreateEvent(nil, 0, 0, nil) if err != nil { return } overlappedRx.HEvent = syscall.Handle(hevent) buf := make([]byte, t.mtu) var l uint32 for { if err := syscall.ReadFile(t.fd, buf, &l, &overlappedRx); err != nil { } if _, err := syscall.WaitForSingleObject(overlappedRx.HEvent, syscall.INFINITE); err != nil { fmt.Println(err) } overlappedRx.Offset += l totalLen := 0 switch buf[0] & 0xf0 { case 0x40: totalLen = 256*int(buf[2]) + int(buf[3]) case 0x60: continue totalLen = 256*int(buf[4]) + int(buf[5]) + IPv6_HEADER_LENGTH } fmt.Println("read data", buf[:totalLen]) send := make([]byte, totalLen) copy(send, buf) ch <- send } }
// waitForCompletion waits for an asynchronous I/O request referred to by overlapped to complete. // This function returns the number of bytes transferred by the operation and an error code if // applicable (nil otherwise). func waitForCompletion(handle syscall.Handle, overlapped *syscall.Overlapped) (uint32, error) { _, err := syscall.WaitForSingleObject(overlapped.HEvent, syscall.INFINITE) if err != nil { return 0, err } var transferred uint32 err = getOverlappedResult(handle, overlapped, &transferred, true) return transferred, err }
func waitForSingleObject(handle syscall.Handle, timeout uint32) (bool, error) { s, e := syscall.WaitForSingleObject(handle, timeout) switch s { case syscall.WAIT_OBJECT_0: return true, nil case syscall.WAIT_TIMEOUT: return false, nil default: return false, e } }
func (e *event) Wait() error { s, err := syscall.WaitForSingleObject(e.h, syscall.INFINITE) switch s { case syscall.WAIT_OBJECT_0: break case syscall.WAIT_FAILED: return err default: return errors.New("unexpected result from WaitForSingleObject") } return nil }
// setupConfigReloadTrap configures a Win32 event to reload the configuration. func (cli *DaemonCli) setupConfigReloadTrap() { go func() { sa := syscall.SecurityAttributes{ Length: 0, } ev := "Global\\docker-daemon-config-" + fmt.Sprint(os.Getpid()) if h, _ := system.CreateEvent(&sa, false, false, ev); h != 0 { logrus.Debugf("Config reload - waiting signal at %s", ev) for { syscall.WaitForSingleObject(h, syscall.INFINITE) cli.reloadConfig() } } }() }
// setupConfigReloadTrap configures a Win32 event to reload the configuration. func setupConfigReloadTrap(configFile string, flags *mflag.FlagSet, reload func(*daemon.Config)) { go func() { sa := syscall.SecurityAttributes{ Length: 0, } ev := "Global\\docker-daemon-config-" + fmt.Sprint(os.Getpid()) if h, _ := system.CreateEvent(&sa, false, false, ev); h != 0 { logrus.Debugf("Config reload - waiting signal at %s", ev) for { syscall.WaitForSingleObject(h, syscall.INFINITE) daemon.ReloadConfiguration(configFile, flags, reload) } } }() }
// Copied over from docker/daemon/debugtrap_windows.go func setupDumpStackTrap() { go func() { sa := syscall.SecurityAttributes{ Length: 0, } ev := "Global\\docker-daemon-" + fmt.Sprint(os.Getpid()) if h, _ := system.CreateEvent(&sa, false, false, ev); h != 0 { logrus.Debugf("Stackdump - waiting signal at %s", ev) for { syscall.WaitForSingleObject(h, syscall.INFINITE) signal.DumpStacks() } } }() }
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 e = syscall.GetExitCodeProcess(uint32(p.handle), &ec) if e != 0 { return nil, NewSyscallError("GetExitCodeProcess", e) } return &Waitmsg{p.Pid, syscall.WaitStatus{s, ec}, new(syscall.Rusage)}, nil }
func setupDumpStackTrap() { // Windows does not support signals like *nix systems. So instead of // trapping on SIGUSR1 to dump stacks, we wait on a Win32 event to be // signaled. go func() { sa := syscall.SecurityAttributes{ Length: 0, } ev := "Global\\docker-daemon-" + fmt.Sprint(os.Getpid()) if h, _ := system.CreateEvent(&sa, false, false, ev); h != 0 { logrus.Debugf("Stackdump - waiting signal at %s", ev) for { syscall.WaitForSingleObject(h, syscall.INFINITE) psignal.DumpStacks() } } }() }
// Wait waits for the Process to exit or stop, and then returns a // ProcessState describing its status and an error, if any. func (p *Process) Wait() (ps *ProcessState, err error) { s, e := syscall.WaitForSingleObject(syscall.Handle(p.handle), syscall.INFINITE) switch s { case syscall.WAIT_OBJECT_0: break case syscall.WAIT_FAILED: return nil, NewSyscallError("WaitForSingleObject", e) default: return nil, errors.New("os: unexpected result from WaitForSingleObject") } var ec uint32 e = syscall.GetExitCodeProcess(syscall.Handle(p.handle), &ec) if e != nil { return nil, NewSyscallError("GetExitCodeProcess", e) } p.done = true return &ProcessState{p.Pid, syscall.WaitStatus{Status: s, ExitCode: ec}, new(syscall.Rusage)}, nil }
func (t *Interface) Read(ch chan []byte) (err error) { rx := syscall.Overlapped{} var hevent windows.Handle hevent, err = windows.CreateEvent(nil, 0, 0, nil) if err != nil { return } rx.HEvent = syscall.Handle(hevent) buf := make([]byte, 1500) var l uint32 for { if err := syscall.ReadFile(t.file, buf, &l, &rx); err != nil { } if _, err := syscall.WaitForSingleObject(rx.HEvent, syscall.INFINITE); err != nil { Log(Error, "Failed to read from TUN/TAP: %v", err) } rx.Offset += l ch <- buf } }
func BenchmarkChanToSyscallPing(b *testing.B) { n := b.N ch := make(chan int) event, err := createEvent() if err != nil { b.Fatal(err) } go func() { for i := 0; i < n; i++ { syscall.WaitForSingleObject(event, syscall.INFINITE) ch <- 1 } }() for i := 0; i < n; i++ { err := setEvent(event) if err != nil { b.Fatal(err) } <-ch } }
func InjectDll(d *SubprocessData, loadLibraryW uintptr, dll string) error { if int(loadLibraryW) == 0 { return nil } ec := tools.ErrorContext("InjectDll") log.Debug("InjectDll: Injecting library %s with call to %d", dll, loadLibraryW) name, err := syscall.UTF16FromString(dll) if err != nil { return ec.NewError(err, ERR_USER, "UTF16FromString") } nameLen := uint32((len(name) + 1) * 2) remoteName, err := win32.VirtualAllocEx(d.platformData.hProcess, 0, nameLen, win32.MEM_COMMIT, win32.PAGE_READWRITE) if err != nil { return ec.NewError(err) } defer win32.VirtualFreeEx(d.platformData.hProcess, remoteName, 0, win32.MEM_RELEASE) _, err = win32.WriteProcessMemory(d.platformData.hProcess, remoteName, unsafe.Pointer(&name[0]), nameLen) if err != nil { return ec.NewError(err) } thread, _, err := win32.CreateRemoteThread(d.platformData.hProcess, win32.MakeInheritSa(), 0, loadLibraryW, remoteName, 0) if err != nil { return ec.NewError(err) } defer syscall.CloseHandle(thread) wr, err := syscall.WaitForSingleObject(thread, syscall.INFINITE) if err != nil { return ec.NewError(os.NewSyscallError("WaitForSingleObject", err)) } if wr != syscall.WAIT_OBJECT_0 { return ec.NewError(fmt.Errorf("Unexpected wait result %s", wr)) } return nil }