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 }
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 }
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 }
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 }
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 }
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) } }
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 }
// 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) }