1 #define __EXTENSIONS__ 2 #define _BSD_COMPAT 3 #include <lib9.h> 4 #include <sys/types.h> 5 #include <sys/time.h> 6 #include <sys/socket.h> 7 #include <netinet/in.h> 8 9 #include "styxserver.h" 10 #include "styxaux.h" 11 12 typedef struct Fdset Fdset; 13 14 struct Fdset 15 { 16 fd_set infds, outfds, excfds, r_infds, r_outfds, r_excfds; 17 }; 18 19 int 20 styxinitsocket(void) 21 { 22 return 0; 23 } 24 25 void 26 styxendsocket(void) 27 { 28 } 29 30 void 31 styxclosesocket(int fd) 32 { 33 close(fd); 34 } 35 36 int 37 styxannounce(Styxserver *server, char *port) 38 { 39 struct sockaddr_in sin; 40 int s, one; 41 42 USED(server); 43 s = socket(AF_INET, SOCK_STREAM, 0); 44 if(s < 0) 45 return s; 46 one = 1; 47 if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(one)) < 0) 48 fprint(2, "setsockopt failed\n"); 49 memset(&sin, 0, sizeof(sin)); 50 sin.sin_family = AF_INET; 51 sin.sin_addr.s_addr = 0; 52 sin.sin_port = htons(atoi(port)); 53 if(bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0){ 54 close(s); 55 return -1; 56 } 57 if(listen(s, 20) < 0){ 58 close(s); 59 return -1; 60 } 61 return s; 62 } 63 64 int 65 styxaccept(Styxserver *server) 66 { 67 struct sockaddr_in sin; 68 int s; 69 socklen_t len; 70 71 len = sizeof(sin); 72 memset(&sin, 0, sizeof(sin)); 73 sin.sin_family = AF_INET; 74 s = accept(server->connfd, (struct sockaddr *)&sin, &len); 75 if(s < 0){ 76 if(errno != EINTR) 77 fprint(2, "error in accept: %s\n", strerror(errno)); 78 } 79 return s; 80 } 81 82 void 83 styxinitwait(Styxserver *server) 84 { 85 Fdset *fs; 86 87 server->priv = fs = malloc(sizeof(Fdset)); 88 FD_ZERO(&fs->infds); 89 FD_ZERO(&fs->outfds); 90 FD_ZERO(&fs->excfds); 91 FD_SET(server->connfd, &fs->infds); 92 } 93 94 int 95 styxnewcall(Styxserver *server) 96 { 97 Fdset *fs; 98 99 fs = server->priv; 100 return FD_ISSET(server->connfd, &fs->r_infds); 101 } 102 103 void 104 styxnewclient(Styxserver *server, int s) 105 { 106 Fdset *fs; 107 108 fs = server->priv; 109 FD_SET(s, &fs->infds); 110 } 111 112 void 113 styxfreeclient(Styxserver *server, int s) 114 { 115 Fdset *fs; 116 117 fs = server->priv; 118 FD_CLR(s, &fs->infds); 119 } 120 121 int 122 styxnewmsg(Styxserver *server, int s) 123 { 124 Fdset *fs; 125 126 fs = server->priv; 127 return FD_ISSET(s, &fs->r_infds) || FD_ISSET(s, &fs->r_excfds); 128 } 129 130 char* 131 styxwaitmsg(Styxserver *server) 132 { 133 struct timeval seltime; 134 int nfds; 135 Fdset *fs; 136 137 fs = server->priv; 138 fs->r_infds = fs->infds; 139 fs->r_outfds = fs->outfds; 140 fs->r_excfds = fs->excfds; 141 seltime.tv_sec = 10; 142 seltime.tv_usec = 0L; 143 nfds = select(sizeof(fd_set)*8, &fs->r_infds, &fs->r_outfds, &fs->r_excfds, &seltime); 144 if(nfds < 0 && errno != EINTR) 145 return"error in select"; 146 return nil; 147 } 148 149 int 150 styxrecv(Styxserver *server, int fd, char *buf, int n, int m) 151 { 152 return recv(fd, buf, n, m); 153 } 154 155 int 156 styxsend(Styxserver *server, int fd, char *buf, int n, int m) 157 { 158 return send(fd, buf, n, m); 159 } 160 161 void 162 styxexit(int n) 163 { 164 exit(n); 165 } 166