Beispiel #1
0
func (fd *netFD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
	if fd == nil || fd.sysfile == nil {
		return 0, 0, os.EINVAL
	}
	fd.wio.Lock()
	defer fd.wio.Unlock()
	fd.incref()
	defer fd.decref()
	for {
		err = syscall.Sendmsg(fd.sysfd, p, oob, sa, 0)
		if err == syscall.EAGAIN {
			if fd.wdeadline >= 0 {
				pollserver.WaitWrite(fd)
				continue
			}
			err = errTimeout
		}
		break
	}
	if err == nil {
		n = len(p)
		oobn = len(oob)
	} else {
		err = &OpError{"write", fd.net, fd.raddr, err}
	}
	return
}
Beispiel #2
0
func (fd *netFD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
	fd.wio.Lock()
	defer fd.wio.Unlock()
	if err := fd.incref(false); err != nil {
		return 0, 0, err
	}
	defer fd.decref()
	for {
		err = syscall.Sendmsg(fd.sysfd, p, oob, sa, 0)
		if err == syscall.EAGAIN {
			err = errTimeout
			if fd.wdeadline >= 0 {
				if err = fd.pollServer.WaitWrite(fd); err == nil {
					continue
				}
			}
		}
		break
	}
	if err == nil {
		n = len(p)
		oobn = len(oob)
	} else {
		err = &OpError{"write", fd.net, fd.raddr, err}
	}
	return
}
Beispiel #3
0
func (fd *netFD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
	if fd == nil || fd.sysfile == nil {
		return 0, 0, os.EINVAL
	}
	fd.wio.Lock()
	defer fd.wio.Unlock()
	fd.incref()
	defer fd.decref()
	if fd.wdeadline_delta > 0 {
		fd.wdeadline = pollserver.Now() + fd.wdeadline_delta
	} else {
		fd.wdeadline = 0
	}
	var oserr error
	for {
		var errno int
		errno = syscall.Sendmsg(fd.sysfd, p, oob, sa, 0)
		if errno == syscall.EAGAIN && fd.wdeadline >= 0 {
			pollserver.WaitWrite(fd)
			continue
		}
		if errno != 0 {
			oserr = os.Errno(errno)
		}
		break
	}
	if oserr == nil {
		n = len(p)
		oobn = len(oob)
	} else {
		err = &OpError{"write", fd.net, fd.raddr, oserr}
	}
	return
}
Beispiel #4
0
func (fd *netFD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
	if err := fd.writeLock(); err != nil {
		return 0, 0, err
	}
	defer fd.writeUnlock()
	if err := fd.pd.PrepareWrite(); err != nil {
		return 0, 0, &OpError{"write", fd.net, fd.raddr, err}
	}
	for {
		err = syscall.Sendmsg(fd.sysfd, p, oob, sa, 0)
		if err == syscall.EAGAIN {
			if err = fd.pd.WaitWrite(); err == nil {
				continue
			}
		}
		break
	}
	if err == nil {
		n = len(p)
		oobn = len(oob)
	} else {
		err = &OpError{"write", fd.net, fd.raddr, err}
	}
	return
}
Beispiel #5
0
func qmpCommander(handler chan QmpInteraction, conn *net.UnixConn, session *QmpSession, feedback chan QmpInteraction) {
	glog.V(1).Info("Begin process command session")
	for _, cmd := range session.commands {
		msg, err := json.Marshal(*cmd)
		if err != nil {
			handler <- qmpFail("cannot marshal command", session.respond)
			return
		}

		success := false
		var qe *QmpError = nil
		for repeat := 0; !success && repeat < 3; repeat++ {

			if len(cmd.Scm) > 0 {
				glog.V(1).Infof("send cmd with scm (%d bytes) (%d) %s", len(cmd.Scm), repeat+1, string(msg))
				f, _ := conn.File()
				fd := f.Fd()
				syscall.Sendmsg(int(fd), msg, cmd.Scm, nil, 0)
			} else {
				glog.V(1).Infof("sending command (%d) %s", repeat+1, string(msg))
				conn.Write(msg)
			}

			res, ok := <-feedback
			if !ok {
				glog.Info("QMP command result chan closed")
				return
			}
			switch res.MessageType() {
			case QMP_RESULT:
				success = true
				break
			//success
			case QMP_ERROR:
				glog.Warning("got one qmp error")
				qe = res.(*QmpError)
				time.Sleep(1000 * time.Millisecond)
			case QMP_INTERNAL_ERROR:
				glog.Info("QMP quit... commander quit... ")
				return
			}
		}

		if !success {
			handler <- qe.Finish(session.respond)
			return
		}
	}
	handler <- session.Finish()
	return
}
Beispiel #6
0
func sendMsg(addr *net.UDPAddr, i int) {
	log.Printf("Start `sendMsg` test with %d iteration\n", i)

	laddr := UDPAddrToSockaddr(&net.UDPAddr{Port: local_port, IP: net.IPv4zero})
	raddr := UDPAddrToSockaddr(addr)

	fd := connectUDP(laddr, raddr)

	payload := make([]byte, payload_sz)
	for ; i > 0; i-- {
		err := syscall.Sendmsg(fd, payload, nil, raddr, syscall.MSG_DONTWAIT)
		chk(err)
	}
}
Beispiel #7
0
func Send(fd, sendfd int) os.Error {
	cmsglen := cmsgLen(int(unsafe.Sizeof(sendfd)))

	buf := make([]byte, cmsglen)
	cmsg := (*syscall.Cmsghdr)(unsafe.Pointer(&buf[0]))
	cmsg.Level = syscall.SOL_SOCKET
	cmsg.Type = syscall.SCM_RIGHTS
	cmsg.SetLen(cmsglen)
	*(*int)(unsafe.Pointer(&buf[cmsgLen(0)])) = sendfd

	errno := syscall.Sendmsg(fd, nil, buf, nil, 0)
	if errno != 0 {
		return fmt.Errorf("fdpass: Send: %v", os.Errno(errno))
	}
	return nil
}
Beispiel #8
0
// Put sends file descriptors to Unix domain socket.
//
// Please note that the number of descriptors in one message is limited
// and is rather small.
// Use conn.File() to get a file if you want to put a network connection.
func Put(via *net.UnixConn, files ...*os.File) error {
	if len(files) == 0 {
		return nil
	}

	viaf, err := via.File()
	if err != nil {
		return err
	}
	socket := int(viaf.Fd())
	defer viaf.Close()

	fds := make([]int, len(files))
	for i := range files {
		fds[i] = int(files[i].Fd())
	}

	rights := syscall.UnixRights(fds...)
	return syscall.Sendmsg(socket, nil, rights, nil, 0)
}