Ejemplo n.º 1
1
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))
		}
	}
}
Ejemplo n.º 2
0
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)
	}
}
Ejemplo n.º 3
0
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
}
Ejemplo n.º 4
0
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
}
Ejemplo n.º 5
0
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
}
Ejemplo n.º 6
0
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
}
Ejemplo n.º 7
0
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)
		}
	}()
}
Ejemplo n.º 8
0
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
	}
}
Ejemplo n.º 9
0
// 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
}
Ejemplo n.º 10
0
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
	}
}
Ejemplo n.º 11
0
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
}
Ejemplo n.º 12
0
// 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()
			}
		}
	}()
}
Ejemplo n.º 13
0
// 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)
			}
		}
	}()
}
Ejemplo n.º 14
0
// 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()
			}
		}
	}()
}
Ejemplo n.º 15
0
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
}
Ejemplo n.º 16
0
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()
			}
		}
	}()
}
Ejemplo n.º 17
0
// 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
}
Ejemplo n.º 18
0
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
	}
}
Ejemplo n.º 19
0
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
	}
}
Ejemplo n.º 20
0
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
}