5 #include <sys/socket.h>
6 #include <netinet/in.h>
7 #include <netinet/tcp.h>
19 if(strncmp(dir, "/dev/fd/", 8) != 0)
21 fd = strtol(dir+8, &dir, 0);
28 putfd(char *dir, int fd)
30 snprint(dir, NETPATHLEN, "/dev/fd/%d", fd);
37 addrlen(struct sockaddr_storage *ss)
39 switch(ss->ss_family){
41 return sizeof(struct sockaddr_in);
43 return sizeof(struct sockaddr_in6);
45 return sizeof(struct sockaddr_un);
51 p9announce(char *addr, char *dir)
59 struct sockaddr_storage ss;
65 if(p9dialparse(buf, &net, &unix, &ss, &port) < 0){
69 if(strcmp(net, "tcp") == 0)
71 else if(strcmp(net, "udp") == 0)
73 else if(strcmp(net, "unix") == 0)
76 werrstr("can only handle tcp, udp, and unix: not %s", net);
82 if((s = socket(ss.ss_family, proto, 0)) < 0)
85 if(port && getsockopt(s, SOL_SOCKET, SO_TYPE, (void*)&n, &sn) >= 0
88 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&n, sizeof n);
90 if(bind(s, (struct sockaddr*)&ss, addrlen(&ss)) < 0){
94 if(proto == SOCK_STREAM){
101 if((s = socket(ss.ss_family, SOCK_STREAM, 0)) < 0)
103 if(bind(s, (struct sockaddr*)&ss, addrlen(&ss)) < 0){
104 if(errno == EADDRINUSE
105 && connect(s, (struct sockaddr*)&ss, addrlen(&ss)) < 0
106 && errno == ECONNREFUSED){
107 /* dead socket, so remove it */
110 if((s = socket(ss.ss_family, SOCK_STREAM, 0)) < 0)
112 if(bind(s, (struct sockaddr*)&ss, addrlen(&ss)) >= 0)
125 p9listen(char *dir, char *newdir)
129 if((fd = _p9netfd(dir)) < 0){
130 werrstr("bad 'directory' in listen: %s", dir);
134 if((fd = accept(fd, nil, nil)) < 0)
138 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof one);
145 p9accept(int cfd, char *dir)
149 if((fd = _p9netfd(dir)) < 0){
150 werrstr("bad 'directory' in accept");
153 /* need to dup because the listen fd will be closed */