ref: d2a28cc46d5101760733f1b831287f6b9fcf1be1
dir: /lib/std/dial+posixy.myr/
use sys use "alloc" use "chartype" use "dialparse" use "die" use "endian" use "option" use "result" use "slcp" use "sleq" use "strfind" use "striter" use "syswrap" use "utf" pkg std = const dial : (ds : byte[:] -> result(fd, byte[:])) ;; /* a map from service name to a list of (port,proto) pairs in order of preference */ /* FIXME: implement var services : htab(byte[:], [int, byte[:]][:])# var inited = false */ /* takes a plan 9 style dial string */ const dial = {ds match nameseg(ds) | `Some ("tcp", str): -> dialsock(sys.Sockstream, str) | `Some ("udp", str): -> dialsock(sys.Sockdgram, str) | `Some ("unix", u): -> dialunix(u) | `Some (proto, str): -> `Fail "unknown protocol" | `None: -> `Fail "missing protocol" ;; } const dialsock = {proto, str var sa4 : sys.sockaddr_in var sa6 : sys.sockaddr_in6 var sa : sys.sockaddr# var hoststr, portstr, port var sock, sz var err match nameseg(str) | `None: -> `Fail "required host!port for ip dial" | `Some ("", _): -> `Fail "empty host" | `Some (_, ""): -> `Fail "empty port" | `Some segs: (hoststr, portstr) = segs ;; match parseport(portstr) | `Some p: port = p | `None: -> `Fail("invalid port") ;; match getaddr(hoststr) | `Ok `Ipv4 bits: sa4=[.fam=sys.Afinet, .addr=bits, .port=hosttonet(port)] sa = &sa4 castto(sys.sockaddr#) sz = sizeof(sys.sockaddr_in) | `Ok `Ipv6 bits: sa6=[.fam=sys.Afinet6, .addr=bits, .port=hosttonet(port)] sa = &sa6 castto(sys.sockaddr#) sz = sizeof(sys.sockaddr_in6) | `Fail m: -> `Fail m ;; sock = sys.socket(sa.fam, proto, 0) if sock < 0 -> `Fail "failed to create socket" ;; err = sys.connect(sock, sa, sz) if err < 0 sys.close(sock) -> `Fail "Failed to bind socket" ;; -> `Ok (sock castto(fd)) } const dialunix = {path var sa : sys.sockaddr_un var sock sa = [.fam = sys.Afunix] if path.len >= sa.path.len -> `Fail "path too long" ;; sock = sys.socket(sys.Afunix, sys.Sockstream, 0) if sock < 0 -> `Fail "failed to create socket" ;; slcp(sa.path[:path.len], path) if sys.connect(sock, &sa castto(sys.sockaddr#), sizeof(sys.sockaddr_un)) < 0 -> `Fail "failed to bind address" ;; -> `Ok (sock castto(fd)) }