]> git.saurik.com Git - wxWidgets.git/blob - src/unix/gsocket.c
cleaning up image mess for os/2
[wxWidgets.git] / src / unix / gsocket.c
1 /* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket) for WX
3 * Name: gsocket.c
4 * Purpose: GSocket main Unix file
5 * CVSID: $Id$
6 * -------------------------------------------------------------------------
7 */
8
9 #include "wx/setup.h"
10
11 #if wxUSE_SOCKETS
12
13 #include <assert.h>
14 #include <sys/types.h>
15 #include <netdb.h>
16 #include <sys/ioctl.h>
17 #ifdef __VMS__
18 #include <socket.h>
19 struct sockaddr_un {
20 u_char sun_len; /* sockaddr len including null */
21 u_char sun_family; /* AF_UNIX */
22 char sun_path[108]; /* path name (gag) */
23 };
24 #else
25 #include <sys/socket.h>
26 #include <sys/un.h>
27 #endif
28 #include <sys/time.h>
29 #include <netinet/in.h>
30 #include <arpa/inet.h>
31 #include <errno.h>
32
33 #include <string.h>
34 #include <unistd.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stddef.h>
38 #include <ctype.h>
39
40 #ifdef sun
41 # include <sys/filio.h>
42 #endif
43
44 #ifdef sgi
45 # include <bstring.h>
46 #endif
47
48 #include <signal.h>
49
50 #include "wx/gsocket.h"
51 #include "wx/unix/gsockunx.h"
52
53 #ifndef SOCKLEN_T
54
55 #ifdef VMS
56 # define SOCKLEN_T unsigned int
57 #else
58 # ifdef __GLIBC__
59 # if __GLIBC__ == 2
60 # define SOCKLEN_T socklen_t
61 # endif
62 # else
63 # define SOCKLEN_T int
64 # endif
65 #endif
66
67 #endif // SOCKLEN_T
68
69 #define MASK_SIGNAL() \
70 { \
71 void (*old_handler)(int); \
72 \
73 old_handler = signal(SIGPIPE, SIG_IGN);
74
75 #define UNMASK_SIGNAL() \
76 signal(SIGPIPE, old_handler); \
77 }
78
79
80 /* Global initialisers */
81
82 bool GSocket_Init()
83 {
84 return TRUE;
85 }
86
87 void GSocket_Cleanup()
88 {
89 }
90
91 /* Constructors / Destructors */
92
93 GSocket *GSocket_new()
94 {
95 int i;
96 GSocket *socket;
97
98 socket = (GSocket *)malloc(sizeof(GSocket));
99
100 if (socket == NULL)
101 return NULL;
102
103 socket->m_fd = -1;
104 for (i=0;i<GSOCK_MAX_EVENT;i++)
105 {
106 socket->m_cbacks[i] = NULL;
107 }
108 socket->m_detected = 0;
109 socket->m_local = NULL;
110 socket->m_peer = NULL;
111 socket->m_error = GSOCK_NOERROR;
112 socket->m_server = FALSE;
113 socket->m_stream = TRUE;
114 socket->m_gui_dependent = NULL;
115 socket->m_non_blocking = FALSE;
116 socket->m_timeout = 10*60*1000;
117 /* 10 minutes * 60 sec * 1000 millisec */
118 socket->m_establishing = FALSE;
119
120 /* We initialize the GUI specific entries here */
121 _GSocket_GUI_Init(socket);
122
123 return socket;
124 }
125
126 void GSocket_destroy(GSocket *socket)
127 {
128 assert(socket != NULL);
129
130 /* First, we check that the socket is really shutdowned */
131 if (socket->m_fd != -1)
132 GSocket_Shutdown(socket);
133
134 /* We destroy GUI specific variables */
135 _GSocket_GUI_Destroy(socket);
136
137 /* We destroy private addresses */
138 if (socket->m_local)
139 GAddress_destroy(socket->m_local);
140
141 if (socket->m_peer)
142 GAddress_destroy(socket->m_peer);
143
144 /* We destroy socket itself */
145 free(socket);
146 }
147
148 void GSocket_Shutdown(GSocket *socket)
149 {
150 int evt;
151
152 assert(socket != NULL);
153
154 /* If socket has been created, we shutdown it */
155 if (socket->m_fd != -1)
156 {
157 shutdown(socket->m_fd, 2);
158 close(socket->m_fd);
159 socket->m_fd = -1;
160 }
161
162 /* We also disable GUI callbacks */
163 for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
164 socket->m_cbacks[evt] = NULL;
165
166 socket->m_detected = 0;
167 _GSocket_Disable_Events(socket);
168 }
169
170 /* Address handling */
171
172 GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address)
173 {
174 assert(socket != NULL);
175
176 if ((socket->m_fd != -1 && !socket->m_server)) {
177 socket->m_error = GSOCK_INVSOCK;
178 return GSOCK_INVSOCK;
179 }
180
181 if (address == NULL || address->m_family == GSOCK_NOFAMILY) {
182 socket->m_error = GSOCK_INVADDR;
183 return GSOCK_INVADDR;
184 }
185
186 if (socket->m_local)
187 GAddress_destroy(socket->m_local);
188
189 socket->m_local = GAddress_copy(address);
190
191 return GSOCK_NOERROR;
192 }
193
194 GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address)
195 {
196 assert(socket != NULL);
197
198 if (address == NULL || address->m_family == GSOCK_NOFAMILY) {
199 socket->m_error = GSOCK_INVADDR;
200 return GSOCK_INVADDR;
201 }
202
203 if (socket->m_peer)
204 GAddress_destroy(socket->m_peer);
205
206 socket->m_peer = GAddress_copy(address);
207
208 return GSOCK_NOERROR;
209 }
210
211 GAddress *GSocket_GetLocal(GSocket *socket)
212 {
213 GAddress *address;
214 struct sockaddr addr;
215 SOCKLEN_T size = sizeof(addr);
216 GSocketError err;
217
218 assert(socket != NULL);
219
220 if (socket->m_local)
221 return GAddress_copy(socket->m_local);
222
223 if (socket->m_fd == -1) {
224 socket->m_error = GSOCK_INVSOCK;
225 return NULL;
226 }
227
228 size = sizeof(addr);
229
230 if (getsockname(socket->m_fd, &addr, (SOCKLEN_T *) &size) < 0) {
231 socket->m_error = GSOCK_IOERR;
232 return NULL;
233 }
234
235 address = GAddress_new();
236 if (address == NULL) {
237 socket->m_error = GSOCK_MEMERR;
238 return NULL;
239 }
240 err = _GAddress_translate_from(address, &addr, size); /*xxx*/
241 if (err != GSOCK_NOERROR) {
242 GAddress_destroy(address);
243 socket->m_error = err;
244 return NULL;
245 }
246
247 return address;
248 }
249
250 GAddress *GSocket_GetPeer(GSocket *socket)
251 {
252 assert(socket != NULL);
253
254 if (socket->m_peer)
255 return GAddress_copy(socket->m_peer);
256
257 return NULL;
258 }
259
260 /* Server specific parts */
261
262 /* GSocket_SetServer:
263 * Sets up the socket as a server. It uses the "Local" field of GSocket.
264 * "Local" must be set by GSocket_SetLocal() before GSocket_SetServer()
265 * is called. Possible error codes are: GSOCK_INVSOCK if socket has not
266 * been initialized, GSOCK_INVADDR if the local address has not been
267 * defined and GSOCK_IOERR for other internal errors.
268 */
269 GSocketError GSocket_SetServer(GSocket *sck)
270 {
271 int type;
272 int arg = 1;
273
274 assert(sck != NULL);
275
276 if (sck->m_fd != -1) {
277 sck->m_error = GSOCK_INVSOCK;
278 return GSOCK_INVSOCK;
279 }
280
281 if (!sck->m_local) {
282 sck->m_error = GSOCK_INVADDR;
283 return GSOCK_INVADDR;
284 }
285
286 /* We always have a stream here */
287 sck->m_stream = TRUE;
288 sck->m_server = TRUE;
289
290 /* Create the socket */
291 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0);
292
293 if (sck->m_fd == -1) {
294 sck->m_error = GSOCK_IOERR;
295 return GSOCK_IOERR;
296 }
297
298 ioctl(sck->m_fd, FIONBIO, &arg);
299 _GSocket_Enable_Events(sck);
300
301 /* Bind the socket to the LOCAL address */
302 if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
303 close(sck->m_fd);
304 sck->m_fd = -1;
305 sck->m_error = GSOCK_IOERR;
306 return GSOCK_IOERR;
307 }
308
309 /* Enable listening up to 5 connections */
310 if (listen(sck->m_fd, 5) < 0) {
311 close(sck->m_fd);
312 sck->m_fd = -1;
313 sck->m_error = GSOCK_IOERR;
314 return GSOCK_IOERR;
315 }
316
317 return GSOCK_NOERROR;
318 }
319
320 /* GSocket_WaitConnection:
321 * Waits for an incoming client connection.
322 */
323 GSocket *GSocket_WaitConnection(GSocket *socket)
324 {
325 struct sockaddr from;
326 SOCKLEN_T fromlen = sizeof(from);
327 GSocket *connection;
328 int arg = 1;
329
330 assert(socket != NULL);
331
332 /* Reenable CONNECTION events */
333 _GSocket_Enable(socket, GSOCK_CONNECTION);
334
335 /* If the socket has already been created, we exit immediately */
336 if (socket->m_fd == -1 || !socket->m_server)
337 {
338 socket->m_error = GSOCK_INVSOCK;
339 return NULL;
340 }
341
342 /* Create a GSocket object for the new connection */
343 connection = GSocket_new();
344 if (!connection)
345 {
346 socket->m_error = GSOCK_MEMERR;
347 return NULL;
348 }
349
350 /* Accept the incoming connection */
351 if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
352 {
353 GSocket_destroy(connection);
354 /* socket->m_error set by _GSocket_Input_Timeout */
355 return NULL;
356 }
357
358 connection->m_fd = accept(socket->m_fd, &from, (SOCKLEN_T *) &fromlen);
359
360 if (connection->m_fd == -1)
361 {
362 if (errno == EWOULDBLOCK)
363 socket->m_error = GSOCK_WOULDBLOCK;
364 else
365 socket->m_error = GSOCK_IOERR;
366
367 GSocket_destroy(connection);
368 return NULL;
369 }
370
371 /* Initialize all fields */
372 connection->m_server = FALSE;
373 connection->m_stream = TRUE;
374 connection->m_oriented = TRUE;
375
376 /* Setup the peer address field */ /*xxx*/
377 connection->m_peer = GAddress_new();
378 if (!connection->m_peer)
379 {
380 GSocket_destroy(connection);
381 socket->m_error = GSOCK_MEMERR;
382 return NULL;
383 }
384 err = _GAddress_translate_from(connection->m_peer, &from, fromlen);
385 if (err != GSOCK_NOERROR)
386 {
387 GAddress_destroy(connection->m_peer);
388 GSocket_destroy(connection);
389 socket->m_error = err;
390 return NULL;
391 }
392
393 ioctl(connection->m_fd, FIONBIO, &arg);
394 _GSocket_Enable_Events(connection);
395
396 return connection;
397 }
398
399 /* Non oriented connections */
400
401 GSocketError GSocket_SetNonOriented(GSocket *sck)
402 {
403 int arg = 1;
404
405 assert(sck != NULL);
406
407 if (sck->m_fd != -1) {
408 sck->m_error = GSOCK_INVSOCK;
409 return GSOCK_INVSOCK;
410 }
411
412 if (!sck->m_local) {
413 sck->m_error = GSOCK_INVADDR;
414 return GSOCK_INVADDR;
415 }
416
417 sck->m_stream = FALSE;
418 sck->m_server = FALSE;
419 sck->m_oriented = FALSE;
420
421 /* Create the socket */
422 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
423
424 if (sck->m_fd < 0) {
425 sck->m_error = GSOCK_IOERR;
426 return GSOCK_IOERR;
427 }
428
429 ioctl(sck->m_fd, FIONBIO, &arg);
430 _GSocket_Enable_Events(sck);
431
432 /* Bind it to the LOCAL address */
433 if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
434 close(sck->m_fd);
435 sck->m_fd = -1;
436 sck->m_error = GSOCK_IOERR;
437 return GSOCK_IOERR;
438 }
439
440 return GSOCK_NOERROR;
441 }
442
443 /* Client specific parts */
444
445 /* GSocket_Connect:
446 * Establishes a client connection to a server using the "Peer"
447 * field of GSocket. "Peer" must be set by GSocket_SetPeer() before
448 * GSocket_Connect() is called. Possible error codes are GSOCK_INVSOCK,
449 * GSOCK_INVADDR, GSOCK_TIMEDOUT, GSOCK_WOULDBLOCK and GSOCK_IOERR.
450 * If a socket is nonblocking and Connect() returns GSOCK_WOULDBLOCK,
451 * the connection request can be completed later. Use GSocket_Select()
452 * to check or wait for a GSOCK_CONNECTION event.
453 */
454 GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
455 {
456 int type, err, ret;
457 int arg = 1;
458
459 assert(sck != NULL);
460
461 /* Enable CONNECTION events (needed for nonblocking connections) */
462 _GSocket_Enable(sck, GSOCK_CONNECTION);
463
464 if (sck->m_fd != -1)
465 {
466 sck->m_error = GSOCK_INVSOCK;
467 return GSOCK_INVSOCK;
468 }
469
470 if (!sck->m_peer)
471 {
472 sck->m_error = GSOCK_INVADDR;
473 return GSOCK_INVADDR;
474 }
475
476 /* Test whether we want the socket to be a stream (e.g. TCP) */
477 sck->m_stream = (stream == GSOCK_STREAMED);
478 sck->m_oriented = TRUE;
479 sck->m_server = FALSE;
480 sck->m_establishing = FALSE;
481
482 if (sck->m_stream)
483 type = SOCK_STREAM;
484 else
485 type = SOCK_DGRAM;
486
487 /* Create the socket */
488 sck->m_fd = socket(sck->m_peer->m_realfamily, type, 0);
489
490 if (sck->m_fd == -1) {
491 sck->m_error = GSOCK_IOERR;
492 return GSOCK_IOERR;
493 }
494
495 ioctl(sck->m_fd, FIONBIO, &arg);
496 _GSocket_Enable_Events(sck);
497
498 /* Connect it to the PEER address */
499 ret = connect(sck->m_fd, sck->m_peer->m_addr, sck->m_peer->m_len);
500
501 if (ret == -1)
502 {
503 err = errno;
504
505 /* If connect failed with EINPROGRESS and the GSocket object
506 * is in blocking mode, we select() for the specified timeout
507 * checking for writability to see if the connection request
508 * completes.
509 */
510 if ((err == EINPROGRESS) && (!sck->m_non_blocking))
511 {
512 if (_GSocket_Output_Timeout(sck) == GSOCK_TIMEDOUT)
513 {
514 close(sck->m_fd);
515 sck->m_fd = -1;
516 /* sck->m_error is set in _GSocket_Output_Timeout */
517 return GSOCK_TIMEDOUT;
518 }
519 else
520 {
521 return GSOCK_NOERROR;
522 }
523 }
524
525 /* If connect failed with EINPROGRESS and the GSocket object
526 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
527 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
528 * this way if the connection completes, a GSOCK_CONNECTION
529 * event will be generated, if enabled.
530 */
531 if ((err == EINPROGRESS) && (sck->m_non_blocking))
532 {
533 sck->m_error = GSOCK_WOULDBLOCK;
534 sck->m_establishing = TRUE;
535
536 return GSOCK_WOULDBLOCK;
537 }
538
539 /* If connect failed with an error other than EINPROGRESS,
540 * then the call to GSocket_Connect has failed.
541 */
542 close(sck->m_fd);
543 sck->m_fd = -1;
544 sck->m_error = GSOCK_IOERR;
545
546 return GSOCK_IOERR;
547 }
548
549 return GSOCK_NOERROR;
550 }
551
552 /* Generic IO */
553
554 /* Like recv(), send(), ... */
555 int GSocket_Read(GSocket *socket, char *buffer, int size)
556 {
557 int ret;
558
559 assert(socket != NULL);
560
561 /* Reenable INPUT events */
562 _GSocket_Enable(socket, GSOCK_INPUT);
563
564 if (socket->m_fd == -1 || socket->m_server)
565 {
566 socket->m_error = GSOCK_INVSOCK;
567 return -1;
568 }
569
570 if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
571 return -1;
572
573 if (socket->m_stream)
574 ret = _GSocket_Recv_Stream(socket, buffer, size);
575 else
576 ret = _GSocket_Recv_Dgram(socket, buffer, size);
577
578 if (ret == -1)
579 {
580 if (errno == EWOULDBLOCK)
581 socket->m_error = GSOCK_WOULDBLOCK;
582 else
583 socket->m_error = GSOCK_IOERR;
584 }
585
586 return ret;
587 }
588
589 int GSocket_Write(GSocket *socket, const char *buffer,
590 int size)
591 {
592 int ret;
593
594 assert(socket != NULL);
595
596 if (socket->m_fd == -1 || socket->m_server)
597 {
598 socket->m_error = GSOCK_INVSOCK;
599 return -1;
600 }
601
602 if (_GSocket_Output_Timeout(socket) == GSOCK_TIMEDOUT)
603 return -1;
604
605 if (socket->m_stream)
606 ret = _GSocket_Send_Stream(socket, buffer, size);
607 else
608 ret = _GSocket_Send_Dgram(socket, buffer, size);
609
610 if (ret == -1)
611 {
612 if (errno == EWOULDBLOCK)
613 socket->m_error = GSOCK_WOULDBLOCK;
614 else
615 socket->m_error = GSOCK_IOERR;
616
617 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
618 * in MSW). Once the first OUTPUT event is received, users can assume
619 * that the socket is writable until a read operation fails. Only then
620 * will further OUTPUT events be posted.
621 */
622 _GSocket_Enable(socket, GSOCK_OUTPUT);
623 }
624
625 return ret;
626 }
627
628 /* GSocket_Select:
629 * Polls the socket to determine its status. This function will
630 * check for the events specified in the 'flags' parameter, and
631 * it will return a mask indicating which operations can be
632 * performed. This function won't block, regardless of the
633 * mode (blocking|nonblocking) of the socket.
634 */
635 GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags)
636 {
637 assert(socket != NULL);
638
639 return (flags & socket->m_detected);
640 }
641
642 /* Flags */
643
644 /* GSocket_SetNonBlocking:
645 * Sets the socket to non-blocking mode. This is useful if
646 * we don't want to wait.
647 */
648 void GSocket_SetNonBlocking(GSocket *socket, bool non_block)
649 {
650 assert(socket != NULL);
651
652 socket->m_non_blocking = non_block;
653 }
654
655 /* GSocket_SetTimeout:
656 * Sets the timeout for blocking calls. Time is
657 * expressed in milliseconds.
658 */
659 void GSocket_SetTimeout(GSocket *socket, unsigned long millisec)
660 {
661 assert(socket != NULL);
662
663 socket->m_timeout = millisec;
664 }
665
666 /* GSocket_GetError:
667 * Returns the last error occured for this socket.
668 */
669 GSocketError GSocket_GetError(GSocket *socket)
670 {
671 assert(socket != NULL);
672
673 return socket->m_error;
674 }
675
676 /* Callbacks */
677
678 /* Only one callback is possible for each event (INPUT, OUTPUT, CONNECTION
679 * and LOST). The callbacks are called in the following situations:
680 *
681 * INPUT: There is at least one byte in the input buffer
682 * OUTPUT: The system is sure that the next write call will not block
683 * CONNECTION: Two cases are possible:
684 * Client socket -> the connection is established
685 * Server socket -> a client requests a connection
686 * LOST: The connection is lost
687 *
688 * An event is generated only once and its state is reseted when the
689 * relative IO call is requested.
690 * For example: INPUT -> GSocket_Read()
691 * CONNECTION -> GSocket_Accept()
692 */
693
694 /* GSocket_SetCallback:
695 * Enables the callbacks specified by 'flags'. Note that 'flags'
696 * may be a combination of flags OR'ed toghether, so the same
697 * callback function can be made to accept different events.
698 * The callback function must have the following prototype:
699 *
700 * void function(GSocket *socket, GSocketEvent event, char *cdata)
701 */
702 void GSocket_SetCallback(GSocket *socket, GSocketEventFlags flags,
703 GSocketCallback callback, char *cdata)
704 {
705 int count;
706
707 assert(socket != NULL);
708
709 for (count = 0; count < GSOCK_MAX_EVENT; count++)
710 {
711 if ((flags & (1 << count)) != 0)
712 {
713 socket->m_cbacks[count] = callback;
714 socket->m_data[count] = cdata;
715 }
716 }
717 }
718
719 /* GSocket_UnsetCallback:
720 * Disables all callbacks specified by 'flags', which may be a
721 * combination of flags OR'ed toghether.
722 */
723 void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags)
724 {
725 int count;
726
727 assert(socket != NULL);
728
729 for (count = 0; count < GSOCK_MAX_EVENT; count++)
730 {
731 if ((flags & (1 << count)) != 0)
732 {
733 socket->m_cbacks[count] = NULL;
734 socket->m_data[count] = NULL;
735 }
736 }
737 }
738
739 #define CALL_CALLBACK(socket, event) { \
740 _GSocket_Disable(socket, event); \
741 if (socket->m_cbacks[event]) \
742 socket->m_cbacks[event](socket, event, socket->m_data[event]); \
743 }
744
745
746 void _GSocket_Enable(GSocket *socket, GSocketEvent event)
747 {
748 socket->m_detected &= ~(1 << event);
749 _GSocket_Install_Callback(socket, event);
750 }
751
752 void _GSocket_Disable(GSocket *socket, GSocketEvent event)
753 {
754 socket->m_detected |= (1 << event);
755 _GSocket_Uninstall_Callback(socket, event);
756 }
757
758 /* _GSocket_Input_Timeout:
759 * For blocking sockets, wait until data is available or
760 * until timeout ellapses.
761 */
762 GSocketError _GSocket_Input_Timeout(GSocket *socket)
763 {
764 struct timeval tv;
765 fd_set readfds;
766
767 /* Linux select() will overwrite the struct on return */
768 tv.tv_sec = (socket->m_timeout / 1000);
769 tv.tv_usec = (socket->m_timeout % 1000) * 1000;
770
771 if (!socket->m_non_blocking)
772 {
773 FD_ZERO(&readfds);
774 FD_SET(socket->m_fd, &readfds);
775 if (select(socket->m_fd + 1, &readfds, NULL, NULL, &tv) == 0)
776 {
777 socket->m_error = GSOCK_TIMEDOUT;
778 return GSOCK_TIMEDOUT;
779 }
780 }
781 return GSOCK_NOERROR;
782 }
783
784 /* _GSocket_Output_Timeout:
785 * For blocking sockets, wait until data can be sent without
786 * blocking or until timeout ellapses.
787 */
788 GSocketError _GSocket_Output_Timeout(GSocket *socket)
789 {
790 struct timeval tv;
791 fd_set writefds;
792
793 /* Linux select() will overwrite the struct on return */
794 tv.tv_sec = (socket->m_timeout / 1000);
795 tv.tv_usec = (socket->m_timeout % 1000) * 1000;
796
797 if (!socket->m_non_blocking)
798 {
799 FD_ZERO(&writefds);
800 FD_SET(socket->m_fd, &writefds);
801 if (select(socket->m_fd + 1, NULL, &writefds, NULL, &tv) == 0)
802 {
803 socket->m_error = GSOCK_TIMEDOUT;
804 return GSOCK_TIMEDOUT;
805 }
806 }
807 return GSOCK_NOERROR;
808 }
809
810 int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
811 {
812 int ret;
813
814 MASK_SIGNAL();
815 ret = recv(socket->m_fd, buffer, size, 0);
816 UNMASK_SIGNAL();
817
818 return ret;
819 }
820
821 int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
822 {
823 struct sockaddr from;
824 SOCKLEN_T fromlen = sizeof(from);
825 int ret;
826 GSocketError err;
827
828 fromlen = sizeof(from);
829
830 MASK_SIGNAL();
831 ret = recvfrom(socket->m_fd, buffer, size, 0, &from, (SOCKLEN_T *) &fromlen);
832 UNMASK_SIGNAL();
833
834 if (ret == -1)
835 return -1;
836
837 /* Translate a system address into a GSocket address */
838 if (!socket->m_peer)
839 {
840 socket->m_peer = GAddress_new();
841 if (!socket->m_peer)
842 {
843 socket->m_error = GSOCK_MEMERR;
844 return -1;
845 }
846 }
847 err = _GAddress_translate_from(socket->m_peer, &from, fromlen);
848 if (err != GSOCK_NOERROR)
849 {
850 GAddress_destroy(socket->m_peer);
851 socket->m_peer = NULL;
852 socket->m_error = err;
853 return -1;
854 }
855
856 return ret;
857 }
858
859 int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
860 {
861 int ret;
862
863 MASK_SIGNAL();
864 ret = send(socket->m_fd, buffer, size, 0);
865 UNMASK_SIGNAL();
866
867 return ret;
868 }
869
870 int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
871 {
872 struct sockaddr *addr;
873 int len, ret;
874 GSocketError err;
875
876 if (!socket->m_peer) {
877 socket->m_error = GSOCK_INVADDR;
878 return -1;
879 }
880
881 err = _GAddress_translate_to(socket->m_peer, &addr, &len);
882 if (err != GSOCK_NOERROR) {
883 socket->m_error = err;
884 return -1;
885 }
886
887 MASK_SIGNAL();
888 ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
889 UNMASK_SIGNAL();
890
891 /* Frees memory allocated from _GAddress_translate_to */
892 free(addr);
893
894 return ret;
895 }
896
897 void _GSocket_Detected_Read(GSocket *socket)
898 {
899 char c;
900 int ret;
901
902 if (socket->m_stream)
903 {
904 ret = recv(socket->m_fd, &c, 1, MSG_PEEK);
905
906 if (ret < 0 && socket->m_server)
907 {
908 CALL_CALLBACK(socket, GSOCK_CONNECTION);
909 return;
910 }
911
912 if (ret > 0)
913 {
914 CALL_CALLBACK(socket, GSOCK_INPUT);
915 }
916 else
917 {
918 CALL_CALLBACK(socket, GSOCK_LOST);
919 }
920 }
921 }
922
923 void _GSocket_Detected_Write(GSocket *socket)
924 {
925 if (socket->m_establishing && !socket->m_server)
926 {
927 int error, len;
928
929 socket->m_establishing = FALSE;
930
931 len = sizeof(error);
932 getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, (void*) &error,
933 (SOCKLEN_T *) &len);
934
935 if (error)
936 {
937 CALL_CALLBACK(socket, GSOCK_LOST);
938 }
939 else
940 {
941 CALL_CALLBACK(socket, GSOCK_CONNECTION);
942 /* We have to fire this event by hand because CONNECTION (for clients)
943 * and OUTPUT are internally the same and we just disabled CONNECTION
944 * events with the above macro.
945 */
946 CALL_CALLBACK(socket, GSOCK_OUTPUT);
947 }
948 }
949 else
950 {
951 CALL_CALLBACK(socket, GSOCK_OUTPUT);
952 }
953 }
954
955 /*
956 * -------------------------------------------------------------------------
957 * GAddress
958 * -------------------------------------------------------------------------
959 */
960
961 /* CHECK_ADDRESS verifies that the current family is either GSOCK_NOFAMILY or
962 * GSOCK_*family*. In case it is GSOCK_NOFAMILY, it initializes address to be
963 * a GSOCK_*family*. In other cases, it returns GSOCK_INVADDR.
964 */
965 #define CHECK_ADDRESS(address, family, retval) \
966 { \
967 if (address->m_family == GSOCK_NOFAMILY) \
968 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) {\
969 return address->m_error; \
970 }\
971 if (address->m_family != GSOCK_##family) {\
972 address->m_error = GSOCK_INVADDR; \
973 return retval; \
974 } \
975 }
976
977 GAddress *GAddress_new()
978 {
979 GAddress *address;
980
981 address = (GAddress *)malloc(sizeof(GAddress));
982
983 if (address == NULL)
984 return NULL;
985
986 address->m_family = GSOCK_NOFAMILY;
987 address->m_addr = NULL;
988 address->m_len = 0;
989
990 return address;
991 }
992
993 GAddress *GAddress_copy(GAddress *address)
994 {
995 GAddress *addr2;
996
997 assert(address != NULL);
998
999 addr2 = (GAddress *)malloc(sizeof(GAddress));
1000
1001 if (addr2 == NULL)
1002 return NULL;
1003
1004 memcpy(addr2, address, sizeof(GAddress));
1005
1006 if (address->m_addr) {
1007 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
1008 if (addr2->m_addr == NULL) {
1009 free(addr2);
1010 return NULL;
1011 }
1012 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
1013 }
1014
1015 return addr2;
1016 }
1017
1018 void GAddress_destroy(GAddress *address)
1019 {
1020 assert(address != NULL);
1021
1022 free(address);
1023 }
1024
1025 void GAddress_SetFamily(GAddress *address, GAddressType type)
1026 {
1027 assert(address != NULL);
1028
1029 address->m_family = type;
1030 }
1031
1032 GAddressType GAddress_GetFamily(GAddress *address)
1033 {
1034 assert(address != NULL);
1035
1036 return address->m_family;
1037 }
1038
1039 GSocketError _GAddress_translate_from(GAddress *address, struct sockaddr *addr, int len){
1040 address->m_realfamily = addr->sa_family;
1041 switch (addr->sa_family) {
1042 case AF_INET:
1043 address->m_family = GSOCK_INET;
1044 break;
1045 case AF_UNIX:
1046 address->m_family = GSOCK_UNIX;
1047 break;
1048 #ifdef AF_INET6
1049 case AF_INET6:
1050 address->m_family = GSOCK_INET6;
1051 break;
1052 #endif
1053 default:
1054 {
1055 address->m_error = GSOCK_INVOP;
1056 return GSOCK_INVOP;
1057 }
1058 }
1059
1060 if (address->m_addr)
1061 free(address->m_addr);
1062
1063 address->m_len = len;
1064 address->m_addr = (struct sockaddr *)malloc(len);
1065 if (address->m_addr == NULL) {
1066 address->m_error = GSOCK_MEMERR;
1067 return GSOCK_MEMERR;
1068 }
1069 memcpy(address->m_addr, addr, len);
1070
1071 return GSOCK_NOERROR;
1072 }
1073
1074 GSocketError _GAddress_translate_to(GAddress *address,
1075 struct sockaddr **addr, int *len)
1076 {
1077 if (!address->m_addr) {
1078 address->m_error = GSOCK_INVADDR;
1079 return GSOCK_INVADDR;
1080 }
1081
1082 *len = address->m_len;
1083 *addr = (struct sockaddr *)malloc(address->m_len);
1084 if (*addr == NULL) {
1085 address->m_error = GSOCK_MEMERR;
1086 return GSOCK_MEMERR;
1087 }
1088
1089 memcpy(*addr, address->m_addr, address->m_len);
1090 return GSOCK_NOERROR;
1091 }
1092
1093 /*
1094 * -------------------------------------------------------------------------
1095 * Internet address family
1096 * -------------------------------------------------------------------------
1097 */
1098
1099 GSocketError _GAddress_Init_INET(GAddress *address)
1100 {
1101 address->m_len = sizeof(struct sockaddr_in);
1102 address->m_addr = (struct sockaddr *)malloc(address->m_len);
1103 if (address->m_addr == NULL)
1104 {
1105 address->m_error = GSOCK_MEMERR;
1106 return GSOCK_MEMERR;
1107 }
1108
1109 address->m_family = GSOCK_INET;
1110 address->m_realfamily = PF_INET;
1111 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
1112 /*
1113 INADDR_BROADCAST is identical to INADDR_NONE which is not defined
1114 on all unices. INADDR_BROADCAST should be fine to indicate an error.
1115 */
1116 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_BROADCAST;
1117
1118 return GSOCK_NOERROR;
1119 }
1120
1121 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
1122 {
1123 struct hostent *he;
1124 struct in_addr *addr;
1125
1126 assert(address != NULL);
1127
1128 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1129
1130 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1131
1132 /* If it is a numeric host name, convert it now */
1133 #if defined(HAVE_INET_ATON)
1134 if (inet_aton(hostname, addr) == 0)
1135 {
1136 #elif defined(HAVE_INET_ADDR)
1137 /* Fix from Guillermo Rodriguez Garcia <guille@iies.es> */
1138 if ( (addr->s_addr = inet_addr(hostname)) == -1 )
1139 {
1140 #else
1141 /* Use gethostbyname by default */
1142 if (1)
1143 {
1144 #endif
1145 struct in_addr *array_addr;
1146
1147 /* It is a real name, we solve it */
1148 if ((he = gethostbyname(hostname)) == NULL)
1149 {
1150 address->m_error = GSOCK_NOHOST;
1151 return GSOCK_NOHOST;
1152 }
1153 array_addr = (struct in_addr *) *(he->h_addr_list);
1154 addr->s_addr = array_addr[0].s_addr;
1155 }
1156 return GSOCK_NOERROR;
1157 }
1158
1159 GSocketError GAddress_INET_SetHostAddress(GAddress *address,
1160 unsigned long hostaddr)
1161 {
1162 struct in_addr *addr;
1163
1164 assert(address != NULL);
1165
1166 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1167
1168 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1169 addr->s_addr = hostaddr;
1170
1171 return GSOCK_NOERROR;
1172 }
1173
1174 GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1175 const char *protocol)
1176 {
1177 struct servent *se;
1178 struct sockaddr_in *addr;
1179
1180 assert(address != NULL);
1181 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1182
1183 if (!port)
1184 {
1185 address->m_error = GSOCK_INVPORT;
1186 return GSOCK_INVPORT;
1187 }
1188
1189 se = getservbyname(port, protocol);
1190 if (!se) {
1191 if (isdigit(port[0]))
1192 {
1193 int port_int;
1194
1195 port_int = atoi(port);
1196 addr = (struct sockaddr_in *)address->m_addr;
1197 addr->sin_port = htons(port_int);
1198 return GSOCK_NOERROR;
1199 }
1200
1201 address->m_error = GSOCK_INVPORT;
1202 return GSOCK_INVPORT;
1203 }
1204
1205 addr = (struct sockaddr_in *)address->m_addr;
1206 addr->sin_port = se->s_port;
1207
1208 return GSOCK_NOERROR;
1209 }
1210
1211 GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1212 {
1213 struct sockaddr_in *addr;
1214
1215 assert(address != NULL);
1216 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1217
1218 addr = (struct sockaddr_in *)address->m_addr;
1219 addr->sin_port = htons(port);
1220
1221 return GSOCK_NOERROR;
1222 }
1223
1224 GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1225 {
1226 struct hostent *he;
1227 char *addr_buf;
1228 struct sockaddr_in *addr;
1229
1230 assert(address != NULL);
1231 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1232
1233 addr = (struct sockaddr_in *)address->m_addr;
1234 addr_buf = (char *)&(addr->sin_addr);
1235
1236 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1237 if (he == NULL)
1238 {
1239 address->m_error = GSOCK_NOHOST;
1240 return GSOCK_NOHOST;
1241 }
1242
1243 strncpy(hostname, he->h_name, sbuf);
1244
1245 return GSOCK_NOERROR;
1246 }
1247
1248 unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1249 {
1250 struct sockaddr_in *addr;
1251
1252 assert(address != NULL);
1253 CHECK_ADDRESS(address, INET, 0);
1254
1255 addr = (struct sockaddr_in *)address->m_addr;
1256
1257 return addr->sin_addr.s_addr;
1258 }
1259
1260 unsigned short GAddress_INET_GetPort(GAddress *address)
1261 {
1262 struct sockaddr_in *addr;
1263
1264 assert(address != NULL);
1265 CHECK_ADDRESS(address, INET, 0);
1266
1267 addr = (struct sockaddr_in *)address->m_addr;
1268 return ntohs(addr->sin_port);
1269 }
1270
1271 /*
1272 * -------------------------------------------------------------------------
1273 * Unix address family
1274 * -------------------------------------------------------------------------
1275 */
1276
1277 GSocketError _GAddress_Init_UNIX(GAddress *address)
1278 {
1279 address->m_len = sizeof(struct sockaddr_un);
1280 address->m_addr = (struct sockaddr *)malloc(address->m_len);
1281 if (address->m_addr == NULL)
1282 {
1283 address->m_error = GSOCK_MEMERR;
1284 return GSOCK_MEMERR;
1285 }
1286
1287 address->m_family = GSOCK_UNIX;
1288 address->m_realfamily = PF_UNIX;
1289 ((struct sockaddr_un *)address->m_addr)->sun_family = AF_UNIX;
1290 ((struct sockaddr_un *)address->m_addr)->sun_path[0] = 0;
1291
1292 return TRUE;
1293 }
1294
1295 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
1296 {
1297 struct sockaddr_un *addr;
1298
1299 assert(address != NULL);
1300
1301 CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR);
1302
1303 addr = ((struct sockaddr_un *)address->m_addr);
1304 memcpy(addr->sun_path, path, strlen(path));
1305
1306 return GSOCK_NOERROR;
1307 }
1308
1309 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
1310 {
1311 struct sockaddr_un *addr;
1312
1313 assert(address != NULL);
1314 CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR);
1315
1316 addr = (struct sockaddr_un *)address->m_addr;
1317
1318 strncpy(path, addr->sun_path, sbuf);
1319
1320 return GSOCK_NOERROR;
1321 }
1322
1323 #endif
1324 /* wxUSE_SOCKETS */
1325