package net
import (
"context"
"os"
"sync"
"syscall"
"time"
)
type UnixAddr struct {
Name string
Net string
}
func (a *UnixAddr ) Network () string {
return a .Net
}
func (a *UnixAddr ) String () string {
if a == nil {
return "<nil>"
}
return a .Name
}
func (a *UnixAddr ) isWildcard () bool {
return a == nil || a .Name == ""
}
func (a *UnixAddr ) opAddr () Addr {
if a == nil {
return nil
}
return a
}
func ResolveUnixAddr (network , address string ) (*UnixAddr , error ) {
switch network {
case "unix" , "unixgram" , "unixpacket" :
return &UnixAddr {Name : address , Net : network }, nil
default :
return nil , UnknownNetworkError (network )
}
}
type UnixConn struct {
conn
}
func (c *UnixConn ) SyscallConn () (syscall .RawConn , error ) {
if !c .ok () {
return nil , syscall .EINVAL
}
return newRawConn (c .fd ), nil
}
func (c *UnixConn ) CloseRead () error {
if !c .ok () {
return syscall .EINVAL
}
if err := c .fd .closeRead (); err != nil {
return &OpError {Op : "close" , Net : c .fd .net , Source : c .fd .laddr , Addr : c .fd .raddr , Err : err }
}
return nil
}
func (c *UnixConn ) CloseWrite () error {
if !c .ok () {
return syscall .EINVAL
}
if err := c .fd .closeWrite (); err != nil {
return &OpError {Op : "close" , Net : c .fd .net , Source : c .fd .laddr , Addr : c .fd .raddr , Err : err }
}
return nil
}
func (c *UnixConn ) ReadFromUnix (b []byte ) (int , *UnixAddr , error ) {
if !c .ok () {
return 0 , nil , syscall .EINVAL
}
n , addr , err := c .readFrom (b )
if err != nil {
err = &OpError {Op : "read" , Net : c .fd .net , Source : c .fd .laddr , Addr : c .fd .raddr , Err : err }
}
return n , addr , err
}
func (c *UnixConn ) ReadFrom (b []byte ) (int , Addr , error ) {
if !c .ok () {
return 0 , nil , syscall .EINVAL
}
n , addr , err := c .readFrom (b )
if err != nil {
err = &OpError {Op : "read" , Net : c .fd .net , Source : c .fd .laddr , Addr : c .fd .raddr , Err : err }
}
if addr == nil {
return n , nil , err
}
return n , addr , err
}
func (c *UnixConn ) ReadMsgUnix (b , oob []byte ) (n , oobn , flags int , addr *UnixAddr , err error ) {
if !c .ok () {
return 0 , 0 , 0 , nil , syscall .EINVAL
}
n , oobn , flags , addr , err = c .readMsg (b , oob )
if err != nil {
err = &OpError {Op : "read" , Net : c .fd .net , Source : c .fd .laddr , Addr : c .fd .raddr , Err : err }
}
return
}
func (c *UnixConn ) WriteToUnix (b []byte , addr *UnixAddr ) (int , error ) {
if !c .ok () {
return 0 , syscall .EINVAL
}
n , err := c .writeTo (b , addr )
if err != nil {
err = &OpError {Op : "write" , Net : c .fd .net , Source : c .fd .laddr , Addr : addr .opAddr (), Err : err }
}
return n , err
}
func (c *UnixConn ) WriteTo (b []byte , addr Addr ) (int , error ) {
if !c .ok () {
return 0 , syscall .EINVAL
}
a , ok := addr .(*UnixAddr )
if !ok {
return 0 , &OpError {Op : "write" , Net : c .fd .net , Source : c .fd .laddr , Addr : addr , Err : syscall .EINVAL }
}
n , err := c .writeTo (b , a )
if err != nil {
err = &OpError {Op : "write" , Net : c .fd .net , Source : c .fd .laddr , Addr : a .opAddr (), Err : err }
}
return n , err
}
func (c *UnixConn ) WriteMsgUnix (b , oob []byte , addr *UnixAddr ) (n , oobn int , err error ) {
if !c .ok () {
return 0 , 0 , syscall .EINVAL
}
n , oobn , err = c .writeMsg (b , oob , addr )
if err != nil {
err = &OpError {Op : "write" , Net : c .fd .net , Source : c .fd .laddr , Addr : addr .opAddr (), Err : err }
}
return
}
func newUnixConn(fd *netFD ) *UnixConn { return &UnixConn {conn {fd }} }
func DialUnix (network string , laddr , raddr *UnixAddr ) (*UnixConn , error ) {
switch network {
case "unix" , "unixgram" , "unixpacket" :
default :
return nil , &OpError {Op : "dial" , Net : network , Source : laddr .opAddr (), Addr : raddr .opAddr (), Err : UnknownNetworkError (network )}
}
sd := &sysDialer {network : network , address : raddr .String ()}
c , err := sd .dialUnix (context .Background (), laddr , raddr )
if err != nil {
return nil , &OpError {Op : "dial" , Net : network , Source : laddr .opAddr (), Addr : raddr .opAddr (), Err : err }
}
return c , nil
}
type UnixListener struct {
fd *netFD
path string
unlink bool
unlinkOnce sync .Once
}
func (ln *UnixListener ) ok () bool { return ln != nil && ln .fd != nil }
func (l *UnixListener ) SyscallConn () (syscall .RawConn , error ) {
if !l .ok () {
return nil , syscall .EINVAL
}
return newRawListener (l .fd ), nil
}
func (l *UnixListener ) AcceptUnix () (*UnixConn , error ) {
if !l .ok () {
return nil , syscall .EINVAL
}
c , err := l .accept ()
if err != nil {
return nil , &OpError {Op : "accept" , Net : l .fd .net , Source : nil , Addr : l .fd .laddr , Err : err }
}
return c , nil
}
func (l *UnixListener ) Accept () (Conn , error ) {
if !l .ok () {
return nil , syscall .EINVAL
}
c , err := l .accept ()
if err != nil {
return nil , &OpError {Op : "accept" , Net : l .fd .net , Source : nil , Addr : l .fd .laddr , Err : err }
}
return c , nil
}
func (l *UnixListener ) Close () error {
if !l .ok () {
return syscall .EINVAL
}
if err := l .close (); err != nil {
return &OpError {Op : "close" , Net : l .fd .net , Source : nil , Addr : l .fd .laddr , Err : err }
}
return nil
}
func (l *UnixListener ) Addr () Addr { return l .fd .laddr }
func (l *UnixListener ) SetDeadline (t time .Time ) error {
if !l .ok () {
return syscall .EINVAL
}
return l .fd .SetDeadline (t )
}
func (l *UnixListener ) File () (f *os .File , err error ) {
if !l .ok () {
return nil , syscall .EINVAL
}
f , err = l .file ()
if err != nil {
err = &OpError {Op : "file" , Net : l .fd .net , Source : nil , Addr : l .fd .laddr , Err : err }
}
return
}
func ListenUnix (network string , laddr *UnixAddr ) (*UnixListener , error ) {
switch network {
case "unix" , "unixpacket" :
default :
return nil , &OpError {Op : "listen" , Net : network , Source : nil , Addr : laddr .opAddr (), Err : UnknownNetworkError (network )}
}
if laddr == nil {
return nil , &OpError {Op : "listen" , Net : network , Source : nil , Addr : laddr .opAddr (), Err : errMissingAddress }
}
sl := &sysListener {network : network , address : laddr .String ()}
ln , err := sl .listenUnix (context .Background (), laddr )
if err != nil {
return nil , &OpError {Op : "listen" , Net : network , Source : nil , Addr : laddr .opAddr (), Err : err }
}
return ln , nil
}
func ListenUnixgram (network string , laddr *UnixAddr ) (*UnixConn , error ) {
switch network {
case "unixgram" :
default :
return nil , &OpError {Op : "listen" , Net : network , Source : nil , Addr : laddr .opAddr (), Err : UnknownNetworkError (network )}
}
if laddr == nil {
return nil , &OpError {Op : "listen" , Net : network , Source : nil , Addr : nil , Err : errMissingAddress }
}
sl := &sysListener {network : network , address : laddr .String ()}
c , err := sl .listenUnixgram (context .Background (), laddr )
if err != nil {
return nil , &OpError {Op : "listen" , Net : network , Source : nil , Addr : laddr .opAddr (), Err : err }
}
return c , nil
}
The pages are generated with Golds v0.7.0-preview . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .