]> git.saurik.com Git - wxWidgets.git/blame - src/unix/gsocket.c
*** empty log message ***
[wxWidgets.git] / src / unix / gsocket.c
CommitLineData
a324a7bc
GL
1/* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket) for WX
3 * Name: gsocket.c
4 * Purpose: GSocket main Unix file
5 * CVSID: $Id$
a324a7bc
GL
6 * -------------------------------------------------------------------------
7 */
8
813c20a6
VZ
9#include "wx/setup.h"
10
11#if wxUSE_SOCKETS
12
a324a7bc 13#include <assert.h>
efee48a0 14#include <sys/types.h>
6a2e7225
VZ
15#include <netdb.h>
16#include <sys/ioctl.h>
af9d1662 17#ifdef __VMS__
a324a7bc 18#include <socket.h>
af9d1662
JJ
19struct 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};
a324a7bc
GL
24#else
25#include <sys/socket.h>
a324a7bc 26#include <sys/un.h>
af9d1662 27#endif
a324a7bc
GL
28#include <sys/time.h>
29#include <netinet/in.h>
30#include <arpa/inet.h>
9592b687 31#include <errno.h>
a324a7bc
GL
32
33#include <string.h>
34#include <unistd.h>
35#include <stdio.h>
36#include <stdlib.h>
552e8bf8 37#include <stddef.h>
9b61f868 38#include <ctype.h>
a324a7bc
GL
39
40#ifdef sun
f61815af 41# include <sys/filio.h>
a324a7bc
GL
42#endif
43
44#ifdef sgi
f61815af 45# include <bstring.h>
a324a7bc
GL
46#endif
47
48#include <signal.h>
5a96d2f4 49
ca17eff3 50#include "wx/gsocket.h"
533c7161 51#include "wx/unix/gsockunx.h"
a324a7bc 52
efee48a0 53#ifndef SOCKLEN_T
5a96d2f4 54
85806dc2
GRG
55#ifdef VMS
56# define SOCKLEN_T unsigned int
5a96d2f4 57#else
85806dc2
GRG
58# ifdef __GLIBC__
59# if __GLIBC__ == 2
60# define SOCKLEN_T socklen_t
61# endif
62# else
63# define SOCKLEN_T int
64# endif
5a96d2f4
GL
65#endif
66
85806dc2 67#endif // SOCKLEN_T
efee48a0 68
483249fc
GRG
69#define MASK_SIGNAL() \
70{ \
71 void (*old_handler)(int); \
72 \
aa6d9706
GL
73 old_handler = signal(SIGPIPE, SIG_IGN);
74
483249fc
GRG
75#define UNMASK_SIGNAL() \
76 signal(SIGPIPE, old_handler); \
aa6d9706
GL
77}
78
54e575f9 79
a58d5df4
GL
80/* Global initialisers */
81
31989b0b 82bool GSocket_Init()
a58d5df4 83{
31989b0b 84 return TRUE;
a58d5df4
GL
85}
86
87void GSocket_Cleanup()
88{
89}
90
a324a7bc
GL
91/* Constructors / Destructors */
92
93GSocket *GSocket_new()
94{
95 int i;
96 GSocket *socket;
97
98 socket = (GSocket *)malloc(sizeof(GSocket));
99
e00f35bb
GL
100 if (socket == NULL)
101 return NULL;
102
a324a7bc 103 socket->m_fd = -1;
483249fc
GRG
104 for (i=0;i<GSOCK_MAX_EVENT;i++)
105 {
98781fa3 106 socket->m_cbacks[i] = NULL;
a324a7bc 107 }
483249fc 108 socket->m_detected = 0;
a324a7bc
GL
109 socket->m_local = NULL;
110 socket->m_peer = NULL;
111 socket->m_error = GSOCK_NOERROR;
ef25e638
GRG
112 socket->m_server = FALSE;
113 socket->m_stream = TRUE;
114 socket->m_gui_dependent = NULL;
115 socket->m_non_blocking = FALSE;
39b91eca 116 socket->m_timeout = 10*60*1000;
ef25e638 117 /* 10 minutes * 60 sec * 1000 millisec */
aa6d9706 118 socket->m_establishing = FALSE;
a324a7bc 119
31989b0b 120 /* We initialize the GUI specific entries here */
a324a7bc
GL
121 _GSocket_GUI_Init(socket);
122
123 return socket;
124}
125
126void GSocket_destroy(GSocket *socket)
127{
128 assert(socket != NULL);
129
31989b0b 130 /* First, we check that the socket is really shutdowned */
a324a7bc
GL
131 if (socket->m_fd != -1)
132 GSocket_Shutdown(socket);
133
31989b0b 134 /* We destroy GUI specific variables */
dbd300df
GL
135 _GSocket_GUI_Destroy(socket);
136
31989b0b 137 /* We destroy private addresses */
a324a7bc
GL
138 if (socket->m_local)
139 GAddress_destroy(socket->m_local);
140
141 if (socket->m_peer)
142 GAddress_destroy(socket->m_peer);
143
31989b0b 144 /* We destroy socket itself */
a324a7bc
GL
145 free(socket);
146}
147
148void GSocket_Shutdown(GSocket *socket)
149{
150 int evt;
151
152 assert(socket != NULL);
153
31989b0b 154 /* If socket has been created, we shutdown it */
483249fc
GRG
155 if (socket->m_fd != -1)
156 {
533c7161 157 shutdown(socket->m_fd, 2);
a324a7bc
GL
158 close(socket->m_fd);
159 socket->m_fd = -1;
160 }
161
31989b0b 162 /* We also disable GUI callbacks */
483249fc
GRG
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);
a324a7bc
GL
168}
169
170/* Address handling */
171
172GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address)
173{
5a96d2f4
GL
174 assert(socket != NULL);
175
31989b0b
GL
176 if ((socket->m_fd != -1 && !socket->m_server)) {
177 socket->m_error = GSOCK_INVSOCK;
a324a7bc 178 return GSOCK_INVSOCK;
31989b0b 179 }
a324a7bc 180
31989b0b
GL
181 if (address == NULL || address->m_family == GSOCK_NOFAMILY) {
182 socket->m_error = GSOCK_INVADDR;
a324a7bc 183 return GSOCK_INVADDR;
31989b0b 184 }
a324a7bc
GL
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
194GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address)
195{
5a96d2f4 196 assert(socket != NULL);
a324a7bc
GL
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
211GAddress *GSocket_GetLocal(GSocket *socket)
212{
213 GAddress *address;
214 struct sockaddr addr;
85806dc2 215 SOCKLEN_T size = sizeof(addr);
aa6d9706 216 GSocketError err;
a324a7bc
GL
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
85806dc2 230 if (getsockname(socket->m_fd, &addr, (SOCKLEN_T *) &size) < 0) {
a324a7bc
GL
231 socket->m_error = GSOCK_IOERR;
232 return NULL;
233 }
234
235 address = GAddress_new();
e00f35bb
GL
236 if (address == NULL) {
237 socket->m_error = GSOCK_MEMERR;
238 return NULL;
239 }
85806dc2
GRG
240 err = _GAddress_translate_from(address, &addr, size); /*xxx*/
241 if (err != GSOCK_NOERROR) {
e00f35bb 242 GAddress_destroy(address);
85806dc2 243 socket->m_error = err;
e00f35bb
GL
244 return NULL;
245 }
a324a7bc
GL
246
247 return address;
248}
249
250GAddress *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
2f7c2af5
GRG
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 */
a324a7bc
GL
269GSocketError GSocket_SetServer(GSocket *sck)
270{
271 int type;
483249fc 272 int arg = 1;
a324a7bc
GL
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
f61815af
GL
286 /* We always have a stream here */
287 sck->m_stream = TRUE;
8f7173ab 288 sck->m_server = TRUE;
a324a7bc 289
f61815af
GL
290 /* Create the socket */
291 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0);
a324a7bc
GL
292
293 if (sck->m_fd == -1) {
294 sck->m_error = GSOCK_IOERR;
295 return GSOCK_IOERR;
296 }
297
483249fc
GRG
298 ioctl(sck->m_fd, FIONBIO, &arg);
299 _GSocket_Enable_Events(sck);
300
f61815af 301 /* Bind the socket to the LOCAL address */
a324a7bc
GL
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
f61815af 309 /* Enable listening up to 5 connections */
a324a7bc
GL
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
a324a7bc 317 return GSOCK_NOERROR;
a324a7bc
GL
318}
319
2f7c2af5
GRG
320/* GSocket_WaitConnection:
321 * Waits for an incoming client connection.
322 */
a324a7bc
GL
323GSocket *GSocket_WaitConnection(GSocket *socket)
324{
85806dc2
GRG
325 struct sockaddr from;
326 SOCKLEN_T fromlen = sizeof(from);
a324a7bc 327 GSocket *connection;
483249fc 328 int arg = 1;
a324a7bc
GL
329
330 assert(socket != NULL);
331
483249fc
GRG
332 /* Reenable CONNECTION events */
333 _GSocket_Enable(socket, GSOCK_CONNECTION);
334
f61815af 335 /* If the socket has already been created, we exit immediately */
483249fc
GRG
336 if (socket->m_fd == -1 || !socket->m_server)
337 {
a324a7bc
GL
338 socket->m_error = GSOCK_INVSOCK;
339 return NULL;
340 }
341
f61815af 342 /* Create a GSocket object for the new connection */
a324a7bc 343 connection = GSocket_new();
483249fc
GRG
344 if (!connection)
345 {
85806dc2 346 socket->m_error = GSOCK_MEMERR;
aa6d9706
GL
347 return NULL;
348 }
a324a7bc 349
f61815af 350 /* Accept the incoming connection */
483249fc
GRG
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
85806dc2 358 connection->m_fd = accept(socket->m_fd, &from, (SOCKLEN_T *) &fromlen);
483249fc
GRG
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
a324a7bc 367 GSocket_destroy(connection);
a324a7bc
GL
368 return NULL;
369 }
370
f61815af 371 /* Initialize all fields */
a324a7bc 372 connection->m_server = FALSE;
483249fc 373 connection->m_stream = TRUE;
a324a7bc
GL
374 connection->m_oriented = TRUE;
375
85806dc2
GRG
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
483249fc
GRG
393 ioctl(connection->m_fd, FIONBIO, &arg);
394 _GSocket_Enable_Events(connection);
2f7c2af5 395
a324a7bc
GL
396 return connection;
397}
398
399/* Non oriented connections */
400
401GSocketError GSocket_SetNonOriented(GSocket *sck)
402{
483249fc
GRG
403 int arg = 1;
404
a324a7bc
GL
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
f61815af 421 /* Create the socket */
a324a7bc
GL
422 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
423
aa6d9706
GL
424 if (sck->m_fd < 0) {
425 sck->m_error = GSOCK_IOERR;
426 return GSOCK_IOERR;
427 }
428
483249fc
GRG
429 ioctl(sck->m_fd, FIONBIO, &arg);
430 _GSocket_Enable_Events(sck);
431
f61815af 432 /* Bind it to the LOCAL address */
a324a7bc
GL
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
2f7c2af5
GRG
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 */
a324a7bc
GL
454GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
455{
483249fc
GRG
456 int type, err, ret;
457 int arg = 1;
a324a7bc
GL
458
459 assert(sck != NULL);
460
483249fc
GRG
461 /* Enable CONNECTION events (needed for nonblocking connections) */
462 _GSocket_Enable(sck, GSOCK_CONNECTION);
463
464 if (sck->m_fd != -1)
465 {
a324a7bc
GL
466 sck->m_error = GSOCK_INVSOCK;
467 return GSOCK_INVSOCK;
468 }
469
483249fc
GRG
470 if (!sck->m_peer)
471 {
a324a7bc
GL
472 sck->m_error = GSOCK_INVADDR;
473 return GSOCK_INVADDR;
474 }
475
f61815af 476 /* Test whether we want the socket to be a stream (e.g. TCP) */
483249fc 477 sck->m_stream = (stream == GSOCK_STREAMED);
a324a7bc 478 sck->m_oriented = TRUE;
483249fc
GRG
479 sck->m_server = FALSE;
480 sck->m_establishing = FALSE;
a324a7bc
GL
481
482 if (sck->m_stream)
483 type = SOCK_STREAM;
484 else
485 type = SOCK_DGRAM;
486
f61815af 487 /* Create the socket */
a324a7bc
GL
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
483249fc
GRG
495 ioctl(sck->m_fd, FIONBIO, &arg);
496 _GSocket_Enable_Events(sck);
aa6d9706 497
f61815af 498 /* Connect it to the PEER address */
483249fc
GRG
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 */
483249fc
GRG
517 return GSOCK_TIMEDOUT;
518 }
519 else
520 {
483249fc
GRG
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;
483249fc
GRG
535
536 return GSOCK_WOULDBLOCK;
537 }
aa6d9706 538
483249fc
GRG
539 /* If connect failed with an error other than EINPROGRESS,
540 * then the call to GSocket_Connect has failed.
541 */
a324a7bc
GL
542 close(sck->m_fd);
543 sck->m_fd = -1;
483249fc
GRG
544 sck->m_error = GSOCK_IOERR;
545
a324a7bc
GL
546 return GSOCK_IOERR;
547 }
39b91eca 548
483249fc 549 return GSOCK_NOERROR;
a324a7bc
GL
550}
551
552/* Generic IO */
553
554/* Like recv(), send(), ... */
555int GSocket_Read(GSocket *socket, char *buffer, int size)
556{
483249fc
GRG
557 int ret;
558
a324a7bc
GL
559 assert(socket != NULL);
560
483249fc
GRG
561 /* Reenable INPUT events */
562 _GSocket_Enable(socket, GSOCK_INPUT);
563
564 if (socket->m_fd == -1 || socket->m_server)
565 {
a324a7bc
GL
566 socket->m_error = GSOCK_INVSOCK;
567 return -1;
568 }
569
483249fc
GRG
570 if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
571 return -1;
a324a7bc 572
f61815af 573 if (socket->m_stream)
483249fc 574 ret = _GSocket_Recv_Stream(socket, buffer, size);
a324a7bc 575 else
483249fc
GRG
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;
a324a7bc
GL
587}
588
589int GSocket_Write(GSocket *socket, const char *buffer,
590 int size)
591{
483249fc
GRG
592 int ret;
593
a324a7bc
GL
594 assert(socket != NULL);
595
483249fc
GRG
596 if (socket->m_fd == -1 || socket->m_server)
597 {
a324a7bc
GL
598 socket->m_error = GSOCK_INVSOCK;
599 return -1;
600 }
601
483249fc
GRG
602 if (_GSocket_Output_Timeout(socket) == GSOCK_TIMEDOUT)
603 return -1;
a324a7bc 604
f61815af 605 if (socket->m_stream)
483249fc 606 ret = _GSocket_Send_Stream(socket, buffer, size);
a324a7bc 607 else
483249fc
GRG
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;
a324a7bc
GL
626}
627
ef25e638
GRG
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 */
635GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags)
a324a7bc 636{
a324a7bc
GL
637 assert(socket != NULL);
638
483249fc 639 return (flags & socket->m_detected);
a324a7bc
GL
640}
641
642/* Flags */
643
2f7c2af5
GRG
644/* GSocket_SetNonBlocking:
645 * Sets the socket to non-blocking mode. This is useful if
646 * we don't want to wait.
647 */
54e575f9 648void GSocket_SetNonBlocking(GSocket *socket, bool non_block)
a324a7bc
GL
649{
650 assert(socket != NULL);
651
dc26b37a 652 socket->m_non_blocking = non_block;
a324a7bc
GL
653}
654
2f7c2af5
GRG
655/* GSocket_SetTimeout:
656 * Sets the timeout for blocking calls. Time is
657 * expressed in milliseconds.
39b91eca
GL
658 */
659void GSocket_SetTimeout(GSocket *socket, unsigned long millisec)
660{
661 assert(socket != NULL);
662
54e575f9 663 socket->m_timeout = millisec;
39b91eca
GL
664}
665
2f7c2af5
GRG
666/* GSocket_GetError:
667 * Returns the last error occured for this socket.
668 */
a324a7bc
GL
669GSocketError GSocket_GetError(GSocket *socket)
670{
671 assert(socket != NULL);
672
673 return socket->m_error;
674}
675
676/* Callbacks */
677
2f7c2af5
GRG
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 */
ef25e638 702void GSocket_SetCallback(GSocket *socket, GSocketEventFlags flags,
98781fa3 703 GSocketCallback callback, char *cdata)
a324a7bc
GL
704{
705 int count;
706
483249fc 707 assert(socket != NULL);
a324a7bc 708
483249fc
GRG
709 for (count = 0; count < GSOCK_MAX_EVENT; count++)
710 {
711 if ((flags & (1 << count)) != 0)
712 {
98781fa3 713 socket->m_cbacks[count] = callback;
a324a7bc 714 socket->m_data[count] = cdata;
a324a7bc
GL
715 }
716 }
717}
718
2f7c2af5
GRG
719/* GSocket_UnsetCallback:
720 * Disables all callbacks specified by 'flags', which may be a
721 * combination of flags OR'ed toghether.
722 */
ef25e638 723void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags)
a324a7bc 724{
2f7c2af5 725 int count;
a324a7bc
GL
726
727 assert(socket != NULL);
728
483249fc
GRG
729 for (count = 0; count < GSOCK_MAX_EVENT; count++)
730 {
731 if ((flags & (1 << count)) != 0)
732 {
98781fa3 733 socket->m_cbacks[count] = NULL;
483249fc 734 socket->m_data[count] = NULL;
a324a7bc
GL
735 }
736 }
737}
738
483249fc
GRG
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]); \
a324a7bc
GL
743}
744
483249fc 745
a324a7bc
GL
746void _GSocket_Enable(GSocket *socket, GSocketEvent event)
747{
483249fc
GRG
748 socket->m_detected &= ~(1 << event);
749 _GSocket_Install_Callback(socket, event);
a324a7bc
GL
750}
751
752void _GSocket_Disable(GSocket *socket, GSocketEvent event)
753{
483249fc
GRG
754 socket->m_detected |= (1 << event);
755 _GSocket_Uninstall_Callback(socket, event);
a324a7bc
GL
756}
757
483249fc
GRG
758/* _GSocket_Input_Timeout:
759 * For blocking sockets, wait until data is available or
760 * until timeout ellapses.
761 */
762GSocketError _GSocket_Input_Timeout(GSocket *socket)
2f7c2af5 763{
483249fc
GRG
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 */
788GSocketError _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;
2f7c2af5
GRG
805 }
806 }
483249fc 807 return GSOCK_NOERROR;
2f7c2af5
GRG
808}
809
a324a7bc
GL
810int _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();
54e575f9 817
a324a7bc
GL
818 return ret;
819}
820
821int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
822{
823 struct sockaddr from;
85806dc2 824 SOCKLEN_T fromlen = sizeof(from);
ca17eff3 825 int ret;
aa6d9706 826 GSocketError err;
a324a7bc
GL
827
828 fromlen = sizeof(from);
829
830 MASK_SIGNAL();
85806dc2 831 ret = recvfrom(socket->m_fd, buffer, size, 0, &from, (SOCKLEN_T *) &fromlen);
a324a7bc 832 UNMASK_SIGNAL();
483249fc
GRG
833
834 if (ret == -1)
aa6d9706 835 return -1;
a324a7bc 836
f61815af 837 /* Translate a system address into a GSocket address */
483249fc
GRG
838 if (!socket->m_peer)
839 {
a324a7bc 840 socket->m_peer = GAddress_new();
483249fc
GRG
841 if (!socket->m_peer)
842 {
e00f35bb
GL
843 socket->m_error = GSOCK_MEMERR;
844 return -1;
845 }
846 }
aa6d9706 847 err = _GAddress_translate_from(socket->m_peer, &from, fromlen);
483249fc
GRG
848 if (err != GSOCK_NOERROR)
849 {
aa6d9706
GL
850 GAddress_destroy(socket->m_peer);
851 socket->m_peer = NULL;
852 socket->m_error = err;
e00f35bb 853 return -1;
aa6d9706 854 }
a324a7bc
GL
855
856 return ret;
857}
858
859int _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();
483249fc 866
a324a7bc
GL
867 return ret;
868}
869
870int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
871{
872 struct sockaddr *addr;
873 int len, ret;
aa6d9706 874 GSocketError err;
a324a7bc
GL
875
876 if (!socket->m_peer) {
877 socket->m_error = GSOCK_INVADDR;
878 return -1;
879 }
880
aa6d9706
GL
881 err = _GAddress_translate_to(socket->m_peer, &addr, &len);
882 if (err != GSOCK_NOERROR) {
883 socket->m_error = err;
e00f35bb
GL
884 return -1;
885 }
a324a7bc
GL
886
887 MASK_SIGNAL();
888 ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
889 UNMASK_SIGNAL();
a324a7bc 890
f61815af 891 /* Frees memory allocated from _GAddress_translate_to */
a324a7bc
GL
892 free(addr);
893
894 return ret;
895}
896
897void _GSocket_Detected_Read(GSocket *socket)
898{
899 char c;
900 int ret;
901
483249fc
GRG
902 if (socket->m_stream)
903 {
a324a7bc
GL
904 ret = recv(socket->m_fd, &c, 1, MSG_PEEK);
905
483249fc
GRG
906 if (ret < 0 && socket->m_server)
907 {
aa6d9706 908 CALL_CALLBACK(socket, GSOCK_CONNECTION);
a324a7bc
GL
909 return;
910 }
911
483249fc
GRG
912 if (ret > 0)
913 {
aa6d9706 914 CALL_CALLBACK(socket, GSOCK_INPUT);
483249fc
GRG
915 }
916 else
917 {
aa6d9706 918 CALL_CALLBACK(socket, GSOCK_LOST);
a324a7bc
GL
919 }
920 }
921}
922
923void _GSocket_Detected_Write(GSocket *socket)
924{
483249fc
GRG
925 if (socket->m_establishing && !socket->m_server)
926 {
aa6d9706
GL
927 int error, len;
928
aa6d9706 929 socket->m_establishing = FALSE;
aa6d9706 930
483249fc 931 len = sizeof(error);
af9d1662 932 getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, (void*) &error,
85806dc2 933 (SOCKLEN_T *) &len);
aa6d9706 934
483249fc
GRG
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 {
aa6d9706 951 CALL_CALLBACK(socket, GSOCK_OUTPUT);
483249fc 952 }
aa6d9706 953}
a324a7bc
GL
954
955/*
956 * -------------------------------------------------------------------------
957 * GAddress
958 * -------------------------------------------------------------------------
959 */
960
f61815af
GL
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 */
a324a7bc
GL
965#define CHECK_ADDRESS(address, family, retval) \
966{ \
967 if (address->m_family == GSOCK_NOFAMILY) \
54e575f9
GL
968 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) {\
969 return address->m_error; \
e00f35bb 970 }\
a324a7bc
GL
971 if (address->m_family != GSOCK_##family) {\
972 address->m_error = GSOCK_INVADDR; \
973 return retval; \
974 } \
975}
976
977GAddress *GAddress_new()
978{
979 GAddress *address;
980
981 address = (GAddress *)malloc(sizeof(GAddress));
982
e00f35bb
GL
983 if (address == NULL)
984 return NULL;
985
a324a7bc
GL
986 address->m_family = GSOCK_NOFAMILY;
987 address->m_addr = NULL;
988 address->m_len = 0;
989
990 return address;
991}
992
993GAddress *GAddress_copy(GAddress *address)
994{
995 GAddress *addr2;
996
997 assert(address != NULL);
998
999 addr2 = (GAddress *)malloc(sizeof(GAddress));
e00f35bb
GL
1000
1001 if (addr2 == NULL)
1002 return NULL;
1003
a324a7bc
GL
1004 memcpy(addr2, address, sizeof(GAddress));
1005
1006 if (address->m_addr) {
1007 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
e00f35bb
GL
1008 if (addr2->m_addr == NULL) {
1009 free(addr2);
1010 return NULL;
1011 }
a324a7bc
GL
1012 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
1013 }
1014
1015 return addr2;
1016}
1017
1018void GAddress_destroy(GAddress *address)
1019{
1020 assert(address != NULL);
1021
1022 free(address);
1023}
1024
1025void GAddress_SetFamily(GAddress *address, GAddressType type)
1026{
1027 assert(address != NULL);
1028
1029 address->m_family = type;
1030}
1031
1032GAddressType GAddress_GetFamily(GAddress *address)
1033{
1034 assert(address != NULL);
1035
1036 return address->m_family;
1037}
1038
54e575f9 1039GSocketError _GAddress_translate_from(GAddress *address, struct sockaddr *addr, int len){
a324a7bc
GL
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;
efee48a0 1048#ifdef AF_INET6
a324a7bc
GL
1049 case AF_INET6:
1050 address->m_family = GSOCK_INET6;
1051 break;
efee48a0 1052#endif
a324a7bc 1053 default:
ca17eff3 1054 {
54e575f9
GL
1055 address->m_error = GSOCK_INVOP;
1056 return GSOCK_INVOP;
ca17eff3 1057 }
a324a7bc
GL
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);
54e575f9
GL
1065 if (address->m_addr == NULL) {
1066 address->m_error = GSOCK_MEMERR;
1067 return GSOCK_MEMERR;
1068 }
a324a7bc 1069 memcpy(address->m_addr, addr, len);
e00f35bb 1070
54e575f9 1071 return GSOCK_NOERROR;
a324a7bc
GL
1072}
1073
54e575f9
GL
1074GSocketError _GAddress_translate_to(GAddress *address,
1075 struct sockaddr **addr, int *len)
a324a7bc
GL
1076{
1077 if (!address->m_addr) {
54e575f9
GL
1078 address->m_error = GSOCK_INVADDR;
1079 return GSOCK_INVADDR;
a324a7bc
GL
1080 }
1081
1082 *len = address->m_len;
1083 *addr = (struct sockaddr *)malloc(address->m_len);
54e575f9
GL
1084 if (*addr == NULL) {
1085 address->m_error = GSOCK_MEMERR;
1086 return GSOCK_MEMERR;
1087 }
e00f35bb 1088
a324a7bc 1089 memcpy(*addr, address->m_addr, address->m_len);
54e575f9 1090 return GSOCK_NOERROR;
a324a7bc
GL
1091}
1092
1093/*
1094 * -------------------------------------------------------------------------
1095 * Internet address family
1096 * -------------------------------------------------------------------------
1097 */
1098
54e575f9 1099GSocketError _GAddress_Init_INET(GAddress *address)
a324a7bc 1100{
f3e60952 1101 address->m_len = sizeof(struct sockaddr_in);
d5370801 1102 address->m_addr = (struct sockaddr *)malloc(address->m_len);
f3e60952
GRG
1103 if (address->m_addr == NULL)
1104 {
54e575f9
GL
1105 address->m_error = GSOCK_MEMERR;
1106 return GSOCK_MEMERR;
1107 }
e00f35bb 1108
a324a7bc
GL
1109 address->m_family = GSOCK_INET;
1110 address->m_realfamily = PF_INET;
1111 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
52a55020
VZ
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 */
11694d1f 1116 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_BROADCAST;
e00f35bb 1117
cc345f78 1118 return GSOCK_NOERROR;
a324a7bc
GL
1119}
1120
1121GSocketError 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
f61815af 1132 /* If it is a numeric host name, convert it now */
d5b08e7b 1133#if defined(HAVE_INET_ATON)
f3e60952
GRG
1134 if (inet_aton(hostname, addr) == 0)
1135 {
d5b08e7b 1136#elif defined(HAVE_INET_ADDR)
e96ac54e 1137 /* Fix from Guillermo Rodriguez Garcia <guille@iies.es> */
f3e60952
GRG
1138 if ( (addr->s_addr = inet_addr(hostname)) == -1 )
1139 {
e96ac54e
GL
1140#else
1141 /* Use gethostbyname by default */
f3e60952
GRG
1142 if (1)
1143 {
e96ac54e 1144#endif
a324a7bc
GL
1145 struct in_addr *array_addr;
1146
f61815af 1147 /* It is a real name, we solve it */
f3e60952
GRG
1148 if ((he = gethostbyname(hostname)) == NULL)
1149 {
a324a7bc
GL
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
1159GSocketError 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
5a96d2f4
GL
1174GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1175 const char *protocol)
a324a7bc
GL
1176{
1177 struct servent *se;
1178 struct sockaddr_in *addr;
1179
1180 assert(address != NULL);
1181 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1182
f3e60952
GRG
1183 if (!port)
1184 {
a324a7bc 1185 address->m_error = GSOCK_INVPORT;
54e575f9 1186 return GSOCK_INVPORT;
a324a7bc
GL
1187 }
1188
5a96d2f4 1189 se = getservbyname(port, protocol);
a324a7bc 1190 if (!se) {
f3e60952
GRG
1191 if (isdigit(port[0]))
1192 {
a324a7bc
GL
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
1211GSocketError 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
1224GSocketError 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
f3e60952
GRG
1236 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1237 if (he == NULL)
1238 {
a324a7bc
GL
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
1248unsigned 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
1260unsigned 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
54e575f9 1277GSocketError _GAddress_Init_UNIX(GAddress *address)
a324a7bc 1278{
f3e60952 1279 address->m_len = sizeof(struct sockaddr_un);
a324a7bc 1280 address->m_addr = (struct sockaddr *)malloc(address->m_len);
f3e60952
GRG
1281 if (address->m_addr == NULL)
1282 {
54e575f9
GL
1283 address->m_error = GSOCK_MEMERR;
1284 return GSOCK_MEMERR;
1285 }
e00f35bb 1286
a324a7bc
GL
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;
e00f35bb
GL
1291
1292 return TRUE;
a324a7bc
GL
1293}
1294
1295GSocketError 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
1309GSocketError 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}
813c20a6 1322
d422d01e
RR
1323#endif
1324 /* wxUSE_SOCKETS */
85806dc2 1325