...
Run Format

Source file src/net/file_unix.go

     1	// Copyright 2011 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	// +build darwin dragonfly freebsd linux netbsd openbsd solaris
     6	
     7	package net
     8	
     9	import (
    10		"os"
    11		"syscall"
    12	)
    13	
    14	func dupSocket(f *os.File) (int, error) {
    15		s, err := dupCloseOnExec(int(f.Fd()))
    16		if err != nil {
    17			return -1, err
    18		}
    19		if err := syscall.SetNonblock(s, true); err != nil {
    20			closeFunc(s)
    21			return -1, os.NewSyscallError("setnonblock", err)
    22		}
    23		return s, nil
    24	}
    25	
    26	func newFileFD(f *os.File) (*netFD, error) {
    27		s, err := dupSocket(f)
    28		if err != nil {
    29			return nil, err
    30		}
    31		family := syscall.AF_UNSPEC
    32		sotype, err := syscall.GetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_TYPE)
    33		if err != nil {
    34			closeFunc(s)
    35			return nil, os.NewSyscallError("getsockopt", err)
    36		}
    37		lsa, _ := syscall.Getsockname(s)
    38		rsa, _ := syscall.Getpeername(s)
    39		switch lsa.(type) {
    40		case *syscall.SockaddrInet4:
    41			family = syscall.AF_INET
    42		case *syscall.SockaddrInet6:
    43			family = syscall.AF_INET6
    44		case *syscall.SockaddrUnix:
    45			family = syscall.AF_UNIX
    46		default:
    47			closeFunc(s)
    48			return nil, syscall.EPROTONOSUPPORT
    49		}
    50		fd, err := newFD(s, family, sotype, "")
    51		if err != nil {
    52			closeFunc(s)
    53			return nil, err
    54		}
    55		laddr := fd.addrFunc()(lsa)
    56		raddr := fd.addrFunc()(rsa)
    57		fd.net = laddr.Network()
    58		if err := fd.init(); err != nil {
    59			fd.Close()
    60			return nil, err
    61		}
    62		fd.setAddr(laddr, raddr)
    63		return fd, nil
    64	}
    65	
    66	func fileConn(f *os.File) (Conn, error) {
    67		fd, err := newFileFD(f)
    68		if err != nil {
    69			return nil, err
    70		}
    71		switch fd.laddr.(type) {
    72		case *TCPAddr:
    73			return newTCPConn(fd), nil
    74		case *UDPAddr:
    75			return newUDPConn(fd), nil
    76		case *IPAddr:
    77			return newIPConn(fd), nil
    78		case *UnixAddr:
    79			return newUnixConn(fd), nil
    80		}
    81		fd.Close()
    82		return nil, syscall.EINVAL
    83	}
    84	
    85	func fileListener(f *os.File) (Listener, error) {
    86		fd, err := newFileFD(f)
    87		if err != nil {
    88			return nil, err
    89		}
    90		switch laddr := fd.laddr.(type) {
    91		case *TCPAddr:
    92			return &TCPListener{fd}, nil
    93		case *UnixAddr:
    94			return &UnixListener{fd: fd, path: laddr.Name, unlink: false}, nil
    95		}
    96		fd.Close()
    97		return nil, syscall.EINVAL
    98	}
    99	
   100	func filePacketConn(f *os.File) (PacketConn, error) {
   101		fd, err := newFileFD(f)
   102		if err != nil {
   103			return nil, err
   104		}
   105		switch fd.laddr.(type) {
   106		case *UDPAddr:
   107			return newUDPConn(fd), nil
   108		case *IPAddr:
   109			return newIPConn(fd), nil
   110		case *UnixAddr:
   111			return newUnixConn(fd), nil
   112		}
   113		fd.Close()
   114		return nil, syscall.EINVAL
   115	}
   116	

View as plain text