Mercurial > repos > tabletprog
comparison modules/socket.tp @ 370:57d78a0af132
Add code to socket module to allow listening for incoming connections
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 12 Aug 2015 19:13:31 -0700 |
parents | 4c96a393103e |
children |
comparison
equal
deleted
inserted
replaced
369:6b5096b07dd5 | 370:57d78a0af132 |
---|---|
39 } andCode: :domain type protocol { | 39 } andCode: :domain type protocol { |
40 fd <- make_object: (addr_of: obj_int32_meta) NULL 0 | 40 fd <- make_object: (addr_of: obj_int32_meta) NULL 0 |
41 fd num!: (socket: (domain num) (type num) (protocol num)) | 41 fd num!: (socket: (domain num) (type num) (protocol num)) |
42 fd | 42 fd |
43 } | 43 } |
44 | 44 |
45 new <- :domain type protocol { | 45 _sock_obj <- :sfd { |
46 sfd <- socket: domain type protocol | |
47 #{ | 46 #{ |
48 fd <- {sfd} | 47 fd <- {sfd} |
49 | 48 |
50 llMessage: close withVars: { | 49 llMessage: close withVars: { |
51 sfd <- obj_int32 ptr | 50 sfd <- obj_int32 ptr |
110 } | 109 } |
111 } | 110 } |
112 received | 111 received |
113 } | 112 } |
114 } | 113 } |
114 } | |
115 | |
116 _accept_sock <- :domain type protocol { | |
117 sfd <- socket: domain type protocol | |
118 #{ | |
119 fd <- {sfd} | |
120 | |
121 llMessage: close withVars: { | |
122 sfd <- obj_int32 ptr | |
123 } andCode: { | |
124 sfd <- mcall: fd 1 self | |
125 close: (sfd num) | |
126 self | |
127 } | |
128 | |
129 llMessage: accept withVars: { | |
130 sfd <- obj_int32 ptr | |
131 newfd <- obj_int32 ptr | |
132 } andCode: { | |
133 sfd <- mcall: fd 1 self | |
134 newfd <- make_object: (addr_of: obj_int32_meta) NULL 0 | |
135 //TODO: expose peer address | |
136 newfd num!: (accept: (sfd num) NULL NULL) | |
137 if: (newfd num) >= 0 { | |
138 mcall: value 2 option (mcall: _sock_obj 2 socket newfd) | |
139 } else: { | |
140 mcall: none 1 option | |
141 } | |
142 } | |
143 } | |
144 } | |
145 | |
146 new <- :domain type protocol { | |
147 sfd <- socket: domain type protocol | |
148 _sock_obj: sfd | |
115 } | 149 } |
116 | 150 |
117 llMessage: _connectTo:onPort withVars: { | 151 llMessage: _connectTo:onPort withVars: { |
118 host <- string ptr | 152 host <- string ptr |
119 port <- string ptr | 153 port <- string ptr |
143 connect: (sfd num) (info ai_addr) (info ai_addrlen) | 177 connect: (sfd num) (info ai_addr) (info ai_addrlen) |
144 | 178 |
145 freeaddrinfo: info | 179 freeaddrinfo: info |
146 sock | 180 sock |
147 } | 181 } |
182 | |
148 | 183 |
149 connectTo:onPort <- :host :port { | 184 connectTo:onPort <- :host :port { |
150 _connectTo: host onPort: (string: port) | 185 _connectTo: host onPort: (string: port) |
151 } | 186 } |
152 listenOn <- :port { | 187 llMessage: listenAt:onPort withVars: { |
153 } | 188 ohost <- object ptr |
154 listenAt:onPort <- :host :port { | 189 host <- string ptr |
190 oport <- object ptr | |
191 port <- string ptr | |
192 hints <- struct: addrinfo | |
193 info <- (struct: addrinfo) ptr | |
194 curinfo <- (struct: addrinfo) ptr | |
195 domain <- obj_int32 ptr | |
196 type <- obj_int32 ptr | |
197 protocol <- obj_int32 ptr | |
198 sock <- object ptr | |
199 sfd <- obj_int32 ptr | |
200 result <- int32_t | |
201 hstr <- uint8_t ptr | |
202 } andCode: :ohost :oport { | |
203 host <- (mcall: string 1 ohost) castTo: (string ptr) | |
204 port <- (mcall: string 1 oport) castTo: (string ptr) | |
205 memset: (addr_of: hints) 0 (sizeof: hints) | |
206 hints ai_family!: AF_UNSPEC | |
207 hints ai_socktype!: SOCK_STREAM | |
208 hints ai_flags!: AI_PASSIVE | |
209 hints ai_protocol!: 0 | |
210 hints ai_canonname!: NULL | |
211 hints ai_addr!: NULL | |
212 hints ai_next!: NULL | |
213 result <- getaddrinfo | |
214 if: (host bytes) = 0 { | |
215 hstr <- NULL | |
216 } else: { | |
217 hstr <- host data | |
218 } | |
219 result <- getaddrinfo: hstr (port data) (addr_of: hints) (addr_of: info) | |
220 if: result = 0 { | |
221 curinfo <- info | |
222 domain <- make_object: (addr_of: obj_int32_meta) NULL 0 | |
223 type <- make_object: (addr_of: obj_int32_meta) NULL 0 | |
224 protocol <- make_object: (addr_of: obj_int32_meta) NULL 0 | |
225 while: { curinfo != NULL } do: { | |
226 domain num!: (curinfo ai_family) | |
227 type num!: (curinfo ai_socktype) | |
228 protocol num!: (curinfo ai_protocol) | |
229 sock <- mcall: _accept_sock 4 self domain type protocol | |
230 sfd <- (mcall: fd 1 sock) castTo: (obj_int32 ptr) | |
231 if: (sfd num) != -1 { | |
232 result <- bind: (sfd num) (curinfo ai_addr) (curinfo ai_addrlen) | |
233 if: result = 0 { | |
234 curinfo <- NULL | |
235 } else: { | |
236 //failed to bind, close this socket so we can try again | |
237 close: (sfd num) | |
238 sock <- NULL | |
239 } | |
240 } | |
241 } | |
242 if: sock { | |
243 listen: (sfd num) 8 | |
244 mcall: value 2 option sock | |
245 } else: { | |
246 mcall: none 1 option | |
247 } | |
248 } else: { | |
249 mcall: none 1 option | |
250 } | |
251 } | |
252 | |
253 listenOnPort <- :port { | |
254 listenAt: "" onPort: port | |
155 } | 255 } |
156 } | 256 } |