1 /* ------------------------------------------------------------------------- 
   2  * Project: GSocket (Generic Socket) for WX 
   4  * Authors: Guilhem Lavaux, 
   5  *          Guillermo Rodriguez Garcia <guille@iies.es> (maintainer) 
   6  * Purpose: GSocket main Unix-style file 
   7  * Licence: The wxWindows licence 
   9  * ------------------------------------------------------------------------- 
  13  * PLEASE don't put C++ comments here - this is a C source file. 
  16 #ifndef __GSOCKET_STANDALONE__ 
  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.                                   */ 
  27 #if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) 
  29 #define BSD_SELECT /* use Berkley Sockets select */ 
  32 #include <sys/types.h> 
  36 #include <netinet/in.h> 
  37 #include <arpa/inet.h> 
  42 #define HAVE_INET_ADDR 
  50 #include <netinet/in.h> 
  56 #if defined(__VISAGECPP__) && __IBMCPP__ < 400 
  58 #include <machine/endian.h> 
  64 #define EBADF   SOCEBADF 
  68 #include <sys/socket.h> 
  69 #include <sys/ioctl.h> 
  70 #include <sys/select.h> 
  73 #define soclose(a) close(a) 
  75 #define select(a,b,c,d,e) bsdselect(a,b,c,d,e) 
  76 int _System 
bsdselect(int, 
  81 int _System 
soclose(int); 
  86 #if (defined(__VISAGECPP__) && __IBMCPP__ < 400) || defined(__EMX__) 
 102 #         define SOCKLEN_T socklen_t 
 105 #      define SOCKLEN_T int 
 111  * MSW defines this, Unices don't. 
 113 #ifndef INVALID_SOCKET 
 114 #define INVALID_SOCKET -1 
 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. 
 122 #define INADDR_NONE INADDR_BROADCAST 
 125 #define MASK_SIGNAL()                       \ 
 127   void (*old_handler)(int);                 \ 
 129   old_handler = signal(SIGPIPE, SIG_IGN); 
 131 #define UNMASK_SIGNAL()                     \ 
 132   signal(SIGPIPE, old_handler);             \ 
 136 #ifndef __GSOCKET_STANDALONE__ 
 137 #  include "wx/unix/gsockunx.h" 
 138 #  include "wx/gsocket.h" 
 140 #  include "gsockunx.h" 
 141 #  include "gsocket.h" 
 142 #endif /* __GSOCKET_STANDALONE__ */ 
 144 /* debugging helpers */ 
 145 #ifdef __GSOCKET_DEBUG__ 
 146 #  define GSocket_Debug(args) printf args 
 148 #  define GSocket_Debug(args) 
 149 #endif /* __GSOCKET_DEBUG__ */ 
 151 /* Table of GUI-related functions. We must call them indirectly because 
 152  * of wxBase and GUI separation: */ 
 154 static struct GSocketGUIFunctionsTable 
*gs_gui_functions
; 
 156 #define USE_GUI() (gs_gui_functions != NULL) 
 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) 
 176 static struct GSocketBaseFunctionsTable gs_base_functions 
= 
 178     _GSocket_Detected_Read
, 
 179     _GSocket_Detected_Write
 
 182 /* Global initialisers */ 
 184 void GSocket_SetGUIFunctions(struct GSocketGUIFunctionsTable 
*guifunc
) 
 186   gs_gui_functions 
= guifunc
; 
 189 int GSocket_Init(void) 
 191   if (gs_gui_functions
) 
 193       if ( !gs_gui_functions
->GUI_Init() ) 
 199 void GSocket_Cleanup(void) 
 201   if (gs_gui_functions
) 
 203       gs_gui_functions
->GUI_Cleanup(); 
 207 /* Constructors / Destructors for GSocket */ 
 209 GSocket 
*GSocket_new(void) 
 214   socket 
= (GSocket 
*)malloc(sizeof(GSocket
)); 
 219   socket
->m_fd                  
= INVALID_SOCKET
; 
 220   for (i
=0;i
<GSOCK_MAX_EVENT
;i
++) 
 222     socket
->m_cbacks
[i
]         = NULL
; 
 224   socket
->m_detected            
= 0; 
 225   socket
->m_local               
= NULL
; 
 226   socket
->m_peer                
= NULL
; 
 227   socket
->m_error               
= GSOCK_NOERROR
; 
 228   socket
->m_server              
= FALSE
; 
 229   socket
->m_stream              
= TRUE
; 
 230   socket
->m_gui_dependent       
= NULL
; 
 231   socket
->m_non_blocking        
= FALSE
; 
 232   socket
->m_timeout             
= 10*60*1000; 
 233                                 /* 10 minutes * 60 sec * 1000 millisec */ 
 234   socket
->m_establishing        
= FALSE
; 
 236   socket
->m_functions           
= &gs_base_functions
; 
 238   /* Per-socket GUI-specific initialization */ 
 239   success 
= _GSocket_GUI_Init_Socket(socket
); 
 249 void GSocket_close(GSocket 
*socket
) 
 251     _GSocket_Disable_Events(socket
); 
 252     soclose(socket
->m_fd
); 
 253     socket
->m_fd 
= INVALID_SOCKET
; 
 256 void GSocket_destroy(GSocket 
*socket
) 
 258   assert(socket 
!= NULL
); 
 260   /* Check that the socket is really shutdowned */ 
 261   if (socket
->m_fd 
!= INVALID_SOCKET
) 
 262     GSocket_Shutdown(socket
); 
 264   /* Per-socket GUI-specific cleanup */ 
 265   _GSocket_GUI_Destroy_Socket(socket
); 
 267   /* Destroy private addresses */ 
 269     GAddress_destroy(socket
->m_local
); 
 272     GAddress_destroy(socket
->m_peer
); 
 274   /* Destroy the socket itself */ 
 279  *  Disallow further read/write operations on this socket, close 
 280  *  the fd and disable all callbacks. 
 282 void GSocket_Shutdown(GSocket 
*socket
) 
 286   assert(socket 
!= NULL
); 
 288   /* If socket has been created, shutdown it */ 
 289   if (socket
->m_fd 
!= INVALID_SOCKET
) 
 291     shutdown(socket
->m_fd
, 2); 
 292     GSocket_close(socket
); 
 295   /* Disable GUI callbacks */ 
 296   for (evt 
= 0; evt 
< GSOCK_MAX_EVENT
; evt
++) 
 297     socket
->m_cbacks
[evt
] = NULL
; 
 299   socket
->m_detected 
= GSOCK_LOST_FLAG
; 
 300   _GSocket_Disable_Events(socket
); 
 303 /* Address handling */ 
 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. 
 316  *    GSOCK_INVSOCK - the socket is not valid. 
 317  *    GSOCK_INVADDR - the address is not valid. 
 319 GSocketError 
GSocket_SetLocal(GSocket 
*socket
, GAddress 
*address
) 
 321   assert(socket 
!= NULL
); 
 323   /* the socket must be initialized, or it must be a server */ 
 324   if ((socket
->m_fd 
!= INVALID_SOCKET 
&& !socket
->m_server
)) 
 326     socket
->m_error 
= GSOCK_INVSOCK
; 
 327     return GSOCK_INVSOCK
; 
 331   if (address 
== NULL 
|| address
->m_family 
== GSOCK_NOFAMILY
) 
 333     socket
->m_error 
= GSOCK_INVADDR
; 
 334     return GSOCK_INVADDR
; 
 338     GAddress_destroy(socket
->m_local
); 
 340   socket
->m_local 
= GAddress_copy(address
); 
 342   return GSOCK_NOERROR
; 
 345 GSocketError 
GSocket_SetPeer(GSocket 
*socket
, GAddress 
*address
) 
 347   assert(socket 
!= NULL
); 
 350   if (address 
== NULL 
|| address
->m_family 
== GSOCK_NOFAMILY
) 
 352     socket
->m_error 
= GSOCK_INVADDR
; 
 353     return GSOCK_INVADDR
; 
 357     GAddress_destroy(socket
->m_peer
); 
 359   socket
->m_peer 
= GAddress_copy(address
); 
 361   return GSOCK_NOERROR
; 
 364 GAddress 
*GSocket_GetLocal(GSocket 
*socket
) 
 367   struct sockaddr addr
; 
 368   SOCKLEN_T size 
= sizeof(addr
); 
 371   assert(socket 
!= NULL
); 
 373   /* try to get it from the m_local var first */ 
 375     return GAddress_copy(socket
->m_local
); 
 377   /* else, if the socket is initialized, try getsockname */ 
 378   if (socket
->m_fd 
== INVALID_SOCKET
) 
 380     socket
->m_error 
= GSOCK_INVSOCK
; 
 384   if (getsockname(socket
->m_fd
, &addr
, (SOCKLEN_T 
*) &size
) < 0) 
 386     socket
->m_error 
= GSOCK_IOERR
; 
 390   /* got a valid address from getsockname, create a GAddress object */ 
 391   address 
= GAddress_new(); 
 394     socket
->m_error 
= GSOCK_MEMERR
; 
 398   err 
= _GAddress_translate_from(address
, &addr
, size
); 
 399   if (err 
!= GSOCK_NOERROR
) 
 401     GAddress_destroy(address
); 
 402     socket
->m_error 
= err
; 
 409 GAddress 
*GSocket_GetPeer(GSocket 
*socket
) 
 411   assert(socket 
!= NULL
); 
 413   /* try to get it from the m_peer var */ 
 415     return GAddress_copy(socket
->m_peer
); 
 420 /* Server specific parts */ 
 422 /* GSocket_SetServer: 
 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: 
 428  *    GSOCK_INVSOCK - the socket is in use. 
 429  *    GSOCK_INVADDR - the local address has not been set. 
 430  *    GSOCK_IOERR   - low-level error.  
 432 GSocketError 
GSocket_SetServer(GSocket 
*sck
) 
 438   /* must not be in use */ 
 439   if (sck
->m_fd 
!= INVALID_SOCKET
) 
 441     sck
->m_error 
= GSOCK_INVSOCK
; 
 442     return GSOCK_INVSOCK
; 
 445   /* the local addr must have been set */ 
 448     sck
->m_error 
= GSOCK_INVADDR
; 
 449     return GSOCK_INVADDR
; 
 452   /* Initialize all fields */ 
 453   sck
->m_stream   
= TRUE
; 
 454   sck
->m_server   
= TRUE
; 
 455   sck
->m_oriented 
= TRUE
; 
 457   /* Create the socket */ 
 458   sck
->m_fd 
= socket(sck
->m_local
->m_realfamily
, SOCK_STREAM
, 0); 
 460   if (sck
->m_fd 
== INVALID_SOCKET
) 
 462     sck
->m_error 
= GSOCK_IOERR
; 
 466   ioctl(sck
->m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
)); 
 467   _GSocket_Enable_Events(sck
); 
 469   /* Bind to the local address, 
 470    * retrieve the actual address bound, 
 471    * and listen up to 5 connections. 
 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)) 
 480     sck
->m_error 
= GSOCK_IOERR
; 
 484   return GSOCK_NOERROR
; 
 487 /* GSocket_WaitConnection: 
 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. 
 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. 
 497  *    GSOCK_IOERR      - low-level error.  
 499 GSocket 
*GSocket_WaitConnection(GSocket 
*socket
) 
 501   struct sockaddr from
; 
 502   SOCKLEN_T fromlen 
= sizeof(from
); 
 507   assert(socket 
!= NULL
); 
 509   /* Reenable CONNECTION events */ 
 510   _GSocket_Enable(socket
, GSOCK_CONNECTION
); 
 512   /* If the socket has already been created, we exit immediately */ 
 513   if (socket
->m_fd 
== INVALID_SOCKET 
|| !socket
->m_server
) 
 515     socket
->m_error 
= GSOCK_INVSOCK
; 
 519   /* Create a GSocket object for the new connection */ 
 520   connection 
= GSocket_new(); 
 524     socket
->m_error 
= GSOCK_MEMERR
; 
 528   /* Wait for a connection (with timeout) */ 
 529   if (_GSocket_Input_Timeout(socket
) == GSOCK_TIMEDOUT
) 
 531     GSocket_destroy(connection
); 
 532     /* socket->m_error set by _GSocket_Input_Timeout */ 
 536   connection
->m_fd 
= accept(socket
->m_fd
, &from
, (SOCKLEN_T 
*) &fromlen
); 
 538   if (connection
->m_fd 
== INVALID_SOCKET
) 
 540     if (errno 
== EWOULDBLOCK
) 
 541       socket
->m_error 
= GSOCK_WOULDBLOCK
; 
 543       socket
->m_error 
= GSOCK_IOERR
; 
 545     GSocket_destroy(connection
); 
 549   /* Initialize all fields */ 
 550   connection
->m_server   
= FALSE
; 
 551   connection
->m_stream   
= TRUE
; 
 552   connection
->m_oriented 
= TRUE
; 
 554   /* Setup the peer address field */ 
 555   connection
->m_peer 
= GAddress_new(); 
 556   if (!connection
->m_peer
) 
 558     GSocket_destroy(connection
); 
 559     socket
->m_error 
= GSOCK_MEMERR
; 
 562   err 
= _GAddress_translate_from(connection
->m_peer
, &from
, fromlen
); 
 563   if (err 
!= GSOCK_NOERROR
) 
 565     GAddress_destroy(connection
->m_peer
); 
 566     GSocket_destroy(connection
); 
 567     socket
->m_error 
= err
; 
 571   ioctl(connection
->m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
)); 
 572   _GSocket_Enable_Events(connection
); 
 577 /* Client specific parts */ 
 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. 
 590  *  For datagram (non connection oriented) sockets, GSocket_Connect() 
 591  *  just sets the peer address established with GSocket_SetPeer() as 
 592  *  default destination. 
 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. 
 600  *    GSOCK_IOERR      - low-level error.  
 602 GSocketError 
GSocket_Connect(GSocket 
*sck
, GSocketStream stream
) 
 609   /* Enable CONNECTION events (needed for nonblocking connections) */ 
 610   _GSocket_Enable(sck
, GSOCK_CONNECTION
); 
 612   if (sck
->m_fd 
!= INVALID_SOCKET
) 
 614     sck
->m_error 
= GSOCK_INVSOCK
; 
 615     return GSOCK_INVSOCK
; 
 620     sck
->m_error 
= GSOCK_INVADDR
; 
 621     return GSOCK_INVADDR
; 
 624   /* Streamed or dgram socket? */ 
 625   sck
->m_stream   
= (stream 
== GSOCK_STREAMED
); 
 626   sck
->m_oriented 
= TRUE
; 
 627   sck
->m_server   
= FALSE
; 
 628   sck
->m_establishing 
= FALSE
; 
 630   /* Create the socket */ 
 631   sck
->m_fd 
= socket(sck
->m_peer
->m_realfamily
, 
 632                      sck
->m_stream
? SOCK_STREAM 
: SOCK_DGRAM
, 0); 
 634   if (sck
->m_fd 
== INVALID_SOCKET
) 
 636     sck
->m_error 
= GSOCK_IOERR
; 
 640   ioctl(sck
->m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
)); 
 641   _GSocket_Enable_Events(sck
); 
 643   /* Connect it to the peer address, with a timeout (see below) */ 
 644   ret 
= connect(sck
->m_fd
, sck
->m_peer
->m_addr
, sck
->m_peer
->m_len
); 
 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 
 655     if ((err 
== EINPROGRESS
) && (!sck
->m_non_blocking
)) 
 657       if (_GSocket_Output_Timeout(sck
) == GSOCK_TIMEDOUT
) 
 660         /* sck->m_error is set in _GSocket_Output_Timeout */ 
 661         return GSOCK_TIMEDOUT
; 
 666         SOCKLEN_T len 
= sizeof(error
); 
 668         getsockopt(sck
->m_fd
, SOL_SOCKET
, SO_ERROR
, (void*) &error
, &len
); 
 671           return GSOCK_NOERROR
; 
 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. 
 681     if ((err 
== EINPROGRESS
) && (sck
->m_non_blocking
)) 
 683       sck
->m_establishing 
= TRUE
; 
 684       sck
->m_error 
= GSOCK_WOULDBLOCK
; 
 685       return GSOCK_WOULDBLOCK
; 
 688     /* If connect failed with an error other than EINPROGRESS, 
 689      * then the call to GSocket_Connect has failed. 
 692     sck
->m_error 
= GSOCK_IOERR
; 
 696   return GSOCK_NOERROR
; 
 699 /* Datagram sockets */ 
 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. 
 708  *    GSOCK_INVSOCK - the socket is in use. 
 709  *    GSOCK_INVADDR - the local address has not been set. 
 710  *    GSOCK_IOERR   - low-level error. 
 712 GSocketError 
GSocket_SetNonOriented(GSocket 
*sck
) 
 718   if (sck
->m_fd 
!= INVALID_SOCKET
) 
 720     sck
->m_error 
= GSOCK_INVSOCK
; 
 721     return GSOCK_INVSOCK
; 
 726     sck
->m_error 
= GSOCK_INVADDR
; 
 727     return GSOCK_INVADDR
; 
 730   /* Initialize all fields */ 
 731   sck
->m_stream   
= FALSE
; 
 732   sck
->m_server   
= FALSE
; 
 733   sck
->m_oriented 
= FALSE
; 
 735   /* Create the socket */ 
 736   sck
->m_fd 
= socket(sck
->m_local
->m_realfamily
, SOCK_DGRAM
, 0); 
 738   if (sck
->m_fd 
== INVALID_SOCKET
) 
 740     sck
->m_error 
= GSOCK_IOERR
; 
 744   ioctl(sck
->m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
)); 
 745   _GSocket_Enable_Events(sck
); 
 747   /* Bind to the local address, 
 748    * and retrieve the actual address bound. 
 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)) 
 756     sck
->m_error 
= GSOCK_IOERR
; 
 760   return GSOCK_NOERROR
; 
 765 /* Like recv(), send(), ... */ 
 766 int GSocket_Read(GSocket 
*socket
, char *buffer
, int size
) 
 770   assert(socket 
!= NULL
); 
 772   /* Reenable INPUT events */ 
 773   _GSocket_Enable(socket
, GSOCK_INPUT
); 
 775   if (socket
->m_fd 
== INVALID_SOCKET 
|| socket
->m_server
) 
 777     socket
->m_error 
= GSOCK_INVSOCK
; 
 781   /* If the socket is blocking, wait for data (with a timeout) */ 
 782   if (_GSocket_Input_Timeout(socket
) == GSOCK_TIMEDOUT
) 
 786   if (socket
->m_stream
) 
 787     ret 
= _GSocket_Recv_Stream(socket
, buffer
, size
); 
 789     ret 
= _GSocket_Recv_Dgram(socket
, buffer
, size
); 
 793     if (errno 
== EWOULDBLOCK
) 
 794       socket
->m_error 
= GSOCK_WOULDBLOCK
; 
 796       socket
->m_error 
= GSOCK_IOERR
; 
 802 int GSocket_Write(GSocket 
*socket
, const char *buffer
, int size
) 
 806   assert(socket 
!= NULL
); 
 808   GSocket_Debug(( "GSocket_Write #1, size %d\n", size 
)); 
 810   if (socket
->m_fd 
== INVALID_SOCKET 
|| socket
->m_server
) 
 812     socket
->m_error 
= GSOCK_INVSOCK
; 
 816   GSocket_Debug(( "GSocket_Write #2, size %d\n", size 
)); 
 818   /* If the socket is blocking, wait for writability (with a timeout) */ 
 819   if (_GSocket_Output_Timeout(socket
) == GSOCK_TIMEDOUT
) 
 822   GSocket_Debug(( "GSocket_Write #3, size %d\n", size 
)); 
 825   if (socket
->m_stream
) 
 826     ret 
= _GSocket_Send_Stream(socket
, buffer
, size
); 
 828     ret 
= _GSocket_Send_Dgram(socket
, buffer
, size
); 
 830   GSocket_Debug(( "GSocket_Write #4, size %d\n", size 
)); 
 834     if (errno 
== EWOULDBLOCK
) 
 836       socket
->m_error 
= GSOCK_WOULDBLOCK
; 
 837       GSocket_Debug(( "GSocket_Write error WOULDBLOCK\n" )); 
 841       socket
->m_error 
= GSOCK_IOERR
; 
 842       GSocket_Debug(( "GSocket_Write error IOERR\n" )); 
 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. 
 850     _GSocket_Enable(socket
, GSOCK_OUTPUT
); 
 854   GSocket_Debug(( "GSocket_Write #5, size %d ret %d\n", size
, ret 
)); 
 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 
 864  *  mode (blocking | nonblocking) of the socket. 
 866 GSocketEventFlags 
GSocket_Select(GSocket 
*socket
, GSocketEventFlags flags
) 
 871     GSocketEventFlags result 
= 0; 
 877     /* Do not use a static struct, Linux can garble it */ 
 881     assert(socket 
!= NULL
); 
 886     FD_SET(socket
->m_fd
, &readfds
); 
 887     FD_SET(socket
->m_fd
, &writefds
); 
 888     FD_SET(socket
->m_fd
, &exceptfds
); 
 890     /* Check 'sticky' CONNECTION flag first */ 
 891     result 
|= (GSOCK_CONNECTION_FLAG 
& socket
->m_detected
); 
 893     /* If we have already detected a LOST event, then don't try 
 894      * to do any further processing. 
 896     if ((socket
->m_detected 
& GSOCK_LOST_FLAG
) != 0) 
 898       socket
->m_establishing 
= FALSE
; 
 900       return (GSOCK_LOST_FLAG 
& flags
); 
 904     if (select(socket
->m_fd 
+ 1, &readfds
, &writefds
, &exceptfds
, &tv
) <= 0) 
 906       /* What to do here? */ 
 907       return (result 
& flags
); 
 910     /* Check for readability */ 
 911     if (FD_ISSET(socket
->m_fd
, &readfds
)) 
 915       if (recv(socket
->m_fd
, &c
, 1, MSG_PEEK
) > 0) 
 917         result 
|= GSOCK_INPUT_FLAG
; 
 921         if (socket
->m_server 
&& socket
->m_stream
) 
 923           result 
|= GSOCK_CONNECTION_FLAG
; 
 924           socket
->m_detected 
|= GSOCK_CONNECTION_FLAG
; 
 928           socket
->m_detected 
= GSOCK_LOST_FLAG
; 
 929           socket
->m_establishing 
= FALSE
; 
 931           /* LOST event: Abort any further processing */ 
 932           return (GSOCK_LOST_FLAG 
& flags
); 
 937     /* Check for writability */ 
 938     if (FD_ISSET(socket
->m_fd
, &writefds
)) 
 940       if (socket
->m_establishing 
&& !socket
->m_server
) 
 943         SOCKLEN_T len 
= sizeof(error
); 
 945         socket
->m_establishing 
= FALSE
; 
 947         getsockopt(socket
->m_fd
, SOL_SOCKET
, SO_ERROR
, (void*)&error
, &len
); 
 951           socket
->m_detected 
= GSOCK_LOST_FLAG
; 
 953           /* LOST event: Abort any further processing */ 
 954           return (GSOCK_LOST_FLAG 
& flags
); 
 958           result 
|= GSOCK_CONNECTION_FLAG
; 
 959           socket
->m_detected 
|= GSOCK_CONNECTION_FLAG
; 
 964         result 
|= GSOCK_OUTPUT_FLAG
; 
 968     /* Check for exceptions and errors (is this useful in Unices?) */ 
 969     if (FD_ISSET(socket
->m_fd
, &exceptfds
)) 
 971       socket
->m_establishing 
= FALSE
; 
 972       socket
->m_detected 
= GSOCK_LOST_FLAG
; 
 974       /* LOST event: Abort any further processing */ 
 975       return (GSOCK_LOST_FLAG 
& flags
); 
 978     return (result 
& flags
); 
 984     assert(socket 
!= NULL
); 
 985     return flags 
& socket
->m_detected
; 
 992 /* GSocket_SetNonBlocking: 
 993  *  Sets the socket to non-blocking mode. All IO calls will return 
 996 void GSocket_SetNonBlocking(GSocket 
*socket
, int non_block
) 
 998   assert(socket 
!= NULL
); 
1000   GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block
) ); 
1002   socket
->m_non_blocking 
= non_block
; 
1005 /* GSocket_SetTimeout: 
1006  *  Sets the timeout for blocking calls. Time is expressed in 
1009 void GSocket_SetTimeout(GSocket 
*socket
, unsigned long millisec
) 
1011   assert(socket 
!= NULL
); 
1013   socket
->m_timeout 
= millisec
; 
1016 /* GSocket_GetError: 
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 
1021 GSocketError 
GSocket_GetError(GSocket 
*socket
) 
1023   assert(socket 
!= NULL
); 
1025   return socket
->m_error
; 
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 
1035  *   The socket is available for writing. That is, the next write call  
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. 
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. 
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. 
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: 
1056  *  void function(GSocket *socket, GSocketEvent event, char *cdata) 
1058 void GSocket_SetCallback(GSocket 
*socket
, GSocketEventFlags flags
, 
1059                          GSocketCallback callback
, char *cdata
) 
1063   assert(socket 
!= NULL
); 
1065   for (count 
= 0; count 
< GSOCK_MAX_EVENT
; count
++) 
1067     if ((flags 
& (1 << count
)) != 0) 
1069       socket
->m_cbacks
[count
] = callback
; 
1070       socket
->m_data
[count
] = cdata
; 
1075 /* GSocket_UnsetCallback: 
1076  *  Disables all callbacks specified by 'flags', which may be a 
1077  *  combination of flags OR'ed toghether. 
1079 void GSocket_UnsetCallback(GSocket 
*socket
, GSocketEventFlags flags
) 
1083   assert(socket 
!= NULL
); 
1085   for (count 
= 0; count 
< GSOCK_MAX_EVENT
; count
++) 
1087     if ((flags 
& (1 << count
)) != 0) 
1089       socket
->m_cbacks
[count
] = NULL
; 
1090       socket
->m_data
[count
] = NULL
; 
1096 #define CALL_CALLBACK(socket, event) {                                  \ 
1097   _GSocket_Disable(socket, event);                                      \ 
1098   if (socket->m_cbacks[event])                                          \ 
1099     socket->m_cbacks[event](socket, event, socket->m_data[event]);      \ 
1103 void _GSocket_Enable(GSocket 
*socket
, GSocketEvent event
) 
1105   socket
->m_detected 
&= ~(1 << event
); 
1106   _GSocket_Install_Callback(socket
, event
); 
1109 void _GSocket_Disable(GSocket 
*socket
, GSocketEvent event
) 
1111   socket
->m_detected 
|= (1 << event
); 
1112   _GSocket_Uninstall_Callback(socket
, event
); 
1115 /* _GSocket_Input_Timeout: 
1116  *  For blocking sockets, wait until data is available or 
1117  *  until timeout ellapses. 
1119 GSocketError 
_GSocket_Input_Timeout(GSocket 
*socket
) 
1125   /* Linux select() will overwrite the struct on return */ 
1126   tv
.tv_sec  
= (socket
->m_timeout 
/ 1000); 
1127   tv
.tv_usec 
= (socket
->m_timeout 
% 1000) * 1000; 
1129   if (!socket
->m_non_blocking
) 
1132     FD_SET(socket
->m_fd
, &readfds
); 
1133     ret 
= select(socket
->m_fd 
+ 1, &readfds
, NULL
, NULL
, &tv
); 
1136       GSocket_Debug(( "GSocket_Input_Timeout, select returned 0\n" )); 
1137       socket
->m_error 
= GSOCK_TIMEDOUT
; 
1138       return GSOCK_TIMEDOUT
; 
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" )); 
1147       socket
->m_error 
= GSOCK_TIMEDOUT
; 
1148       return GSOCK_TIMEDOUT
; 
1151   return GSOCK_NOERROR
; 
1154 /* _GSocket_Output_Timeout: 
1155  *  For blocking sockets, wait until data can be sent without 
1156  *  blocking or until timeout ellapses. 
1158 GSocketError 
_GSocket_Output_Timeout(GSocket 
*socket
) 
1164   /* Linux select() will overwrite the struct on return */ 
1165   tv
.tv_sec  
= (socket
->m_timeout 
/ 1000); 
1166   tv
.tv_usec 
= (socket
->m_timeout 
% 1000) * 1000; 
1168   GSocket_Debug( ("m_non_blocking has: %d\n", (int)socket
->m_non_blocking
) ); 
1170   if (!socket
->m_non_blocking
) 
1173     FD_SET(socket
->m_fd
, &writefds
); 
1174     ret 
= select(socket
->m_fd 
+ 1, NULL
, &writefds
, NULL
, &tv
); 
1177       GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" )); 
1178       socket
->m_error 
= GSOCK_TIMEDOUT
; 
1179       return GSOCK_TIMEDOUT
; 
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
; 
1191     if ( ! FD_ISSET(socket
->m_fd
, &writefds
) ) 
1192       GSocket_Debug(( "GSocket_Output_Timeout is buggy!\n" )); 
1194       GSocket_Debug(( "GSocket_Output_Timeout seems correct\n" )); 
1198     GSocket_Debug(( "GSocket_Output_Timeout, didn't try select!\n" )); 
1201   return GSOCK_NOERROR
; 
1204 int _GSocket_Recv_Stream(GSocket 
*socket
, char *buffer
, int size
) 
1206   return recv(socket
->m_fd
, buffer
, size
, 0); 
1209 int _GSocket_Recv_Dgram(GSocket 
*socket
, char *buffer
, int size
) 
1211   struct sockaddr from
; 
1212   SOCKLEN_T fromlen 
= sizeof(from
); 
1216   fromlen 
= sizeof(from
); 
1218   ret 
= recvfrom(socket
->m_fd
, buffer
, size
, 0, &from
, (SOCKLEN_T 
*) &fromlen
); 
1223   /* Translate a system address into a GSocket address */ 
1224   if (!socket
->m_peer
) 
1226     socket
->m_peer 
= GAddress_new(); 
1227     if (!socket
->m_peer
) 
1229       socket
->m_error 
= GSOCK_MEMERR
; 
1233   err 
= _GAddress_translate_from(socket
->m_peer
, &from
, fromlen
); 
1234   if (err 
!= GSOCK_NOERROR
) 
1236     GAddress_destroy(socket
->m_peer
); 
1237     socket
->m_peer  
= NULL
; 
1238     socket
->m_error 
= err
; 
1245 int _GSocket_Send_Stream(GSocket 
*socket
, const char *buffer
, int size
) 
1251   ret 
= send(socket
->m_fd
, buffer
, size
, 0); 
1254   ret 
= send(socket
->m_fd
, (char *)buffer
, size
, 0); 
1259 int _GSocket_Send_Dgram(GSocket 
*socket
, const char *buffer
, int size
) 
1261   struct sockaddr 
*addr
; 
1265   if (!socket
->m_peer
) 
1267     socket
->m_error 
= GSOCK_INVADDR
; 
1271   err 
= _GAddress_translate_to(socket
->m_peer
, &addr
, &len
); 
1272   if (err 
!= GSOCK_NOERROR
) 
1274     socket
->m_error 
= err
; 
1280   ret 
= sendto(socket
->m_fd
, buffer
, size
, 0, addr
, len
); 
1283   ret 
= sendto(socket
->m_fd
, (char *)buffer
, size
, 0, addr
, len
); 
1286   /* Frees memory allocated from _GAddress_translate_to */ 
1292 void _GSocket_Detected_Read(GSocket 
*socket
) 
1296   /* If we have already detected a LOST event, then don't try 
1297    * to do any further processing. 
1299   if ((socket
->m_detected 
& GSOCK_LOST_FLAG
) != 0) 
1301     socket
->m_establishing 
= FALSE
; 
1303     CALL_CALLBACK(socket
, GSOCK_LOST
); 
1304     GSocket_Shutdown(socket
); 
1308   if (recv(socket
->m_fd
, &c
, 1, MSG_PEEK
) > 0) 
1310     CALL_CALLBACK(socket
, GSOCK_INPUT
); 
1314     if (socket
->m_server 
&& socket
->m_stream
) 
1316       CALL_CALLBACK(socket
, GSOCK_CONNECTION
); 
1320       CALL_CALLBACK(socket
, GSOCK_LOST
); 
1321       GSocket_Shutdown(socket
); 
1326 void _GSocket_Detected_Write(GSocket 
*socket
) 
1328   /* If we have already detected a LOST event, then don't try 
1329    * to do any further processing. 
1331   if ((socket
->m_detected 
& GSOCK_LOST_FLAG
) != 0) 
1333     socket
->m_establishing 
= FALSE
; 
1335     CALL_CALLBACK(socket
, GSOCK_LOST
); 
1336     GSocket_Shutdown(socket
); 
1340   if (socket
->m_establishing 
&& !socket
->m_server
) 
1343     SOCKLEN_T len 
= sizeof(error
); 
1345     socket
->m_establishing 
= FALSE
; 
1347     getsockopt(socket
->m_fd
, SOL_SOCKET
, SO_ERROR
, (void*)&error
, &len
); 
1351       CALL_CALLBACK(socket
, GSOCK_LOST
); 
1352       GSocket_Shutdown(socket
); 
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. 
1361       CALL_CALLBACK(socket
, GSOCK_OUTPUT
); 
1366     CALL_CALLBACK(socket
, GSOCK_OUTPUT
); 
1371  * ------------------------------------------------------------------------- 
1373  * ------------------------------------------------------------------------- 
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. 
1381  * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error. 
1383 #define CHECK_ADDRESS(address, family)                              \ 
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)                          \ 
1390     address->m_error = GSOCK_INVADDR;                               \ 
1391     return GSOCK_INVADDR;                                           \ 
1395 #define CHECK_ADDRESS_RETVAL(address, family, retval)               \ 
1397   if (address->m_family == GSOCK_NOFAMILY)                          \ 
1398     if (_GAddress_Init_##family(address) != GSOCK_NOERROR)          \ 
1400   if (address->m_family != GSOCK_##family)                          \ 
1402     address->m_error = GSOCK_INVADDR;                               \ 
1408 GAddress 
*GAddress_new(void) 
1412   if ((address 
= (GAddress 
*) malloc(sizeof(GAddress
))) == NULL
) 
1415   address
->m_family  
= GSOCK_NOFAMILY
; 
1416   address
->m_addr    
= NULL
; 
1422 GAddress 
*GAddress_copy(GAddress 
*address
) 
1426   assert(address 
!= NULL
); 
1428   if ((addr2 
= (GAddress 
*) malloc(sizeof(GAddress
))) == NULL
) 
1431   memcpy(addr2
, address
, sizeof(GAddress
)); 
1433   if (address
->m_addr 
&& address
->m_len 
> 0) 
1435     addr2
->m_addr 
= (struct sockaddr 
*)malloc(addr2
->m_len
); 
1436     if (addr2
->m_addr 
== NULL
) 
1441     memcpy(addr2
->m_addr
, address
->m_addr
, addr2
->m_len
); 
1447 void GAddress_destroy(GAddress 
*address
) 
1449   assert(address 
!= NULL
); 
1451   if (address
->m_addr
) 
1452     free(address
->m_addr
); 
1454 /*    free(address); */ 
1457 void GAddress_SetFamily(GAddress 
*address
, GAddressType type
) 
1459   assert(address 
!= NULL
); 
1461   address
->m_family 
= type
; 
1464 GAddressType 
GAddress_GetFamily(GAddress 
*address
) 
1466   assert(address 
!= NULL
); 
1468   return address
->m_family
; 
1471 GSocketError 
_GAddress_translate_from(GAddress 
*address
, 
1472                                       struct sockaddr 
*addr
, int len
) 
1474   address
->m_realfamily 
= addr
->sa_family
; 
1475   switch (addr
->sa_family
) 
1478       address
->m_family 
= GSOCK_INET
; 
1481       address
->m_family 
= GSOCK_UNIX
; 
1485       address
->m_family 
= GSOCK_INET6
; 
1490       address
->m_error 
= GSOCK_INVOP
; 
1495   if (address
->m_addr
) 
1496     free(address
->m_addr
); 
1498   address
->m_len  
= len
; 
1499   address
->m_addr 
= (struct sockaddr 
*)malloc(len
); 
1501   if (address
->m_addr 
== NULL
) 
1503     address
->m_error 
= GSOCK_MEMERR
; 
1504     return GSOCK_MEMERR
; 
1506   memcpy(address
->m_addr
, addr
, len
); 
1508   return GSOCK_NOERROR
; 
1511 GSocketError 
_GAddress_translate_to(GAddress 
*address
, 
1512                                     struct sockaddr 
**addr
, int *len
) 
1514   if (!address
->m_addr
) 
1516     address
->m_error 
= GSOCK_INVADDR
; 
1517     return GSOCK_INVADDR
; 
1520   *len 
= address
->m_len
; 
1521   *addr 
= (struct sockaddr 
*)malloc(address
->m_len
); 
1524     address
->m_error 
= GSOCK_MEMERR
; 
1525     return GSOCK_MEMERR
; 
1528   memcpy(*addr
, address
->m_addr
, address
->m_len
); 
1529   return GSOCK_NOERROR
; 
1533  * ------------------------------------------------------------------------- 
1534  * Internet address family 
1535  * ------------------------------------------------------------------------- 
1538 GSocketError 
_GAddress_Init_INET(GAddress 
*address
) 
1540   address
->m_len  
= sizeof(struct sockaddr_in
); 
1541   address
->m_addr 
= (struct sockaddr 
*) malloc(address
->m_len
); 
1542   if (address
->m_addr 
== NULL
) 
1544     address
->m_error 
= GSOCK_MEMERR
; 
1545     return GSOCK_MEMERR
; 
1548   address
->m_family 
= GSOCK_INET
; 
1549   address
->m_realfamily 
= PF_INET
; 
1550   ((struct sockaddr_in 
*)address
->m_addr
)->sin_family 
= AF_INET
; 
1551   ((struct sockaddr_in 
*)address
->m_addr
)->sin_addr
.s_addr 
= INADDR_ANY
; 
1553   return GSOCK_NOERROR
; 
1556 GSocketError 
GAddress_INET_SetHostName(GAddress 
*address
, const char *hostname
) 
1559   struct in_addr 
*addr
; 
1561   assert(address 
!= NULL
); 
1563   CHECK_ADDRESS(address
, INET
); 
1565   addr 
= &(((struct sockaddr_in 
*)address
->m_addr
)->sin_addr
); 
1567   /* If it is a numeric host name, convert it now */ 
1568 #if defined(HAVE_INET_ATON) 
1569   if (inet_aton(hostname
, addr
) == 0) 
1571 #elif defined(HAVE_INET_ADDR) 
1572   addr
->s_addr 
= inet_addr(hostname
); 
1573   if ( addr
->s_addr 
== -1 ) 
1576   /* Use gethostbyname by default */ 
1577   int val 
= 1;  //VA doesn't like constants in conditional expressions at all 
1581     struct in_addr 
*array_addr
; 
1583     /* It is a real name, we solve it */ 
1584     if ((he 
= gethostbyname(hostname
)) == NULL
) 
1586       /* Reset to invalid address */ 
1587       addr
->s_addr 
= INADDR_NONE
; 
1588       address
->m_error 
= GSOCK_NOHOST
; 
1589       return GSOCK_NOHOST
; 
1591     array_addr 
= (struct in_addr 
*) *(he
->h_addr_list
); 
1592     addr
->s_addr 
= array_addr
[0].s_addr
; 
1594   return GSOCK_NOERROR
; 
1597 GSocketError 
GAddress_INET_SetAnyAddress(GAddress 
*address
) 
1599   return GAddress_INET_SetHostAddress(address
, INADDR_ANY
); 
1602 GSocketError 
GAddress_INET_SetHostAddress(GAddress 
*address
, 
1603                                           unsigned long hostaddr
) 
1605   struct in_addr 
*addr
; 
1607   assert(address 
!= NULL
); 
1609   CHECK_ADDRESS(address
, INET
); 
1611   addr 
= &(((struct sockaddr_in 
*)address
->m_addr
)->sin_addr
); 
1612   addr
->s_addr 
= hostaddr
; 
1614   return GSOCK_NOERROR
; 
1617 GSocketError 
GAddress_INET_SetPortName(GAddress 
*address
, const char *port
, 
1618                                        const char *protocol
) 
1621   struct sockaddr_in 
*addr
; 
1623   assert(address 
!= NULL
); 
1624   CHECK_ADDRESS(address
, INET
); 
1628     address
->m_error 
= GSOCK_INVPORT
; 
1629     return GSOCK_INVPORT
; 
1632   se 
= getservbyname(port
, protocol
); 
1635     /* the cast to int suppresses compiler warnings about subscript having the 
1637     if (isdigit((int)port
[0])) 
1641       port_int 
= atoi(port
); 
1642       addr 
= (struct sockaddr_in 
*)address
->m_addr
; 
1643       addr
->sin_port 
= htons(port_int
); 
1644       return GSOCK_NOERROR
; 
1647     address
->m_error 
= GSOCK_INVPORT
; 
1648     return GSOCK_INVPORT
; 
1651   addr 
= (struct sockaddr_in 
*)address
->m_addr
; 
1652   addr
->sin_port 
= se
->s_port
; 
1654   return GSOCK_NOERROR
; 
1657 GSocketError 
GAddress_INET_SetPort(GAddress 
*address
, unsigned short port
) 
1659   struct sockaddr_in 
*addr
; 
1661   assert(address 
!= NULL
); 
1662   CHECK_ADDRESS(address
, INET
); 
1664   addr 
= (struct sockaddr_in 
*)address
->m_addr
; 
1665   addr
->sin_port 
= htons(port
); 
1667   return GSOCK_NOERROR
; 
1670 GSocketError 
GAddress_INET_GetHostName(GAddress 
*address
, char *hostname
, size_t sbuf
) 
1674   struct sockaddr_in 
*addr
; 
1676   assert(address 
!= NULL
);  
1677   CHECK_ADDRESS(address
, INET
); 
1679   addr 
= (struct sockaddr_in 
*)address
->m_addr
; 
1680   addr_buf 
= (char *)&(addr
->sin_addr
); 
1682   he 
= gethostbyaddr(addr_buf
, sizeof(addr
->sin_addr
), AF_INET
); 
1685     address
->m_error 
= GSOCK_NOHOST
; 
1686     return GSOCK_NOHOST
; 
1689   strncpy(hostname
, he
->h_name
, sbuf
); 
1691   return GSOCK_NOERROR
; 
1694 unsigned long GAddress_INET_GetHostAddress(GAddress 
*address
) 
1696   struct sockaddr_in 
*addr
; 
1698   assert(address 
!= NULL
);  
1699   CHECK_ADDRESS_RETVAL(address
, INET
, 0);  
1701   addr 
= (struct sockaddr_in 
*)address
->m_addr
; 
1703   return addr
->sin_addr
.s_addr
; 
1706 unsigned short GAddress_INET_GetPort(GAddress 
*address
) 
1708   struct sockaddr_in 
*addr
; 
1710   assert(address 
!= NULL
);  
1711   CHECK_ADDRESS_RETVAL(address
, INET
, 0);  
1713   addr 
= (struct sockaddr_in 
*)address
->m_addr
; 
1714   return ntohs(addr
->sin_port
); 
1718  * ------------------------------------------------------------------------- 
1719  * Unix address family 
1720  * ------------------------------------------------------------------------- 
1724 GSocketError 
_GAddress_Init_UNIX(GAddress 
*address
) 
1726   address
->m_len  
= sizeof(struct sockaddr_un
); 
1727   address
->m_addr 
= (struct sockaddr 
*)malloc(address
->m_len
); 
1728   if (address
->m_addr 
== NULL
) 
1730     address
->m_error 
= GSOCK_MEMERR
; 
1731     return GSOCK_MEMERR
; 
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; 
1739   return GSOCK_NOERROR
; 
1742 #define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0])) 
1744 GSocketError 
GAddress_UNIX_SetPath(GAddress 
*address
, const char *path
) 
1746   struct sockaddr_un 
*addr
; 
1748   assert(address 
!= NULL
);  
1750   CHECK_ADDRESS(address
, UNIX
);  
1752   addr 
= ((struct sockaddr_un 
*)address
->m_addr
); 
1753   strncpy(addr
->sun_path
, path
, UNIX_SOCK_PATHLEN
); 
1754   addr
->sun_path
[UNIX_SOCK_PATHLEN 
- 1] = '\0'; 
1756   return GSOCK_NOERROR
; 
1759 GSocketError 
GAddress_UNIX_GetPath(GAddress 
*address
, char *path
, size_t sbuf
) 
1761   struct sockaddr_un 
*addr
; 
1763   assert(address 
!= NULL
); 
1764   CHECK_ADDRESS(address
, UNIX
); 
1766   addr 
= (struct sockaddr_un 
*)address
->m_addr
; 
1768   strncpy(path
, addr
->sun_path
, sbuf
); 
1770   return GSOCK_NOERROR
; 
1775   /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */