...
Run Format

Source file src/net/rawconn_unix_test.go

Documentation: net

  // Copyright 2017 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.
  
  // +build darwin dragonfly freebsd linux netbsd openbsd solaris
  
  package net
  
  import (
  	"bytes"
  	"syscall"
  	"testing"
  )
  
  func TestRawConn(t *testing.T) {
  	handler := func(ls *localServer, ln Listener) {
  		c, err := ln.Accept()
  		if err != nil {
  			t.Error(err)
  			return
  		}
  		defer c.Close()
  		var b [32]byte
  		n, err := c.Read(b[:])
  		if err != nil {
  			t.Error(err)
  			return
  		}
  		if _, err := c.Write(b[:n]); err != nil {
  			t.Error(err)
  			return
  		}
  	}
  	ls, err := newLocalServer("tcp")
  	if err != nil {
  		t.Fatal(err)
  	}
  	defer ls.teardown()
  	if err := ls.buildup(handler); err != nil {
  		t.Fatal(err)
  	}
  
  	c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
  	if err != nil {
  		t.Fatal(err)
  	}
  	defer c.Close()
  	cc, err := c.(*TCPConn).SyscallConn()
  	if err != nil {
  		t.Fatal(err)
  	}
  
  	var operr error
  	data := []byte("HELLO-R-U-THERE")
  	err = cc.Write(func(s uintptr) bool {
  		_, operr = syscall.Write(int(s), data)
  		if operr == syscall.EAGAIN {
  			return false
  		}
  		return true
  	})
  	if err != nil || operr != nil {
  		t.Fatal(err, operr)
  	}
  
  	var nr int
  	var b [32]byte
  	err = cc.Read(func(s uintptr) bool {
  		nr, operr = syscall.Read(int(s), b[:])
  		if operr == syscall.EAGAIN {
  			return false
  		}
  		return true
  	})
  	if err != nil || operr != nil {
  		t.Fatal(err, operr)
  	}
  	if bytes.Compare(b[:nr], data) != 0 {
  		t.Fatalf("got %#v; want %#v", b[:nr], data)
  	}
  
  	fn := func(s uintptr) {
  		operr = syscall.SetsockoptInt(int(s), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
  	}
  	err = cc.Control(fn)
  	if err != nil || operr != nil {
  		t.Fatal(err, operr)
  	}
  	c.Close()
  	err = cc.Control(fn)
  	if err == nil {
  		t.Fatal("should fail")
  	}
  }
  

View as plain text