diff options
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/u_pdreceive.c')
-rw-r--r-- | apps/plugins/pdbox/PDa/src/u_pdreceive.c | 650 |
1 files changed, 650 insertions, 0 deletions
diff --git a/apps/plugins/pdbox/PDa/src/u_pdreceive.c b/apps/plugins/pdbox/PDa/src/u_pdreceive.c new file mode 100644 index 0000000000..3ec097edcc --- /dev/null +++ b/apps/plugins/pdbox/PDa/src/u_pdreceive.c | |||
@@ -0,0 +1,650 @@ | |||
1 | /* Copyright (c) 2000 Miller Puckette. | ||
2 | * For information on usage and redistribution, and for a DISCLAIMER OF ALL | ||
3 | * WARRANTIES, see the file, "LICENSE.txt," in the Pd distribution. */ | ||
4 | |||
5 | /* the "pdreceive" command. This is a standalone program that receives messages | ||
6 | from Pd via the netsend/netreceive ("FUDI") protocol, and copies them to | ||
7 | standard output. */ | ||
8 | |||
9 | #include <sys/types.h> | ||
10 | #include <string.h> | ||
11 | #include <stdio.h> | ||
12 | #include <errno.h> | ||
13 | #include <stdlib.h> | ||
14 | #ifdef UNIX | ||
15 | #include <sys/time.h> | ||
16 | #include <unistd.h> | ||
17 | #include <sys/socket.h> | ||
18 | #include <netinet/in.h> | ||
19 | #include <netdb.h> | ||
20 | #define SOCKET_ERROR -1 | ||
21 | #else | ||
22 | #include <winsock.h> | ||
23 | #endif | ||
24 | |||
25 | typedef struct _fdpoll | ||
26 | { | ||
27 | int fdp_fd; | ||
28 | char *fdp_inbuf; | ||
29 | int fdp_inhead; | ||
30 | int fdp_intail; | ||
31 | int fdp_udp; | ||
32 | } t_fdpoll; | ||
33 | |||
34 | static int nfdpoll; | ||
35 | static t_fdpoll *fdpoll; | ||
36 | static int maxfd; | ||
37 | static int sockfd; | ||
38 | static int protocol; | ||
39 | |||
40 | static void sockerror(char *s); | ||
41 | static void x_closesocket(int fd); | ||
42 | static void dopoll(void); | ||
43 | #define BUFSIZE 4096 | ||
44 | |||
45 | int main(int argc, char **argv) | ||
46 | { | ||
47 | int portno; | ||
48 | struct sockaddr_in server; | ||
49 | int nretry = 10; | ||
50 | #ifdef MSW | ||
51 | short version = MAKEWORD(2, 0); | ||
52 | WSADATA nobby; | ||
53 | #endif | ||
54 | if (argc < 2 || sscanf(argv[1], "%d", &portno) < 1 || portno <= 0) | ||
55 | goto usage; | ||
56 | if (argc >= 3) | ||
57 | { | ||
58 | if (!strcmp(argv[2], "tcp")) | ||
59 | protocol = SOCK_STREAM; | ||
60 | else if (!strcmp(argv[2], "udp")) | ||
61 | protocol = SOCK_DGRAM; | ||
62 | else goto usage; | ||
63 | } | ||
64 | else protocol = SOCK_STREAM; | ||
65 | #ifdef MSW | ||
66 | if (WSAStartup(version, &nobby)) sockerror("WSAstartup"); | ||
67 | #endif | ||
68 | sockfd = socket(AF_INET, protocol, 0); | ||
69 | if (sockfd < 0) | ||
70 | { | ||
71 | sockerror("socket()"); | ||
72 | exit(1); | ||
73 | } | ||
74 | maxfd = sockfd + 1; | ||
75 | server.sin_family = AF_INET; | ||
76 | server.sin_addr.s_addr = INADDR_ANY; | ||
77 | |||
78 | #ifdef IRIX | ||
79 | /* this seems to work only in IRIX but is unnecessary in | ||
80 | Linux. Not sure what MSW needs in place of this. */ | ||
81 | if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 0, 0) < 0) | ||
82 | post("setsockopt failed\n"); | ||
83 | #endif | ||
84 | |||
85 | /* assign client port number */ | ||
86 | server.sin_port = htons((unsigned short)portno); | ||
87 | |||
88 | /* name the socket */ | ||
89 | if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) | ||
90 | { | ||
91 | sockerror("bind"); | ||
92 | x_closesocket(sockfd); | ||
93 | return (0); | ||
94 | } | ||
95 | if (protocol == SOCK_STREAM) | ||
96 | { | ||
97 | if (listen(sockfd, 5) < 0) | ||
98 | { | ||
99 | sockerror("listen"); | ||
100 | x_closesocket(sockfd); | ||
101 | exit(1); | ||
102 | } | ||
103 | } | ||
104 | /* now loop forever selecting on sockets */ | ||
105 | while (1) | ||
106 | dopoll(); | ||
107 | |||
108 | usage: | ||
109 | fprintf(stderr, "usage: pdreceive <portnumber> [udp|tcp]\n"); | ||
110 | fprintf(stderr, "(default is tcp)\n"); | ||
111 | exit(1); | ||
112 | } | ||
113 | |||
114 | static void addport(int fd) | ||
115 | { | ||
116 | int nfd = nfdpoll; | ||
117 | t_fdpoll *fp; | ||
118 | fdpoll = (t_fdpoll *)realloc(fdpoll, | ||
119 | (nfdpoll+1) * sizeof(t_fdpoll)); | ||
120 | fp = fdpoll + nfdpoll; | ||
121 | fp->fdp_fd = fd; | ||
122 | nfdpoll++; | ||
123 | if (fd >= maxfd) maxfd = fd + 1; | ||
124 | fp->fdp_inhead = fp->fdp_intail = 0; | ||
125 | if (!(fp->fdp_inbuf = malloc(BUFSIZE))) | ||
126 | { | ||
127 | fprintf(stderr, "out of memory"); | ||
128 | exit(1); | ||
129 | } | ||
130 | printf("number_connected %d;\n", nfdpoll); | ||
131 | } | ||
132 | |||
133 | static void rmport(t_fdpoll *x) | ||
134 | { | ||
135 | int nfd = nfdpoll; | ||
136 | int i, size = nfdpoll * sizeof(t_fdpoll); | ||
137 | t_fdpoll *fp; | ||
138 | for (i = nfdpoll, fp = fdpoll; i--; fp++) | ||
139 | { | ||
140 | if (fp == x) | ||
141 | { | ||
142 | x_closesocket(fp->fdp_fd); | ||
143 | free(fp->fdp_inbuf); | ||
144 | while (i--) | ||
145 | { | ||
146 | fp[0] = fp[1]; | ||
147 | fp++; | ||
148 | } | ||
149 | fdpoll = (t_fdpoll *)realloc(fdpoll, | ||
150 | (nfdpoll-1) * sizeof(t_fdpoll)); | ||
151 | nfdpoll--; | ||
152 | printf("number_connected %d;\n", nfdpoll); | ||
153 | return; | ||
154 | } | ||
155 | } | ||
156 | fprintf(stderr, "warning: item removed from poll list but not found"); | ||
157 | } | ||
158 | |||
159 | static void doconnect(void) | ||
160 | { | ||
161 | int fd = accept(sockfd, 0, 0); | ||
162 | if (fd < 0) | ||
163 | perror("accept"); | ||
164 | else addport(fd); | ||
165 | } | ||
166 | |||
167 | static void udpread(void) | ||
168 | { | ||
169 | char buf[BUFSIZE]; | ||
170 | int ret = recv(sockfd, buf, BUFSIZE, 0); | ||
171 | if (ret < 0) | ||
172 | { | ||
173 | sockerror("recv (udp)"); | ||
174 | x_closesocket(sockfd); | ||
175 | exit(1); | ||
176 | } | ||
177 | else if (ret > 0) | ||
178 | { | ||
179 | #ifdef UNIX | ||
180 | if (write(1, buf, ret) < ret) | ||
181 | { | ||
182 | perror("write"); | ||
183 | exit(1); | ||
184 | } | ||
185 | #else | ||
186 | int j; | ||
187 | for (j = 0; j < ret; j++) | ||
188 | putchar(buf[j]); | ||
189 | #endif | ||
190 | } | ||
191 | } | ||
192 | |||
193 | static int tcpmakeoutput(t_fdpoll *x) | ||
194 | { | ||
195 | char messbuf[BUFSIZE+1], *bp = messbuf; | ||
196 | int indx; | ||
197 | int inhead = x->fdp_inhead; | ||
198 | int intail = x->fdp_intail; | ||
199 | char *inbuf = x->fdp_inbuf; | ||
200 | if (intail == inhead) | ||
201 | return (0); | ||
202 | for (indx = intail; indx != inhead; indx = (indx+1)&(BUFSIZE-1)) | ||
203 | { | ||
204 | /* search for a semicolon. */ | ||
205 | char c = *bp++ = inbuf[indx]; | ||
206 | if (c == ';') | ||
207 | { | ||
208 | intail = (indx+1)&(BUFSIZE-1); | ||
209 | if (inbuf[intail] == '\n') | ||
210 | intail = (intail+1)&(BUFSIZE-1); | ||
211 | *bp++ = '\n'; | ||
212 | #ifdef UNIX | ||
213 | write(1, messbuf, bp - messbuf); | ||
214 | #else | ||
215 | { | ||
216 | int j; | ||
217 | for (j = 0; j < bp - messbuf; j++) | ||
218 | putchar(messbuf[j]); | ||
219 | } | ||
220 | #endif | ||
221 | x->fdp_inhead = inhead; | ||
222 | x->fdp_intail = intail; | ||
223 | return (1); | ||
224 | } | ||
225 | } | ||
226 | return (0); | ||
227 | } | ||
228 | |||
229 | static void tcpread(t_fdpoll *x) | ||
230 | { | ||
231 | int readto = | ||
232 | (x->fdp_inhead >= x->fdp_intail ? BUFSIZE : x->fdp_intail-1); | ||
233 | int ret; | ||
234 | |||
235 | /* the input buffer might be full. If so, drop the whole thing */ | ||
236 | if (readto == x->fdp_inhead) | ||
237 | { | ||
238 | fprintf(stderr, "pd: dropped message from gui\n"); | ||
239 | x->fdp_inhead = x->fdp_intail = 0; | ||
240 | readto = BUFSIZE; | ||
241 | } | ||
242 | else | ||
243 | { | ||
244 | ret = recv(x->fdp_fd, x->fdp_inbuf + x->fdp_inhead, | ||
245 | readto - x->fdp_inhead, 0); | ||
246 | if (ret < 0) | ||
247 | { | ||
248 | sockerror("recv (tcp)"); | ||
249 | rmport(x); | ||
250 | } | ||
251 | else if (ret == 0) | ||
252 | rmport(x); | ||
253 | else | ||
254 | { | ||
255 | x->fdp_inhead += ret; | ||
256 | if (x->fdp_inhead >= BUFSIZE) | ||
257 | x->fdp_inhead = 0; | ||
258 | while (tcpmakeoutput(x)) | ||
259 | ; | ||
260 | } | ||
261 | } | ||
262 | } | ||
263 | |||
264 | static void dopoll(void) | ||
265 | { | ||
266 | int i; | ||
267 | t_fdpoll *fp; | ||
268 | fd_set readset, writeset, exceptset; | ||
269 | FD_ZERO(&writeset); | ||
270 | FD_ZERO(&readset); | ||
271 | FD_ZERO(&exceptset); | ||
272 | |||
273 | FD_SET(sockfd, &readset); | ||
274 | if (protocol == SOCK_STREAM) | ||
275 | { | ||
276 | for (fp = fdpoll, i = nfdpoll; i--; fp++) | ||
277 | FD_SET(fp->fdp_fd, &readset); | ||
278 | } | ||
279 | if (select(maxfd+1, &readset, &writeset, &exceptset, 0) < 0) | ||
280 | { | ||
281 | perror("select"); | ||
282 | exit(1); | ||
283 | } | ||
284 | if (protocol == SOCK_STREAM) | ||
285 | { | ||
286 | for (i = 0; i < nfdpoll; i++) | ||
287 | if (FD_ISSET(fdpoll[i].fdp_fd, &readset)) | ||
288 | tcpread(&fdpoll[i]); | ||
289 | if (FD_ISSET(sockfd, &readset)) | ||
290 | doconnect(); | ||
291 | } | ||
292 | else | ||
293 | { | ||
294 | if (FD_ISSET(sockfd, &readset)) | ||
295 | udpread(); | ||
296 | } | ||
297 | } | ||
298 | |||
299 | |||
300 | static void sockerror(char *s) | ||
301 | { | ||
302 | #ifdef MSW | ||
303 | int err = WSAGetLastError(); | ||
304 | if (err == 10054) return; | ||
305 | else if (err == 10044) | ||
306 | { | ||
307 | fprintf(stderr, | ||
308 | "Warning: you might not have TCP/IP \"networking\" turned on\n"); | ||
309 | } | ||
310 | #endif | ||
311 | #ifdef UNIX | ||
312 | int err = errno; | ||
313 | #endif | ||
314 | fprintf(stderr, "%s: %s (%d)\n", s, strerror(err), err); | ||
315 | } | ||
316 | |||
317 | static void x_closesocket(int fd) | ||
318 | { | ||
319 | #ifdef UNIX | ||
320 | close(fd); | ||
321 | #endif | ||
322 | #ifdef MSW | ||
323 | closesocket(fd); | ||
324 | #endif | ||
325 | } | ||
326 | /* Copyright (c) 2000 Miller Puckette. | ||
327 | * For information on usage and redistribution, and for a DISCLAIMER OF ALL | ||
328 | * WARRANTIES, see the file, "LICENSE.txt," in the Pd distribution. */ | ||
329 | |||
330 | /* the "pdreceive" command. This is a standalone program that receives messages | ||
331 | from Pd via the netsend/netreceive ("FUDI") protocol, and copies them to | ||
332 | standard output. */ | ||
333 | |||
334 | #include <sys/types.h> | ||
335 | #include <string.h> | ||
336 | #include <stdio.h> | ||
337 | #include <errno.h> | ||
338 | #include <stdlib.h> | ||
339 | #ifdef UNIX | ||
340 | #include <sys/time.h> | ||
341 | #include <unistd.h> | ||
342 | #include <sys/socket.h> | ||
343 | #include <netinet/in.h> | ||
344 | #include <netdb.h> | ||
345 | #define SOCKET_ERROR -1 | ||
346 | #else | ||
347 | #include <winsock.h> | ||
348 | #endif | ||
349 | |||
350 | typedef struct _fdpoll | ||
351 | { | ||
352 | int fdp_fd; | ||
353 | char *fdp_inbuf; | ||
354 | int fdp_inhead; | ||
355 | int fdp_intail; | ||
356 | int fdp_udp; | ||
357 | } t_fdpoll; | ||
358 | |||
359 | static int nfdpoll; | ||
360 | static t_fdpoll *fdpoll; | ||
361 | static int maxfd; | ||
362 | static int sockfd; | ||
363 | static int protocol; | ||
364 | |||
365 | static void sockerror(char *s); | ||
366 | static void x_closesocket(int fd); | ||
367 | static void dopoll(void); | ||
368 | #define BUFSIZE 4096 | ||
369 | |||
370 | int main(int argc, char **argv) | ||
371 | { | ||
372 | int portno; | ||
373 | struct sockaddr_in server; | ||
374 | int nretry = 10; | ||
375 | #ifdef MSW | ||
376 | short version = MAKEWORD(2, 0); | ||
377 | WSADATA nobby; | ||
378 | #endif | ||
379 | if (argc < 2 || sscanf(argv[1], "%d", &portno) < 1 || portno <= 0) | ||
380 | goto usage; | ||
381 | if (argc >= 3) | ||
382 | { | ||
383 | if (!strcmp(argv[2], "tcp")) | ||
384 | protocol = SOCK_STREAM; | ||
385 | else if (!strcmp(argv[2], "udp")) | ||
386 | protocol = SOCK_DGRAM; | ||
387 | else goto usage; | ||
388 | } | ||
389 | else protocol = SOCK_STREAM; | ||
390 | #ifdef MSW | ||
391 | if (WSAStartup(version, &nobby)) sockerror("WSAstartup"); | ||
392 | #endif | ||
393 | sockfd = socket(AF_INET, protocol, 0); | ||
394 | if (sockfd < 0) | ||
395 | { | ||
396 | sockerror("socket()"); | ||
397 | exit(1); | ||
398 | } | ||
399 | maxfd = sockfd + 1; | ||
400 | server.sin_family = AF_INET; | ||
401 | server.sin_addr.s_addr = INADDR_ANY; | ||
402 | |||
403 | #ifdef IRIX | ||
404 | /* this seems to work only in IRIX but is unnecessary in | ||
405 | Linux. Not sure what MSW needs in place of this. */ | ||
406 | if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 0, 0) < 0) | ||
407 | post("setsockopt failed\n"); | ||
408 | #endif | ||
409 | |||
410 | /* assign client port number */ | ||
411 | server.sin_port = htons((unsigned short)portno); | ||
412 | |||
413 | /* name the socket */ | ||
414 | if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) | ||
415 | { | ||
416 | sockerror("bind"); | ||
417 | x_closesocket(sockfd); | ||
418 | return (0); | ||
419 | } | ||
420 | if (protocol == SOCK_STREAM) | ||
421 | { | ||
422 | if (listen(sockfd, 5) < 0) | ||
423 | { | ||
424 | sockerror("listen"); | ||
425 | x_closesocket(sockfd); | ||
426 | exit(1); | ||
427 | } | ||
428 | } | ||
429 | /* now loop forever selecting on sockets */ | ||
430 | while (1) | ||
431 | dopoll(); | ||
432 | |||
433 | usage: | ||
434 | fprintf(stderr, "usage: pdreceive <portnumber> [udp|tcp]\n"); | ||
435 | fprintf(stderr, "(default is tcp)\n"); | ||
436 | exit(1); | ||
437 | } | ||
438 | |||
439 | static void addport(int fd) | ||
440 | { | ||
441 | int nfd = nfdpoll; | ||
442 | t_fdpoll *fp; | ||
443 | fdpoll = (t_fdpoll *)realloc(fdpoll, | ||
444 | (nfdpoll+1) * sizeof(t_fdpoll)); | ||
445 | fp = fdpoll + nfdpoll; | ||
446 | fp->fdp_fd = fd; | ||
447 | nfdpoll++; | ||
448 | if (fd >= maxfd) maxfd = fd + 1; | ||
449 | fp->fdp_inhead = fp->fdp_intail = 0; | ||
450 | if (!(fp->fdp_inbuf = malloc(BUFSIZE))) | ||
451 | { | ||
452 | fprintf(stderr, "out of memory"); | ||
453 | exit(1); | ||
454 | } | ||
455 | printf("number_connected %d;\n", nfdpoll); | ||
456 | } | ||
457 | |||
458 | static void rmport(t_fdpoll *x) | ||
459 | { | ||
460 | int nfd = nfdpoll; | ||
461 | int i, size = nfdpoll * sizeof(t_fdpoll); | ||
462 | t_fdpoll *fp; | ||
463 | for (i = nfdpoll, fp = fdpoll; i--; fp++) | ||
464 | { | ||
465 | if (fp == x) | ||
466 | { | ||
467 | x_closesocket(fp->fdp_fd); | ||
468 | free(fp->fdp_inbuf); | ||
469 | while (i--) | ||
470 | { | ||
471 | fp[0] = fp[1]; | ||
472 | fp++; | ||
473 | } | ||
474 | fdpoll = (t_fdpoll *)realloc(fdpoll, | ||
475 | (nfdpoll-1) * sizeof(t_fdpoll)); | ||
476 | nfdpoll--; | ||
477 | printf("number_connected %d;\n", nfdpoll); | ||
478 | return; | ||
479 | } | ||
480 | } | ||
481 | fprintf(stderr, "warning: item removed from poll list but not found"); | ||
482 | } | ||
483 | |||
484 | static void doconnect(void) | ||
485 | { | ||
486 | int fd = accept(sockfd, 0, 0); | ||
487 | if (fd < 0) | ||
488 | perror("accept"); | ||
489 | else addport(fd); | ||
490 | } | ||
491 | |||
492 | static void udpread(void) | ||
493 | { | ||
494 | char buf[BUFSIZE]; | ||
495 | int ret = recv(sockfd, buf, BUFSIZE, 0); | ||
496 | if (ret < 0) | ||
497 | { | ||
498 | sockerror("recv (udp)"); | ||
499 | x_closesocket(sockfd); | ||
500 | exit(1); | ||
501 | } | ||
502 | else if (ret > 0) | ||
503 | { | ||
504 | #ifdef UNIX | ||
505 | if (write(1, buf, ret) < ret) | ||
506 | { | ||
507 | perror("write"); | ||
508 | exit(1); | ||
509 | } | ||
510 | #else | ||
511 | int j; | ||
512 | for (j = 0; j < ret; j++) | ||
513 | putchar(buf[j]); | ||
514 | #endif | ||
515 | } | ||
516 | } | ||
517 | |||
518 | static int tcpmakeoutput(t_fdpoll *x) | ||
519 | { | ||
520 | char messbuf[BUFSIZE+1], *bp = messbuf; | ||
521 | int indx; | ||
522 | int inhead = x->fdp_inhead; | ||
523 | int intail = x->fdp_intail; | ||
524 | char *inbuf = x->fdp_inbuf; | ||
525 | if (intail == inhead) | ||
526 | return (0); | ||
527 | for (indx = intail; indx != inhead; indx = (indx+1)&(BUFSIZE-1)) | ||
528 | { | ||
529 | /* search for a semicolon. */ | ||
530 | char c = *bp++ = inbuf[indx]; | ||
531 | if (c == ';') | ||
532 | { | ||
533 | intail = (indx+1)&(BUFSIZE-1); | ||
534 | if (inbuf[intail] == '\n') | ||
535 | intail = (intail+1)&(BUFSIZE-1); | ||
536 | *bp++ = '\n'; | ||
537 | #ifdef UNIX | ||
538 | write(1, messbuf, bp - messbuf); | ||
539 | #else | ||
540 | { | ||
541 | int j; | ||
542 | for (j = 0; j < bp - messbuf; j++) | ||
543 | putchar(messbuf[j]); | ||
544 | } | ||
545 | #endif | ||
546 | x->fdp_inhead = inhead; | ||
547 | x->fdp_intail = intail; | ||
548 | return (1); | ||
549 | } | ||
550 | } | ||
551 | return (0); | ||
552 | } | ||
553 | |||
554 | static void tcpread(t_fdpoll *x) | ||
555 | { | ||
556 | int readto = | ||
557 | (x->fdp_inhead >= x->fdp_intail ? BUFSIZE : x->fdp_intail-1); | ||
558 | int ret; | ||
559 | |||
560 | /* the input buffer might be full. If so, drop the whole thing */ | ||
561 | if (readto == x->fdp_inhead) | ||
562 | { | ||
563 | fprintf(stderr, "pd: dropped message from gui\n"); | ||
564 | x->fdp_inhead = x->fdp_intail = 0; | ||
565 | readto = BUFSIZE; | ||
566 | } | ||
567 | else | ||
568 | { | ||
569 | ret = recv(x->fdp_fd, x->fdp_inbuf + x->fdp_inhead, | ||
570 | readto - x->fdp_inhead, 0); | ||
571 | if (ret < 0) | ||
572 | { | ||
573 | sockerror("recv (tcp)"); | ||
574 | rmport(x); | ||
575 | } | ||
576 | else if (ret == 0) | ||
577 | rmport(x); | ||
578 | else | ||
579 | { | ||
580 | x->fdp_inhead += ret; | ||
581 | if (x->fdp_inhead >= BUFSIZE) | ||
582 | x->fdp_inhead = 0; | ||
583 | while (tcpmakeoutput(x)) | ||
584 | ; | ||
585 | } | ||
586 | } | ||
587 | } | ||
588 | |||
589 | static void dopoll(void) | ||
590 | { | ||
591 | int i; | ||
592 | t_fdpoll *fp; | ||
593 | fd_set readset, writeset, exceptset; | ||
594 | FD_ZERO(&writeset); | ||
595 | FD_ZERO(&readset); | ||
596 | FD_ZERO(&exceptset); | ||
597 | |||
598 | FD_SET(sockfd, &readset); | ||
599 | if (protocol == SOCK_STREAM) | ||
600 | { | ||
601 | for (fp = fdpoll, i = nfdpoll; i--; fp++) | ||
602 | FD_SET(fp->fdp_fd, &readset); | ||
603 | } | ||
604 | if (select(maxfd+1, &readset, &writeset, &exceptset, 0) < 0) | ||
605 | { | ||
606 | perror("select"); | ||
607 | exit(1); | ||
608 | } | ||
609 | if (protocol == SOCK_STREAM) | ||
610 | { | ||
611 | for (i = 0; i < nfdpoll; i++) | ||
612 | if (FD_ISSET(fdpoll[i].fdp_fd, &readset)) | ||
613 | tcpread(&fdpoll[i]); | ||
614 | if (FD_ISSET(sockfd, &readset)) | ||
615 | doconnect(); | ||
616 | } | ||
617 | else | ||
618 | { | ||
619 | if (FD_ISSET(sockfd, &readset)) | ||
620 | udpread(); | ||
621 | } | ||
622 | } | ||
623 | |||
624 | |||
625 | static void sockerror(char *s) | ||
626 | { | ||
627 | #ifdef MSW | ||
628 | int err = WSAGetLastError(); | ||
629 | if (err == 10054) return; | ||
630 | else if (err == 10044) | ||
631 | { | ||
632 | fprintf(stderr, | ||
633 | "Warning: you might not have TCP/IP \"networking\" turned on\n"); | ||
634 | } | ||
635 | #endif | ||
636 | #ifdef UNIX | ||
637 | int err = errno; | ||
638 | #endif | ||
639 | fprintf(stderr, "%s: %s (%d)\n", s, strerror(err), err); | ||
640 | } | ||
641 | |||
642 | static void x_closesocket(int fd) | ||
643 | { | ||
644 | #ifdef UNIX | ||
645 | close(fd); | ||
646 | #endif | ||
647 | #ifdef MSW | ||
648 | closesocket(fd); | ||
649 | #endif | ||
650 | } | ||