]> git.saurik.com Git - wxWidgets.git/blame - src/os2/gsocket.c
Completely reworked OS/2 thread implementation.
[wxWidgets.git] / src / os2 / gsocket.c
CommitLineData
fb9010ed
DW
1/* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket) for WX
3 * Name: gsocket.c
3958ae62
SN
4 * Authors: Guilhem Lavaux,
5 * Guillermo Rodriguez Garcia <guille@iies.es> (maintainer)
fb9010ed 6 * Purpose: GSocket main Unix-style file
84969af7 7 * Licence: The wxWindows licence
fb9010ed
DW
8 * CVSID: $Id$
9 * -------------------------------------------------------------------------
10 */
11
3958ae62
SN
12/*
13 * PLEASE don't put C++ comments here - this is a C source file.
14 */
15
16#ifndef __GSOCKET_STANDALONE__
fb9010ed 17#include "wx/setup.h"
3958ae62
SN
18#endif
19
bfdc8d18
SN
20#ifndef __EMX__
21/* I don't see, why this include is needed, but it seems to be necessary
22 sometimes. For EMX, including C++ headers into plain C source breaks
23 compilation, so don't do it there. */
1cd04aa2 24#include "wx/defs.h"
bfdc8d18 25#endif
fb9010ed 26
3958ae62 27#if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
fb9010ed 28
9dea36ef 29#define BSD_SELECT /* use Berkley Sockets select */
fb9010ed
DW
30
31#include <assert.h>
19193a2c 32#include <sys/types.h>
29d83fc1 33
610c9851
SN
34#ifdef __EMX__
35#include <sys/time.h>
36#include <netinet/in.h>
37#include <arpa/inet.h>
38#include <netdb.h>
39#include <errno.h>
3958ae62
SN
40#include <unistd.h>
41#include <sys/un.h>
610c9851 42#define HAVE_INET_ADDR
29d83fc1 43
610c9851 44#else
29d83fc1 45
19193a2c
KB
46#include <string.h>
47
48#include <sys/time.h>
5fd2b2c6 49#include <types.h>
19193a2c 50#include <netinet/in.h>
fb9010ed
DW
51#include <netdb.h>
52#include <nerrno.h>
29d83fc1 53
610c9851 54#endif
29d83fc1 55
9ac6ff7b 56#if defined(__VISAGECPP__) && __IBMCPP__ < 400
29d83fc1 57
19193a2c 58#include <machine/endian.h>
9ac6ff7b
DW
59#include <socket.h>
60#include <ioctl.h>
61#include <select.h>
5fd2b2c6 62#include <unistd.h>
29d83fc1
DW
63
64#define EBADF SOCEBADF
65
9ac6ff7b 66#else
29d83fc1 67
19193a2c
KB
68#include <sys/socket.h>
69#include <sys/ioctl.h>
70#include <sys/select.h>
29d83fc1 71
521ccc1b
SN
72#ifdef __EMX__
73#define soclose(a) close(a)
74#else
9dea36ef
DW
75#define select(a,b,c,d,e) bsdselect(a,b,c,d,e)
76int _System bsdselect(int,
77 struct fd_set *,
78 struct fd_set *,
79 struct fd_set *,
80 struct timeval *);
81int _System soclose(int);
9ac6ff7b 82#endif
610c9851 83#endif
fb9010ed 84
fb9010ed 85#include <stdio.h>
3958ae62 86#if (defined(__VISAGECPP__) && __IBMCPP__ < 400) || defined(__EMX__)
e15bbde0
DW
87# ifdef min
88# undef min
89# endif
90# include <stdlib.h>
91#endif
fb9010ed
DW
92#include <stddef.h>
93#include <ctype.h>
19193a2c 94#include <stdlib.h>
fb9010ed
DW
95
96#include <signal.h>
97
fb9010ed
DW
98#ifndef SOCKLEN_T
99
100#ifdef __GLIBC__
101# if __GLIBC__ == 2
102# define SOCKLEN_T socklen_t
103# endif
104#else
105# define SOCKLEN_T int
106#endif
107
108#endif
109
3958ae62
SN
110/*
111 * MSW defines this, Unices don't.
112 */
113#ifndef INVALID_SOCKET
114#define INVALID_SOCKET -1
115#endif
116
117/*
118 * INADDR_BROADCAST is identical to INADDR_NONE which is not defined
119 * on all systems. INADDR_BROADCAST should be fine to indicate an error.
120 */
121#ifndef INADDR_NONE
122#define INADDR_NONE INADDR_BROADCAST
123#endif
124
125#define MASK_SIGNAL() \
126{ \
127 void (*old_handler)(int); \
128 \
129 old_handler = signal(SIGPIPE, SIG_IGN);
130
131#define UNMASK_SIGNAL() \
132 signal(SIGPIPE, old_handler); \
133}
134
e32c4e60 135
3958ae62
SN
136#ifndef __GSOCKET_STANDALONE__
137# include "wx/unix/gsockunx.h"
138# include "wx/gsocket.h"
139#else
140# include "gsockunx.h"
141# include "gsocket.h"
142#endif /* __GSOCKET_STANDALONE__ */
143
3958ae62 144/* debugging helpers */
3958ae62
SN
145#ifdef __GSOCKET_DEBUG__
146# define GSocket_Debug(args) printf args
147#else
148# define GSocket_Debug(args)
149#endif /* __GSOCKET_DEBUG__ */
150
38bb138f
VS
151/* Table of GUI-related functions. We must call them indirectly because
152 * of wxBase and GUI separation: */
153
154static struct GSocketGUIFunctionsTable *gs_gui_functions;
155
156#define USE_GUI() (gs_gui_functions != NULL)
157
158/* Define macros to simplify indirection: */
159#define _GSocket_GUI_Init() \
160 if (gs_gui_functions) gs_gui_functions->GUI_Init()
161#define _GSocket_GUI_Cleanup() \
162 if (gs_gui_functions) gs_gui_functions->GUI_Cleanup()
163#define _GSocket_GUI_Init_Socket(socket) \
164 (gs_gui_functions ? gs_gui_functions->GUI_Init_Socket(socket) : 1)
165#define _GSocket_GUI_Destroy_Socket(socket) \
166 if (gs_gui_functions) gs_gui_functions->GUI_Destroy_Socket(socket)
167#define _GSocket_Enable_Events(socket) \
168 if (gs_gui_functions) gs_gui_functions->Enable_Events(socket)
169#define _GSocket_Disable_Events(socket) \
170 if (gs_gui_functions) gs_gui_functions->Disable_Events(socket)
171#define _GSocket_Install_Callback(socket, event) \
172 if (gs_gui_functions) gs_gui_functions->Install_Callback(socket, event)
173#define _GSocket_Uninstall_Callback(socket, event) \
174 if (gs_gui_functions) gs_gui_functions->Uninstall_Callback(socket, event)
175
176static struct GSocketBaseFunctionsTable gs_base_functions =
177{
178 _GSocket_Detected_Read,
179 _GSocket_Detected_Write
180};
181
fb9010ed
DW
182/* Global initialisers */
183
38bb138f
VS
184void GSocket_SetGUIFunctions(struct GSocketGUIFunctionsTable *guifunc)
185{
186 gs_gui_functions = guifunc;
187}
188
3958ae62 189int GSocket_Init(void)
fb9010ed 190{
38bb138f
VS
191 if (gs_gui_functions)
192 {
193 if ( !gs_gui_functions->GUI_Init() )
194 return 0;
195 }
27f37ae5 196 return 1;
fb9010ed
DW
197}
198
3958ae62 199void GSocket_Cleanup(void)
fb9010ed 200{
38bb138f
VS
201 if (gs_gui_functions)
202 {
203 gs_gui_functions->GUI_Cleanup();
204 }
fb9010ed
DW
205}
206
3958ae62 207/* Constructors / Destructors for GSocket */
fb9010ed 208
3958ae62 209GSocket *GSocket_new(void)
fb9010ed 210{
3958ae62 211 int i, success;
fb9010ed
DW
212 GSocket *socket;
213
214 socket = (GSocket *)malloc(sizeof(GSocket));
215
216 if (socket == NULL)
217 return NULL;
218
3958ae62 219 socket->m_fd = INVALID_SOCKET;
fb9010ed
DW
220 for (i=0;i<GSOCK_MAX_EVENT;i++)
221 {
222 socket->m_cbacks[i] = NULL;
223 }
224 socket->m_detected = 0;
225 socket->m_local = NULL;
226 socket->m_peer = NULL;
227 socket->m_error = GSOCK_NOERROR;
3958ae62
SN
228 socket->m_server = FALSE;
229 socket->m_stream = TRUE;
fb9010ed 230 socket->m_gui_dependent = NULL;
3958ae62 231 socket->m_non_blocking = FALSE;
fb9010ed
DW
232 socket->m_timeout = 10*60*1000;
233 /* 10 minutes * 60 sec * 1000 millisec */
3958ae62
SN
234 socket->m_establishing = FALSE;
235
38bb138f
VS
236 socket->m_functions = &gs_base_functions;
237
3958ae62 238 /* Per-socket GUI-specific initialization */
38bb138f 239 success = _GSocket_GUI_Init_Socket(socket);
3958ae62
SN
240 if (!success)
241 {
242 free(socket);
243 return NULL;
244 }
fb9010ed 245
fb9010ed
DW
246 return socket;
247}
248
e32c4e60
SN
249void GSocket_close(GSocket *socket)
250{
251 _GSocket_Disable_Events(socket);
252 soclose(socket->m_fd);
253 socket->m_fd = INVALID_SOCKET;
254}
255
fb9010ed
DW
256void GSocket_destroy(GSocket *socket)
257{
258 assert(socket != NULL);
259
3958ae62
SN
260 /* Check that the socket is really shutdowned */
261 if (socket->m_fd != INVALID_SOCKET)
fb9010ed
DW
262 GSocket_Shutdown(socket);
263
3958ae62 264 /* Per-socket GUI-specific cleanup */
38bb138f 265 _GSocket_GUI_Destroy_Socket(socket);
3958ae62
SN
266
267 /* Destroy private addresses */
fb9010ed
DW
268 if (socket->m_local)
269 GAddress_destroy(socket->m_local);
270
271 if (socket->m_peer)
272 GAddress_destroy(socket->m_peer);
273
3958ae62 274 /* Destroy the socket itself */
fb9010ed
DW
275 free(socket);
276}
277
3958ae62
SN
278/* GSocket_Shutdown:
279 * Disallow further read/write operations on this socket, close
280 * the fd and disable all callbacks.
281 */
fb9010ed
DW
282void GSocket_Shutdown(GSocket *socket)
283{
284 int evt;
285
286 assert(socket != NULL);
287
3958ae62
SN
288 /* If socket has been created, shutdown it */
289 if (socket->m_fd != INVALID_SOCKET)
fb9010ed
DW
290 {
291 shutdown(socket->m_fd, 2);
e32c4e60 292 GSocket_close(socket);
fb9010ed
DW
293 }
294
3958ae62 295 /* Disable GUI callbacks */
fb9010ed
DW
296 for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
297 socket->m_cbacks[evt] = NULL;
298
3958ae62
SN
299 socket->m_detected = GSOCK_LOST_FLAG;
300 _GSocket_Disable_Events(socket);
fb9010ed
DW
301}
302
303/* Address handling */
304
3958ae62
SN
305/* GSocket_SetLocal:
306 * GSocket_GetLocal:
307 * GSocket_SetPeer:
308 * GSocket_GetPeer:
309 * Set or get the local or peer address for this socket. The 'set'
310 * functions return GSOCK_NOERROR on success, an error code otherwise.
311 * The 'get' functions return a pointer to a GAddress object on success,
312 * or NULL otherwise, in which case they set the error code of the
313 * corresponding GSocket.
314 *
315 * Error codes:
316 * GSOCK_INVSOCK - the socket is not valid.
317 * GSOCK_INVADDR - the address is not valid.
318 */
fb9010ed
DW
319GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address)
320{
321 assert(socket != NULL);
322
3958ae62
SN
323 /* the socket must be initialized, or it must be a server */
324 if ((socket->m_fd != INVALID_SOCKET && !socket->m_server))
325 {
fb9010ed
DW
326 socket->m_error = GSOCK_INVSOCK;
327 return GSOCK_INVSOCK;
328 }
329
3958ae62
SN
330 /* check address */
331 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
332 {
fb9010ed
DW
333 socket->m_error = GSOCK_INVADDR;
334 return GSOCK_INVADDR;
335 }
336
337 if (socket->m_local)
338 GAddress_destroy(socket->m_local);
339
340 socket->m_local = GAddress_copy(address);
341
342 return GSOCK_NOERROR;
343}
344
345GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address)
346{
347 assert(socket != NULL);
348
3958ae62
SN
349 /* check address */
350 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
351 {
fb9010ed
DW
352 socket->m_error = GSOCK_INVADDR;
353 return GSOCK_INVADDR;
354 }
355
356 if (socket->m_peer)
357 GAddress_destroy(socket->m_peer);
358
359 socket->m_peer = GAddress_copy(address);
360
361 return GSOCK_NOERROR;
362}
363
364GAddress *GSocket_GetLocal(GSocket *socket)
365{
366 GAddress *address;
367 struct sockaddr addr;
3958ae62 368 SOCKLEN_T size = sizeof(addr);
fb9010ed
DW
369 GSocketError err;
370
371 assert(socket != NULL);
372
3958ae62 373 /* try to get it from the m_local var first */
fb9010ed
DW
374 if (socket->m_local)
375 return GAddress_copy(socket->m_local);
376
3958ae62
SN
377 /* else, if the socket is initialized, try getsockname */
378 if (socket->m_fd == INVALID_SOCKET)
379 {
fb9010ed
DW
380 socket->m_error = GSOCK_INVSOCK;
381 return NULL;
382 }
383
3958ae62
SN
384 if (getsockname(socket->m_fd, &addr, (SOCKLEN_T *) &size) < 0)
385 {
fb9010ed
DW
386 socket->m_error = GSOCK_IOERR;
387 return NULL;
388 }
389
3958ae62 390 /* got a valid address from getsockname, create a GAddress object */
fb9010ed 391 address = GAddress_new();
3958ae62
SN
392 if (address == NULL)
393 {
fb9010ed
DW
394 socket->m_error = GSOCK_MEMERR;
395 return NULL;
396 }
3958ae62
SN
397
398 err = _GAddress_translate_from(address, &addr, size);
399 if (err != GSOCK_NOERROR)
400 {
fb9010ed 401 GAddress_destroy(address);
3958ae62 402 socket->m_error = err;
fb9010ed
DW
403 return NULL;
404 }
405
406 return address;
407}
408
409GAddress *GSocket_GetPeer(GSocket *socket)
410{
411 assert(socket != NULL);
412
3958ae62 413 /* try to get it from the m_peer var */
fb9010ed
DW
414 if (socket->m_peer)
415 return GAddress_copy(socket->m_peer);
416
417 return NULL;
418}
419
420/* Server specific parts */
421
422/* GSocket_SetServer:
3958ae62
SN
423 * Sets up this socket as a server. The local address must have been
424 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
425 * Returns GSOCK_NOERROR on success, one of the following otherwise:
e32c4e60 426 *
3958ae62
SN
427 * Error codes:
428 * GSOCK_INVSOCK - the socket is in use.
429 * GSOCK_INVADDR - the local address has not been set.
e32c4e60 430 * GSOCK_IOERR - low-level error.
fb9010ed
DW
431 */
432GSocketError GSocket_SetServer(GSocket *sck)
433{
fb9010ed
DW
434 int arg = 1;
435
436 assert(sck != NULL);
437
3958ae62
SN
438 /* must not be in use */
439 if (sck->m_fd != INVALID_SOCKET)
440 {
fb9010ed
DW
441 sck->m_error = GSOCK_INVSOCK;
442 return GSOCK_INVSOCK;
443 }
444
3958ae62
SN
445 /* the local addr must have been set */
446 if (!sck->m_local)
447 {
fb9010ed
DW
448 sck->m_error = GSOCK_INVADDR;
449 return GSOCK_INVADDR;
450 }
451
3958ae62
SN
452 /* Initialize all fields */
453 sck->m_stream = TRUE;
454 sck->m_server = TRUE;
455 sck->m_oriented = TRUE;
fb9010ed
DW
456
457 /* Create the socket */
458 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0);
459
3958ae62
SN
460 if (sck->m_fd == INVALID_SOCKET)
461 {
fb9010ed
DW
462 sck->m_error = GSOCK_IOERR;
463 return GSOCK_IOERR;
464 }
465
19193a2c 466 ioctl(sck->m_fd, FIONBIO, (char*)&arg, sizeof(arg));
3958ae62
SN
467 _GSocket_Enable_Events(sck);
468
469 /* Bind to the local address,
470 * retrieve the actual address bound,
471 * and listen up to 5 connections.
472 */
473 if ((bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) != 0) ||
474 (getsockname(sck->m_fd,
475 sck->m_local->m_addr,
476 (SOCKLEN_T *) &sck->m_local->m_len) != 0) ||
477 (listen(sck->m_fd, 5) != 0))
478 {
e32c4e60 479 GSocket_close(sck);
fb9010ed
DW
480 sck->m_error = GSOCK_IOERR;
481 return GSOCK_IOERR;
482 }
483
484 return GSOCK_NOERROR;
485}
486
487/* GSocket_WaitConnection:
3958ae62
SN
488 * Waits for an incoming client connection. Returns a pointer to
489 * a GSocket object, or NULL if there was an error, in which case
490 * the last error field will be updated for the calling GSocket.
491 *
492 * Error codes (set in the calling GSocket)
493 * GSOCK_INVSOCK - the socket is not valid or not a server.
494 * GSOCK_TIMEDOUT - timeout, no incoming connections.
495 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
496 * GSOCK_MEMERR - couldn't allocate memory.
e32c4e60 497 * GSOCK_IOERR - low-level error.
fb9010ed
DW
498 */
499GSocket *GSocket_WaitConnection(GSocket *socket)
500{
3958ae62
SN
501 struct sockaddr from;
502 SOCKLEN_T fromlen = sizeof(from);
fb9010ed 503 GSocket *connection;
3958ae62 504 GSocketError err;
fb9010ed
DW
505 int arg = 1;
506
507 assert(socket != NULL);
508
509 /* Reenable CONNECTION events */
510 _GSocket_Enable(socket, GSOCK_CONNECTION);
511
512 /* If the socket has already been created, we exit immediately */
3958ae62 513 if (socket->m_fd == INVALID_SOCKET || !socket->m_server)
fb9010ed
DW
514 {
515 socket->m_error = GSOCK_INVSOCK;
516 return NULL;
517 }
518
519 /* Create a GSocket object for the new connection */
520 connection = GSocket_new();
3958ae62 521
fb9010ed
DW
522 if (!connection)
523 {
3958ae62 524 socket->m_error = GSOCK_MEMERR;
fb9010ed
DW
525 return NULL;
526 }
527
3958ae62 528 /* Wait for a connection (with timeout) */
fb9010ed
DW
529 if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
530 {
531 GSocket_destroy(connection);
532 /* socket->m_error set by _GSocket_Input_Timeout */
533 return NULL;
534 }
535
3958ae62 536 connection->m_fd = accept(socket->m_fd, &from, (SOCKLEN_T *) &fromlen);
fb9010ed 537
3958ae62 538 if (connection->m_fd == INVALID_SOCKET)
fb9010ed
DW
539 {
540 if (errno == EWOULDBLOCK)
541 socket->m_error = GSOCK_WOULDBLOCK;
542 else
543 socket->m_error = GSOCK_IOERR;
544
545 GSocket_destroy(connection);
546 return NULL;
547 }
548
549 /* Initialize all fields */
3958ae62
SN
550 connection->m_server = FALSE;
551 connection->m_stream = TRUE;
552 connection->m_oriented = TRUE;
fb9010ed 553
3958ae62
SN
554 /* Setup the peer address field */
555 connection->m_peer = GAddress_new();
556 if (!connection->m_peer)
557 {
558 GSocket_destroy(connection);
559 socket->m_error = GSOCK_MEMERR;
560 return NULL;
fb9010ed 561 }
3958ae62
SN
562 err = _GAddress_translate_from(connection->m_peer, &from, fromlen);
563 if (err != GSOCK_NOERROR)
564 {
565 GAddress_destroy(connection->m_peer);
566 GSocket_destroy(connection);
567 socket->m_error = err;
568 return NULL;
fb9010ed
DW
569 }
570
19193a2c 571 ioctl(connection->m_fd, FIONBIO, (char*)&arg, sizeof(arg));
3958ae62 572 _GSocket_Enable_Events(connection);
fb9010ed 573
3958ae62 574 return connection;
fb9010ed
DW
575}
576
577/* Client specific parts */
578
579/* GSocket_Connect:
3958ae62
SN
580 * For stream (connection oriented) sockets, GSocket_Connect() tries
581 * to establish a client connection to a server using the peer address
582 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
583 * connection has been succesfully established, or one of the error
584 * codes listed below. Note that for nonblocking sockets, a return
585 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
586 * request can be completed later; you should use GSocket_Select()
587 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
588 * corresponding asynchronous events.
589 *
590 * For datagram (non connection oriented) sockets, GSocket_Connect()
591 * just sets the peer address established with GSocket_SetPeer() as
592 * default destination.
593 *
594 * Error codes:
595 * GSOCK_INVSOCK - the socket is in use or not valid.
596 * GSOCK_INVADDR - the peer address has not been established.
597 * GSOCK_TIMEDOUT - timeout, the connection failed.
598 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
599 * GSOCK_MEMERR - couldn't allocate memory.
e32c4e60 600 * GSOCK_IOERR - low-level error.
fb9010ed
DW
601 */
602GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
603{
3958ae62 604 int err, ret;
fb9010ed
DW
605 int arg = 1;
606
607 assert(sck != NULL);
608
609 /* Enable CONNECTION events (needed for nonblocking connections) */
610 _GSocket_Enable(sck, GSOCK_CONNECTION);
611
3958ae62 612 if (sck->m_fd != INVALID_SOCKET)
fb9010ed
DW
613 {
614 sck->m_error = GSOCK_INVSOCK;
615 return GSOCK_INVSOCK;
616 }
617
618 if (!sck->m_peer)
619 {
620 sck->m_error = GSOCK_INVADDR;
621 return GSOCK_INVADDR;
622 }
623
3958ae62 624 /* Streamed or dgram socket? */
fb9010ed 625 sck->m_stream = (stream == GSOCK_STREAMED);
3958ae62
SN
626 sck->m_oriented = TRUE;
627 sck->m_server = FALSE;
628 sck->m_establishing = FALSE;
fb9010ed
DW
629
630 /* Create the socket */
3958ae62
SN
631 sck->m_fd = socket(sck->m_peer->m_realfamily,
632 sck->m_stream? SOCK_STREAM : SOCK_DGRAM, 0);
fb9010ed 633
3958ae62
SN
634 if (sck->m_fd == INVALID_SOCKET)
635 {
fb9010ed
DW
636 sck->m_error = GSOCK_IOERR;
637 return GSOCK_IOERR;
638 }
639
19193a2c 640 ioctl(sck->m_fd, FIONBIO, (char*)&arg, sizeof(arg));
3958ae62 641 _GSocket_Enable_Events(sck);
fb9010ed 642
3958ae62 643 /* Connect it to the peer address, with a timeout (see below) */
fb9010ed
DW
644 ret = connect(sck->m_fd, sck->m_peer->m_addr, sck->m_peer->m_len);
645
646 if (ret == -1)
647 {
648 err = errno;
649
650 /* If connect failed with EINPROGRESS and the GSocket object
651 * is in blocking mode, we select() for the specified timeout
652 * checking for writability to see if the connection request
653 * completes.
654 */
655 if ((err == EINPROGRESS) && (!sck->m_non_blocking))
656 {
657 if (_GSocket_Output_Timeout(sck) == GSOCK_TIMEDOUT)
658 {
e32c4e60 659 GSocket_close(sck);
fb9010ed 660 /* sck->m_error is set in _GSocket_Output_Timeout */
fb9010ed
DW
661 return GSOCK_TIMEDOUT;
662 }
663 else
664 {
3958ae62
SN
665 int error;
666 SOCKLEN_T len = sizeof(error);
667
668 getsockopt(sck->m_fd, SOL_SOCKET, SO_ERROR, (void*) &error, &len);
669
670 if (!error)
671 return GSOCK_NOERROR;
fb9010ed
DW
672 }
673 }
674
675 /* If connect failed with EINPROGRESS and the GSocket object
676 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
677 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
678 * this way if the connection completes, a GSOCK_CONNECTION
679 * event will be generated, if enabled.
680 */
681 if ((err == EINPROGRESS) && (sck->m_non_blocking))
682 {
3958ae62 683 sck->m_establishing = TRUE;
fb9010ed 684 sck->m_error = GSOCK_WOULDBLOCK;
fb9010ed
DW
685 return GSOCK_WOULDBLOCK;
686 }
687
688 /* If connect failed with an error other than EINPROGRESS,
689 * then the call to GSocket_Connect has failed.
690 */
e32c4e60 691 GSocket_close(sck);
fb9010ed 692 sck->m_error = GSOCK_IOERR;
3958ae62
SN
693 return GSOCK_IOERR;
694 }
fb9010ed 695
3958ae62
SN
696 return GSOCK_NOERROR;
697}
698
699/* Datagram sockets */
700
701/* GSocket_SetNonOriented:
702 * Sets up this socket as a non-connection oriented (datagram) socket.
703 * Before using this function, the local address must have been set
704 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
705 * on success, or one of the following otherwise.
706 *
707 * Error codes:
708 * GSOCK_INVSOCK - the socket is in use.
709 * GSOCK_INVADDR - the local address has not been set.
710 * GSOCK_IOERR - low-level error.
711 */
712GSocketError GSocket_SetNonOriented(GSocket *sck)
713{
714 int arg = 1;
715
716 assert(sck != NULL);
717
718 if (sck->m_fd != INVALID_SOCKET)
719 {
720 sck->m_error = GSOCK_INVSOCK;
721 return GSOCK_INVSOCK;
722 }
723
724 if (!sck->m_local)
725 {
726 sck->m_error = GSOCK_INVADDR;
727 return GSOCK_INVADDR;
728 }
729
730 /* Initialize all fields */
731 sck->m_stream = FALSE;
732 sck->m_server = FALSE;
733 sck->m_oriented = FALSE;
734
735 /* Create the socket */
736 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
737
738 if (sck->m_fd == INVALID_SOCKET)
739 {
740 sck->m_error = GSOCK_IOERR;
741 return GSOCK_IOERR;
742 }
743
19193a2c 744 ioctl(sck->m_fd, FIONBIO, (char*)&arg, sizeof(arg));
3958ae62
SN
745 _GSocket_Enable_Events(sck);
746
747 /* Bind to the local address,
748 * and retrieve the actual address bound.
749 */
750 if ((bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) != 0) ||
751 (getsockname(sck->m_fd,
752 sck->m_local->m_addr,
753 (SOCKLEN_T *) &sck->m_local->m_len) != 0))
754 {
e32c4e60 755 GSocket_close(sck);
3958ae62 756 sck->m_error = GSOCK_IOERR;
fb9010ed
DW
757 return GSOCK_IOERR;
758 }
759
fb9010ed
DW
760 return GSOCK_NOERROR;
761}
762
763/* Generic IO */
764
765/* Like recv(), send(), ... */
766int GSocket_Read(GSocket *socket, char *buffer, int size)
767{
768 int ret;
769
770 assert(socket != NULL);
771
772 /* Reenable INPUT events */
773 _GSocket_Enable(socket, GSOCK_INPUT);
774
3958ae62 775 if (socket->m_fd == INVALID_SOCKET || socket->m_server)
fb9010ed
DW
776 {
777 socket->m_error = GSOCK_INVSOCK;
778 return -1;
779 }
780
3958ae62 781 /* If the socket is blocking, wait for data (with a timeout) */
fb9010ed
DW
782 if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
783 return -1;
784
3958ae62 785 /* Read the data */
fb9010ed
DW
786 if (socket->m_stream)
787 ret = _GSocket_Recv_Stream(socket, buffer, size);
788 else
789 ret = _GSocket_Recv_Dgram(socket, buffer, size);
e32c4e60 790
fb9010ed
DW
791 if (ret == -1)
792 {
793 if (errno == EWOULDBLOCK)
794 socket->m_error = GSOCK_WOULDBLOCK;
795 else
796 socket->m_error = GSOCK_IOERR;
797 }
e32c4e60 798
fb9010ed
DW
799 return ret;
800}
801
3958ae62 802int GSocket_Write(GSocket *socket, const char *buffer, int size)
e32c4e60 803{
fb9010ed
DW
804 int ret;
805
806 assert(socket != NULL);
e32c4e60 807
3958ae62 808 GSocket_Debug(( "GSocket_Write #1, size %d\n", size ));
fb9010ed 809
3958ae62 810 if (socket->m_fd == INVALID_SOCKET || socket->m_server)
fb9010ed
DW
811 {
812 socket->m_error = GSOCK_INVSOCK;
813 return -1;
814 }
815
3958ae62
SN
816 GSocket_Debug(( "GSocket_Write #2, size %d\n", size ));
817
818 /* If the socket is blocking, wait for writability (with a timeout) */
fb9010ed
DW
819 if (_GSocket_Output_Timeout(socket) == GSOCK_TIMEDOUT)
820 return -1;
821
3958ae62
SN
822 GSocket_Debug(( "GSocket_Write #3, size %d\n", size ));
823
824 /* Write the data */
fb9010ed
DW
825 if (socket->m_stream)
826 ret = _GSocket_Send_Stream(socket, buffer, size);
827 else
828 ret = _GSocket_Send_Dgram(socket, buffer, size);
e32c4e60 829
3958ae62 830 GSocket_Debug(( "GSocket_Write #4, size %d\n", size ));
fb9010ed
DW
831
832 if (ret == -1)
833 {
834 if (errno == EWOULDBLOCK)
3958ae62 835 {
fb9010ed 836 socket->m_error = GSOCK_WOULDBLOCK;
3958ae62
SN
837 GSocket_Debug(( "GSocket_Write error WOULDBLOCK\n" ));
838 }
fb9010ed 839 else
3958ae62 840 {
fb9010ed 841 socket->m_error = GSOCK_IOERR;
3958ae62
SN
842 GSocket_Debug(( "GSocket_Write error IOERR\n" ));
843 }
fb9010ed
DW
844
845 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
846 * in MSW). Once the first OUTPUT event is received, users can assume
847 * that the socket is writable until a read operation fails. Only then
848 * will further OUTPUT events be posted.
849 */
850 _GSocket_Enable(socket, GSOCK_OUTPUT);
3958ae62 851 return -1;
fb9010ed 852 }
e32c4e60 853
3958ae62 854 GSocket_Debug(( "GSocket_Write #5, size %d ret %d\n", size, ret ));
fb9010ed
DW
855
856 return ret;
857}
858
859/* GSocket_Select:
860 * Polls the socket to determine its status. This function will
861 * check for the events specified in the 'flags' parameter, and
862 * it will return a mask indicating which operations can be
863 * performed. This function won't block, regardless of the
3958ae62 864 * mode (blocking | nonblocking) of the socket.
fb9010ed
DW
865 */
866GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags)
867{
38bb138f
VS
868 if (!USE_GUI())
869 {
3958ae62 870
38bb138f
VS
871 GSocketEventFlags result = 0;
872 fd_set readfds;
873 fd_set writefds;
874 fd_set exceptfds;
875 struct timeval tv;
fb9010ed 876
38bb138f
VS
877 /* Do not use a static struct, Linux can garble it */
878 tv.tv_sec = 0;
879 tv.tv_usec = 0;
3958ae62 880
38bb138f 881 assert(socket != NULL);
e32c4e60 882
38bb138f
VS
883 FD_ZERO(&readfds);
884 FD_ZERO(&writefds);
885 FD_ZERO(&exceptfds);
886 FD_SET(socket->m_fd, &readfds);
887 FD_SET(socket->m_fd, &writefds);
888 FD_SET(socket->m_fd, &exceptfds);
e32c4e60 889
38bb138f
VS
890 /* Check 'sticky' CONNECTION flag first */
891 result |= (GSOCK_CONNECTION_FLAG & socket->m_detected);
3958ae62 892
38bb138f
VS
893 /* If we have already detected a LOST event, then don't try
894 * to do any further processing.
895 */
896 if ((socket->m_detected & GSOCK_LOST_FLAG) != 0)
897 {
898 socket->m_establishing = FALSE;
3958ae62 899
38bb138f
VS
900 return (GSOCK_LOST_FLAG & flags);
901 }
3958ae62 902
38bb138f
VS
903 /* Try select now */
904 if (select(socket->m_fd + 1, &readfds, &writefds, &exceptfds, &tv) <= 0)
3958ae62 905 {
38bb138f
VS
906 /* What to do here? */
907 return (result & flags);
3958ae62 908 }
38bb138f
VS
909
910 /* Check for readability */
911 if (FD_ISSET(socket->m_fd, &readfds))
3958ae62 912 {
38bb138f
VS
913 char c;
914
915 if (recv(socket->m_fd, &c, 1, MSG_PEEK) > 0)
3958ae62 916 {
38bb138f 917 result |= GSOCK_INPUT_FLAG;
3958ae62
SN
918 }
919 else
920 {
38bb138f
VS
921 if (socket->m_server && socket->m_stream)
922 {
923 result |= GSOCK_CONNECTION_FLAG;
924 socket->m_detected |= GSOCK_CONNECTION_FLAG;
925 }
926 else
927 {
928 socket->m_detected = GSOCK_LOST_FLAG;
929 socket->m_establishing = FALSE;
930
931 /* LOST event: Abort any further processing */
932 return (GSOCK_LOST_FLAG & flags);
933 }
3958ae62
SN
934 }
935 }
3958ae62 936
38bb138f
VS
937 /* Check for writability */
938 if (FD_ISSET(socket->m_fd, &writefds))
3958ae62 939 {
38bb138f
VS
940 if (socket->m_establishing && !socket->m_server)
941 {
942 int error;
943 SOCKLEN_T len = sizeof(error);
3958ae62 944
38bb138f 945 socket->m_establishing = FALSE;
3958ae62 946
38bb138f 947 getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, (void*)&error, &len);
3958ae62 948
38bb138f
VS
949 if (error)
950 {
951 socket->m_detected = GSOCK_LOST_FLAG;
e32c4e60 952
38bb138f
VS
953 /* LOST event: Abort any further processing */
954 return (GSOCK_LOST_FLAG & flags);
955 }
956 else
957 {
958 result |= GSOCK_CONNECTION_FLAG;
959 socket->m_detected |= GSOCK_CONNECTION_FLAG;
960 }
3958ae62
SN
961 }
962 else
963 {
38bb138f 964 result |= GSOCK_OUTPUT_FLAG;
3958ae62
SN
965 }
966 }
38bb138f
VS
967
968 /* Check for exceptions and errors (is this useful in Unices?) */
969 if (FD_ISSET(socket->m_fd, &exceptfds))
3958ae62 970 {
38bb138f
VS
971 socket->m_establishing = FALSE;
972 socket->m_detected = GSOCK_LOST_FLAG;
973
974 /* LOST event: Abort any further processing */
975 return (GSOCK_LOST_FLAG & flags);
3958ae62 976 }
3958ae62 977
38bb138f 978 return (result & flags);
e32c4e60 979
3958ae62 980 }
38bb138f
VS
981 else
982 {
3958ae62 983
38bb138f
VS
984 assert(socket != NULL);
985 return flags & socket->m_detected;
3958ae62 986
38bb138f 987 }
fb9010ed
DW
988}
989
990/* Flags */
991
992/* GSocket_SetNonBlocking:
3958ae62
SN
993 * Sets the socket to non-blocking mode. All IO calls will return
994 * immediately.
fb9010ed 995 */
27f37ae5 996void GSocket_SetNonBlocking(GSocket *socket, int non_block)
fb9010ed
DW
997{
998 assert(socket != NULL);
999
3958ae62
SN
1000 GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block) );
1001
fb9010ed
DW
1002 socket->m_non_blocking = non_block;
1003}
1004
1005/* GSocket_SetTimeout:
3958ae62
SN
1006 * Sets the timeout for blocking calls. Time is expressed in
1007 * milliseconds.
fb9010ed
DW
1008 */
1009void GSocket_SetTimeout(GSocket *socket, unsigned long millisec)
1010{
1011 assert(socket != NULL);
1012
1013 socket->m_timeout = millisec;
1014}
1015
1016/* GSocket_GetError:
3958ae62
SN
1017 * Returns the last error occured for this socket. Note that successful
1018 * operations do not clear this back to GSOCK_NOERROR, so use it only
1019 * after an error.
fb9010ed
DW
1020 */
1021GSocketError GSocket_GetError(GSocket *socket)
1022{
1023 assert(socket != NULL);
1024
1025 return socket->m_error;
1026}
1027
1028/* Callbacks */
1029
3958ae62
SN
1030/* GSOCK_INPUT:
1031 * There is data to be read in the input buffer. If, after a read
1032 * operation, there is still data available, the callback function will
1033 * be called again.
1034 * GSOCK_OUTPUT:
e32c4e60 1035 * The socket is available for writing. That is, the next write call
3958ae62
SN
1036 * won't block. This event is generated only once, when the connection is
1037 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
1038 * when the output buffer empties again. This means that the app should
1039 * assume that it can write since the first OUTPUT event, and no more
1040 * OUTPUT events will be generated unless an error occurs.
1041 * GSOCK_CONNECTION:
1042 * Connection succesfully established, for client sockets, or incoming
1043 * client connection, for server sockets. Wait for this event (also watch
1044 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
1045 * GSOCK_LOST:
1046 * The connection is lost (or a connection request failed); this could
1047 * be due to a failure, or due to the peer closing it gracefully.
fb9010ed
DW
1048 */
1049
1050/* GSocket_SetCallback:
1051 * Enables the callbacks specified by 'flags'. Note that 'flags'
1052 * may be a combination of flags OR'ed toghether, so the same
1053 * callback function can be made to accept different events.
1054 * The callback function must have the following prototype:
1055 *
1056 * void function(GSocket *socket, GSocketEvent event, char *cdata)
1057 */
1058void GSocket_SetCallback(GSocket *socket, GSocketEventFlags flags,
3958ae62 1059 GSocketCallback callback, char *cdata)
fb9010ed
DW
1060{
1061 int count;
1062
1063 assert(socket != NULL);
1064
1065 for (count = 0; count < GSOCK_MAX_EVENT; count++)
1066 {
1067 if ((flags & (1 << count)) != 0)
1068 {
1069 socket->m_cbacks[count] = callback;
1070 socket->m_data[count] = cdata;
1071 }
1072 }
1073}
1074
1075/* GSocket_UnsetCallback:
1076 * Disables all callbacks specified by 'flags', which may be a
1077 * combination of flags OR'ed toghether.
1078 */
1079void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags)
1080{
1081 int count;
1082
1083 assert(socket != NULL);
1084
1085 for (count = 0; count < GSOCK_MAX_EVENT; count++)
1086 {
1087 if ((flags & (1 << count)) != 0)
1088 {
1089 socket->m_cbacks[count] = NULL;
1090 socket->m_data[count] = NULL;
1091 }
1092 }
1093}
1094
3958ae62 1095
fb9010ed
DW
1096#define CALL_CALLBACK(socket, event) { \
1097 _GSocket_Disable(socket, event); \
e32c4e60 1098 if (socket->m_cbacks[event]) \
fb9010ed
DW
1099 socket->m_cbacks[event](socket, event, socket->m_data[event]); \
1100}
1101
1102
1103void _GSocket_Enable(GSocket *socket, GSocketEvent event)
1104{
1105 socket->m_detected &= ~(1 << event);
3958ae62 1106 _GSocket_Install_Callback(socket, event);
fb9010ed
DW
1107}
1108
1109void _GSocket_Disable(GSocket *socket, GSocketEvent event)
1110{
1111 socket->m_detected |= (1 << event);
3958ae62 1112 _GSocket_Uninstall_Callback(socket, event);
fb9010ed
DW
1113}
1114
1115/* _GSocket_Input_Timeout:
1116 * For blocking sockets, wait until data is available or
1117 * until timeout ellapses.
1118 */
1119GSocketError _GSocket_Input_Timeout(GSocket *socket)
1120{
1121 struct timeval tv;
1122 fd_set readfds;
3958ae62 1123 int ret;
fb9010ed 1124
3958ae62 1125 /* Linux select() will overwrite the struct on return */
fb9010ed
DW
1126 tv.tv_sec = (socket->m_timeout / 1000);
1127 tv.tv_usec = (socket->m_timeout % 1000) * 1000;
1128
1129 if (!socket->m_non_blocking)
1130 {
1131 FD_ZERO(&readfds);
1132 FD_SET(socket->m_fd, &readfds);
3958ae62
SN
1133 ret = select(socket->m_fd + 1, &readfds, NULL, NULL, &tv);
1134 if (ret == 0)
fb9010ed 1135 {
3958ae62
SN
1136 GSocket_Debug(( "GSocket_Input_Timeout, select returned 0\n" ));
1137 socket->m_error = GSOCK_TIMEDOUT;
1138 return GSOCK_TIMEDOUT;
1139 }
1140 if (ret == -1)
1141 {
1142 GSocket_Debug(( "GSocket_Input_Timeout, select returned -1\n" ));
1143 if (errno == EBADF) GSocket_Debug(( "Invalid file descriptor\n" ));
1144 if (errno == EINTR) GSocket_Debug(( "A non blocked signal was caught\n" ));
1145 if (errno == EINVAL) GSocket_Debug(( "The highest number descriptor is negative\n" ));
1146 if (errno == ENOMEM) GSocket_Debug(( "Not enough memory\n" ));
fb9010ed
DW
1147 socket->m_error = GSOCK_TIMEDOUT;
1148 return GSOCK_TIMEDOUT;
1149 }
1150 }
1151 return GSOCK_NOERROR;
1152}
1153
1154/* _GSocket_Output_Timeout:
1155 * For blocking sockets, wait until data can be sent without
1156 * blocking or until timeout ellapses.
1157 */
1158GSocketError _GSocket_Output_Timeout(GSocket *socket)
1159{
1160 struct timeval tv;
1161 fd_set writefds;
3958ae62 1162 int ret;
fb9010ed 1163
3958ae62 1164 /* Linux select() will overwrite the struct on return */
fb9010ed
DW
1165 tv.tv_sec = (socket->m_timeout / 1000);
1166 tv.tv_usec = (socket->m_timeout % 1000) * 1000;
1167
3958ae62
SN
1168 GSocket_Debug( ("m_non_blocking has: %d\n", (int)socket->m_non_blocking) );
1169
fb9010ed
DW
1170 if (!socket->m_non_blocking)
1171 {
1172 FD_ZERO(&writefds);
1173 FD_SET(socket->m_fd, &writefds);
3958ae62
SN
1174 ret = select(socket->m_fd + 1, NULL, &writefds, NULL, &tv);
1175 if (ret == 0)
fb9010ed 1176 {
3958ae62 1177 GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" ));
fb9010ed
DW
1178 socket->m_error = GSOCK_TIMEDOUT;
1179 return GSOCK_TIMEDOUT;
1180 }
3958ae62
SN
1181 if (ret == -1)
1182 {
1183 GSocket_Debug(( "GSocket_Output_Timeout, select returned -1\n" ));
1184 if (errno == EBADF) GSocket_Debug(( "Invalid file descriptor\n" ));
1185 if (errno == EINTR) GSocket_Debug(( "A non blocked signal was caught\n" ));
1186 if (errno == EINVAL) GSocket_Debug(( "The highest number descriptor is negative\n" ));
1187 if (errno == ENOMEM) GSocket_Debug(( "Not enough memory\n" ));
1188 socket->m_error = GSOCK_TIMEDOUT;
1189 return GSOCK_TIMEDOUT;
1190 }
1191 if ( ! FD_ISSET(socket->m_fd, &writefds) )
1192 GSocket_Debug(( "GSocket_Output_Timeout is buggy!\n" ));
1193 else
1194 GSocket_Debug(( "GSocket_Output_Timeout seems correct\n" ));
1195 }
1196 else
1197 {
1198 GSocket_Debug(( "GSocket_Output_Timeout, didn't try select!\n" ));
fb9010ed 1199 }
3958ae62 1200
fb9010ed
DW
1201 return GSOCK_NOERROR;
1202}
1203
1204int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
1205{
3958ae62 1206 return recv(socket->m_fd, buffer, size, 0);
fb9010ed
DW
1207}
1208
1209int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
1210{
1211 struct sockaddr from;
3958ae62 1212 SOCKLEN_T fromlen = sizeof(from);
fb9010ed
DW
1213 int ret;
1214 GSocketError err;
1215
1216 fromlen = sizeof(from);
1217
3958ae62 1218 ret = recvfrom(socket->m_fd, buffer, size, 0, &from, (SOCKLEN_T *) &fromlen);
fb9010ed
DW
1219
1220 if (ret == -1)
1221 return -1;
1222
1223 /* Translate a system address into a GSocket address */
1224 if (!socket->m_peer)
1225 {
1226 socket->m_peer = GAddress_new();
1227 if (!socket->m_peer)
1228 {
1229 socket->m_error = GSOCK_MEMERR;
1230 return -1;
1231 }
1232 }
1233 err = _GAddress_translate_from(socket->m_peer, &from, fromlen);
1234 if (err != GSOCK_NOERROR)
1235 {
1236 GAddress_destroy(socket->m_peer);
1237 socket->m_peer = NULL;
1238 socket->m_error = err;
1239 return -1;
1240 }
1241
1242 return ret;
1243}
1244
1245int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
1246{
1247 int ret;
fb9010ed 1248
29d83fc1 1249#ifdef __EMX__
3958ae62
SN
1250 MASK_SIGNAL();
1251 ret = send(socket->m_fd, buffer, size, 0);
1252 UNMASK_SIGNAL();
29d83fc1 1253#else
19193a2c 1254 ret = send(socket->m_fd, (char *)buffer, size, 0);
29d83fc1 1255#endif
fb9010ed
DW
1256 return ret;
1257}
1258
1259int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
1260{
1261 struct sockaddr *addr;
1262 int len, ret;
1263 GSocketError err;
1264
3958ae62
SN
1265 if (!socket->m_peer)
1266 {
fb9010ed
DW
1267 socket->m_error = GSOCK_INVADDR;
1268 return -1;
1269 }
1270
1271 err = _GAddress_translate_to(socket->m_peer, &addr, &len);
3958ae62
SN
1272 if (err != GSOCK_NOERROR)
1273 {
fb9010ed
DW
1274 socket->m_error = err;
1275 return -1;
1276 }
1277
29d83fc1 1278#ifdef __EMX__
3958ae62
SN
1279 MASK_SIGNAL();
1280 ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
1281 UNMASK_SIGNAL();
29d83fc1 1282#else
19193a2c 1283 ret = sendto(socket->m_fd, (char *)buffer, size, 0, addr, len);
29d83fc1 1284#endif
fb9010ed
DW
1285
1286 /* Frees memory allocated from _GAddress_translate_to */
1287 free(addr);
1288
1289 return ret;
1290}
1291
1292void _GSocket_Detected_Read(GSocket *socket)
1293{
1294 char c;
fb9010ed 1295
e32c4e60
SN
1296 /* If we have already detected a LOST event, then don't try
1297 * to do any further processing.
1298 */
1299 if ((socket->m_detected & GSOCK_LOST_FLAG) != 0)
1300 {
1301 socket->m_establishing = FALSE;
1302
1303 CALL_CALLBACK(socket, GSOCK_LOST);
1304 GSocket_Shutdown(socket);
1305 return;
1306 }
1307
3958ae62 1308 if (recv(socket->m_fd, &c, 1, MSG_PEEK) > 0)
fb9010ed 1309 {
3958ae62
SN
1310 CALL_CALLBACK(socket, GSOCK_INPUT);
1311 }
1312 else
1313 {
1314 if (socket->m_server && socket->m_stream)
fb9010ed
DW
1315 {
1316 CALL_CALLBACK(socket, GSOCK_CONNECTION);
fb9010ed
DW
1317 }
1318 else
1319 {
1320 CALL_CALLBACK(socket, GSOCK_LOST);
e32c4e60 1321 GSocket_Shutdown(socket);
fb9010ed
DW
1322 }
1323 }
1324}
1325
1326void _GSocket_Detected_Write(GSocket *socket)
1327{
e32c4e60
SN
1328 /* If we have already detected a LOST event, then don't try
1329 * to do any further processing.
1330 */
1331 if ((socket->m_detected & GSOCK_LOST_FLAG) != 0)
1332 {
1333 socket->m_establishing = FALSE;
1334
1335 CALL_CALLBACK(socket, GSOCK_LOST);
1336 GSocket_Shutdown(socket);
1337 return;
1338 }
1339
fb9010ed
DW
1340 if (socket->m_establishing && !socket->m_server)
1341 {
3958ae62
SN
1342 int error;
1343 SOCKLEN_T len = sizeof(error);
fb9010ed 1344
3958ae62 1345 socket->m_establishing = FALSE;
fb9010ed 1346
3958ae62 1347 getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, (void*)&error, &len);
fb9010ed
DW
1348
1349 if (error)
1350 {
1351 CALL_CALLBACK(socket, GSOCK_LOST);
e32c4e60 1352 GSocket_Shutdown(socket);
fb9010ed
DW
1353 }
1354 else
1355 {
1356 CALL_CALLBACK(socket, GSOCK_CONNECTION);
1357 /* We have to fire this event by hand because CONNECTION (for clients)
1358 * and OUTPUT are internally the same and we just disabled CONNECTION
1359 * events with the above macro.
1360 */
1361 CALL_CALLBACK(socket, GSOCK_OUTPUT);
1362 }
1363 }
1364 else
1365 {
1366 CALL_CALLBACK(socket, GSOCK_OUTPUT);
1367 }
1368}
1369
1370/*
1371 * -------------------------------------------------------------------------
1372 * GAddress
1373 * -------------------------------------------------------------------------
1374 */
1375
3958ae62
SN
1376/* CHECK_ADDRESS verifies that the current address family is either
1377 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1378 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1379 * an appropiate error code.
1380 *
1381 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
fb9010ed 1382 */
3958ae62
SN
1383#define CHECK_ADDRESS(address, family) \
1384{ \
1385 if (address->m_family == GSOCK_NOFAMILY) \
1386 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1387 return address->m_error; \
1388 if (address->m_family != GSOCK_##family) \
1389 { \
1390 address->m_error = GSOCK_INVADDR; \
1391 return GSOCK_INVADDR; \
1392 } \
1393}
1394
1395#define CHECK_ADDRESS_RETVAL(address, family, retval) \
1396{ \
1397 if (address->m_family == GSOCK_NOFAMILY) \
1398 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1399 return retval; \
1400 if (address->m_family != GSOCK_##family) \
1401 { \
1402 address->m_error = GSOCK_INVADDR; \
1403 return retval; \
1404 } \
fb9010ed
DW
1405}
1406
3958ae62
SN
1407
1408GAddress *GAddress_new(void)
fb9010ed
DW
1409{
1410 GAddress *address;
1411
3958ae62 1412 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
fb9010ed
DW
1413 return NULL;
1414
1415 address->m_family = GSOCK_NOFAMILY;
1416 address->m_addr = NULL;
1417 address->m_len = 0;
1418
1419 return address;
1420}
1421
1422GAddress *GAddress_copy(GAddress *address)
1423{
1424 GAddress *addr2;
1425
1426 assert(address != NULL);
1427
3958ae62 1428 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
fb9010ed
DW
1429 return NULL;
1430
1431 memcpy(addr2, address, sizeof(GAddress));
1432
e32c4e60 1433 if (address->m_addr && address->m_len > 0)
3958ae62 1434 {
fb9010ed 1435 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
3958ae62
SN
1436 if (addr2->m_addr == NULL)
1437 {
fb9010ed
DW
1438 free(addr2);
1439 return NULL;
1440 }
1441 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
1442 }
1443
1444 return addr2;
1445}
1446
1447void GAddress_destroy(GAddress *address)
1448{
1449 assert(address != NULL);
1450
3958ae62
SN
1451 if (address->m_addr)
1452 free(address->m_addr);
1453
1454/* free(address); */
fb9010ed
DW
1455}
1456
1457void GAddress_SetFamily(GAddress *address, GAddressType type)
1458{
1459 assert(address != NULL);
1460
1461 address->m_family = type;
1462}
1463
1464GAddressType GAddress_GetFamily(GAddress *address)
1465{
1466 assert(address != NULL);
1467
1468 return address->m_family;
1469}
1470
3958ae62
SN
1471GSocketError _GAddress_translate_from(GAddress *address,
1472 struct sockaddr *addr, int len)
1473{
fb9010ed 1474 address->m_realfamily = addr->sa_family;
3958ae62
SN
1475 switch (addr->sa_family)
1476 {
1477 case AF_INET:
1478 address->m_family = GSOCK_INET;
1479 break;
1480 case AF_UNIX:
1481 address->m_family = GSOCK_UNIX;
1482 break;
fb9010ed 1483#ifdef AF_INET6
3958ae62
SN
1484 case AF_INET6:
1485 address->m_family = GSOCK_INET6;
1486 break;
fb9010ed 1487#endif
3958ae62 1488 default:
fb9010ed 1489 {
3958ae62
SN
1490 address->m_error = GSOCK_INVOP;
1491 return GSOCK_INVOP;
fb9010ed
DW
1492 }
1493 }
1494
1495 if (address->m_addr)
1496 free(address->m_addr);
1497
1498 address->m_len = len;
1499 address->m_addr = (struct sockaddr *)malloc(len);
3958ae62
SN
1500
1501 if (address->m_addr == NULL)
1502 {
fb9010ed
DW
1503 address->m_error = GSOCK_MEMERR;
1504 return GSOCK_MEMERR;
1505 }
1506 memcpy(address->m_addr, addr, len);
1507
1508 return GSOCK_NOERROR;
1509}
1510
1511GSocketError _GAddress_translate_to(GAddress *address,
1512 struct sockaddr **addr, int *len)
1513{
3958ae62
SN
1514 if (!address->m_addr)
1515 {
fb9010ed
DW
1516 address->m_error = GSOCK_INVADDR;
1517 return GSOCK_INVADDR;
1518 }
1519
1520 *len = address->m_len;
1521 *addr = (struct sockaddr *)malloc(address->m_len);
3958ae62
SN
1522 if (*addr == NULL)
1523 {
fb9010ed
DW
1524 address->m_error = GSOCK_MEMERR;
1525 return GSOCK_MEMERR;
1526 }
1527
1528 memcpy(*addr, address->m_addr, address->m_len);
1529 return GSOCK_NOERROR;
1530}
1531
1532/*
1533 * -------------------------------------------------------------------------
1534 * Internet address family
1535 * -------------------------------------------------------------------------
1536 */
1537
1538GSocketError _GAddress_Init_INET(GAddress *address)
1539{
3958ae62
SN
1540 address->m_len = sizeof(struct sockaddr_in);
1541 address->m_addr = (struct sockaddr *) malloc(address->m_len);
1542 if (address->m_addr == NULL)
1543 {
fb9010ed
DW
1544 address->m_error = GSOCK_MEMERR;
1545 return GSOCK_MEMERR;
1546 }
1547
fb9010ed
DW
1548 address->m_family = GSOCK_INET;
1549 address->m_realfamily = PF_INET;
1550 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
3958ae62 1551 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
fb9010ed
DW
1552
1553 return GSOCK_NOERROR;
1554}
1555
1556GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
1557{
1558 struct hostent *he;
1559 struct in_addr *addr;
1560
1561 assert(address != NULL);
1562
3958ae62 1563 CHECK_ADDRESS(address, INET);
fb9010ed
DW
1564
1565 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1566
1567 /* If it is a numeric host name, convert it now */
1568#if defined(HAVE_INET_ATON)
3958ae62
SN
1569 if (inet_aton(hostname, addr) == 0)
1570 {
fb9010ed 1571#elif defined(HAVE_INET_ADDR)
29d83fc1 1572 addr->s_addr = inet_addr(hostname);
d75262db 1573 if ( addr->s_addr == -1 )
3958ae62
SN
1574 {
1575#else
1576 /* Use gethostbyname by default */
987da0d4
DW
1577 int val = 1; //VA doesn't like constants in conditional expressions at all
1578 if (val)
3958ae62 1579 {
fb9010ed
DW
1580#endif
1581 struct in_addr *array_addr;
1582
1583 /* It is a real name, we solve it */
3958ae62
SN
1584 if ((he = gethostbyname(hostname)) == NULL)
1585 {
1586 /* Reset to invalid address */
1587 addr->s_addr = INADDR_NONE;
fb9010ed
DW
1588 address->m_error = GSOCK_NOHOST;
1589 return GSOCK_NOHOST;
1590 }
1591 array_addr = (struct in_addr *) *(he->h_addr_list);
1592 addr->s_addr = array_addr[0].s_addr;
fb9010ed 1593 }
fb9010ed
DW
1594 return GSOCK_NOERROR;
1595}
1596
b662c135
SN
1597GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
1598{
1599 return GAddress_INET_SetHostAddress(address, INADDR_ANY);
1600}
1601
fb9010ed
DW
1602GSocketError GAddress_INET_SetHostAddress(GAddress *address,
1603 unsigned long hostaddr)
1604{
1605 struct in_addr *addr;
1606
1607 assert(address != NULL);
1608
3958ae62 1609 CHECK_ADDRESS(address, INET);
fb9010ed
DW
1610
1611 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1612 addr->s_addr = hostaddr;
1613
1614 return GSOCK_NOERROR;
1615}
1616
1617GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1618 const char *protocol)
1619{
1620 struct servent *se;
1621 struct sockaddr_in *addr;
1622
1623 assert(address != NULL);
3958ae62 1624 CHECK_ADDRESS(address, INET);
fb9010ed 1625
3958ae62
SN
1626 if (!port)
1627 {
fb9010ed
DW
1628 address->m_error = GSOCK_INVPORT;
1629 return GSOCK_INVPORT;
1630 }
e32c4e60 1631
3958ae62
SN
1632 se = getservbyname(port, protocol);
1633 if (!se)
1634 {
e32c4e60
SN
1635 /* the cast to int suppresses compiler warnings about subscript having the
1636 type char */
3958ae62
SN
1637 if (isdigit((int)port[0]))
1638 {
fb9010ed
DW
1639 int port_int;
1640
1641 port_int = atoi(port);
1642 addr = (struct sockaddr_in *)address->m_addr;
3958ae62 1643 addr->sin_port = htons(port_int);
fb9010ed
DW
1644 return GSOCK_NOERROR;
1645 }
1646
1647 address->m_error = GSOCK_INVPORT;
1648 return GSOCK_INVPORT;
1649 }
1650
1651 addr = (struct sockaddr_in *)address->m_addr;
1652 addr->sin_port = se->s_port;
1653
1654 return GSOCK_NOERROR;
1655}
1656
1657GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1658{
1659 struct sockaddr_in *addr;
1660
1661 assert(address != NULL);
3958ae62 1662 CHECK_ADDRESS(address, INET);
e32c4e60 1663
fb9010ed 1664 addr = (struct sockaddr_in *)address->m_addr;
3958ae62 1665 addr->sin_port = htons(port);
fb9010ed
DW
1666
1667 return GSOCK_NOERROR;
1668}
1669
1670GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1671{
1672 struct hostent *he;
1673 char *addr_buf;
1674 struct sockaddr_in *addr;
1675
e32c4e60 1676 assert(address != NULL);
3958ae62 1677 CHECK_ADDRESS(address, INET);
fb9010ed
DW
1678
1679 addr = (struct sockaddr_in *)address->m_addr;
1680 addr_buf = (char *)&(addr->sin_addr);
1681
3958ae62
SN
1682 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1683 if (he == NULL)
1684 {
fb9010ed
DW
1685 address->m_error = GSOCK_NOHOST;
1686 return GSOCK_NOHOST;
1687 }
1688
1689 strncpy(hostname, he->h_name, sbuf);
1690
1691 return GSOCK_NOERROR;
1692}
1693
1694unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1695{
1696 struct sockaddr_in *addr;
1697
e32c4e60
SN
1698 assert(address != NULL);
1699 CHECK_ADDRESS_RETVAL(address, INET, 0);
fb9010ed
DW
1700
1701 addr = (struct sockaddr_in *)address->m_addr;
1702
1703 return addr->sin_addr.s_addr;
1704}
1705
1706unsigned short GAddress_INET_GetPort(GAddress *address)
1707{
1708 struct sockaddr_in *addr;
1709
e32c4e60
SN
1710 assert(address != NULL);
1711 CHECK_ADDRESS_RETVAL(address, INET, 0);
fb9010ed
DW
1712
1713 addr = (struct sockaddr_in *)address->m_addr;
3958ae62 1714 return ntohs(addr->sin_port);
fb9010ed
DW
1715}
1716
b662c135
SN
1717/*
1718 * -------------------------------------------------------------------------
1719 * Unix address family
1720 * -------------------------------------------------------------------------
1721 */
1722
3958ae62 1723#ifdef __EMX__
b662c135
SN
1724GSocketError _GAddress_Init_UNIX(GAddress *address)
1725{
3958ae62
SN
1726 address->m_len = sizeof(struct sockaddr_un);
1727 address->m_addr = (struct sockaddr *)malloc(address->m_len);
1728 if (address->m_addr == NULL)
1729 {
1730 address->m_error = GSOCK_MEMERR;
1731 return GSOCK_MEMERR;
1732 }
1733
1734 address->m_family = GSOCK_UNIX;
1735 address->m_realfamily = PF_UNIX;
1736 ((struct sockaddr_un *)address->m_addr)->sun_family = AF_UNIX;
1737 ((struct sockaddr_un *)address->m_addr)->sun_path[0] = 0;
1738
1739 return GSOCK_NOERROR;
b662c135
SN
1740}
1741
e32c4e60
SN
1742#define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
1743
b662c135
SN
1744GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
1745{
3958ae62
SN
1746 struct sockaddr_un *addr;
1747
e32c4e60 1748 assert(address != NULL);
3958ae62 1749
e32c4e60 1750 CHECK_ADDRESS(address, UNIX);
3958ae62
SN
1751
1752 addr = ((struct sockaddr_un *)address->m_addr);
e32c4e60
SN
1753 strncpy(addr->sun_path, path, UNIX_SOCK_PATHLEN);
1754 addr->sun_path[UNIX_SOCK_PATHLEN - 1] = '\0';
3958ae62
SN
1755
1756 return GSOCK_NOERROR;
b662c135
SN
1757}
1758
1759GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
1760{
3958ae62
SN
1761 struct sockaddr_un *addr;
1762
1763 assert(address != NULL);
1764 CHECK_ADDRESS(address, UNIX);
1765
1766 addr = (struct sockaddr_un *)address->m_addr;
1767
1768 strncpy(path, addr->sun_path, sbuf);
b662c135 1769
3958ae62
SN
1770 return GSOCK_NOERROR;
1771}
fb9010ed 1772#endif
3958ae62
SN
1773 /* __EMX__ */
1774#endif
1775 /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */
1776