Home | History | Annotate | Download | only in util
      1 
      2 #include "pipe/p_compiler.h"
      3 #include "util/u_network.h"
      4 #include "util/u_debug.h"
      5 
      6 #if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
      7 #  include <winsock2.h>
      8 #  include <windows.h>
      9 #elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || \
     10    defined(PIPE_OS_APPLE) || defined(PIPE_OS_CYGWIN) || defined(PIPE_OS_SOLARIS)
     11 #  include <sys/socket.h>
     12 #  include <netinet/in.h>
     13 #  include <unistd.h>
     14 #  include <fcntl.h>
     15 #  include <netdb.h>
     16 #else
     17 #  warning "No socket implementation"
     18 #endif
     19 
     20 boolean
     21 u_socket_init()
     22 {
     23 #if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
     24    WORD wVersionRequested;
     25    WSADATA wsaData;
     26    int err;
     27 
     28    /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
     29    wVersionRequested = MAKEWORD(1, 1);
     30 
     31    err = WSAStartup(wVersionRequested, &wsaData);
     32    if (err != 0) {
     33       debug_printf("WSAStartup failed with error: %d\n", err);
     34       return FALSE;
     35    }
     36    return TRUE;
     37 #elif defined(PIPE_HAVE_SOCKETS)
     38    return TRUE;
     39 #else
     40    return FALSE;
     41 #endif
     42 }
     43 
     44 void
     45 u_socket_stop()
     46 {
     47 #if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
     48    WSACleanup();
     49 #endif
     50 }
     51 
     52 void
     53 u_socket_close(int s)
     54 {
     55    if (s < 0)
     56       return;
     57 
     58 #if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) \
     59     || defined(PIPE_OS_APPLE) || defined(PIPE_OS_SOLARIS)
     60    shutdown(s, SHUT_RDWR);
     61    close(s);
     62 #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
     63    shutdown(s, SD_BOTH);
     64    closesocket(s);
     65 #else
     66    assert(0);
     67 #endif
     68 }
     69 
     70 int u_socket_accept(int s)
     71 {
     72 #if defined(PIPE_HAVE_SOCKETS)
     73    return accept(s, NULL, NULL);
     74 #else
     75    return -1;
     76 #endif
     77 }
     78 
     79 int
     80 u_socket_send(int s, void *data, size_t size)
     81 {
     82 #if defined(PIPE_HAVE_SOCKETS)
     83    return send(s, data, size, 0);
     84 #else
     85    return -1;
     86 #endif
     87 }
     88 
     89 int
     90 u_socket_peek(int s, void *data, size_t size)
     91 {
     92 #if defined(PIPE_HAVE_SOCKETS)
     93    return recv(s, data, size, MSG_PEEK);
     94 #else
     95    return -1;
     96 #endif
     97 }
     98 
     99 int
    100 u_socket_recv(int s, void *data, size_t size)
    101 {
    102 #if defined(PIPE_HAVE_SOCKETS)
    103    return recv(s, data, size, 0);
    104 #else
    105    return -1;
    106 #endif
    107 }
    108 
    109 int
    110 u_socket_connect(const char *hostname, uint16_t port)
    111 {
    112 #if defined(PIPE_HAVE_SOCKETS)
    113    int s;
    114    struct sockaddr_in sa;
    115    struct hostent *host = NULL;
    116 
    117    memset(&sa, 0, sizeof(struct sockaddr_in));
    118    host = gethostbyname(hostname);
    119    if (!host)
    120       return -1;
    121 
    122    memcpy((char *)&sa.sin_addr,host->h_addr_list[0],host->h_length);
    123    sa.sin_family= host->h_addrtype;
    124    sa.sin_port = htons(port);
    125 
    126    s = socket(host->h_addrtype, SOCK_STREAM, IPPROTO_TCP);
    127    if (s < 0)
    128       return -1;
    129 
    130    if (connect(s, (struct sockaddr *)&sa, sizeof(sa))) {
    131       u_socket_close(s);
    132       return -1;
    133    }
    134 
    135    return s;
    136 #else
    137    assert(0);
    138    return -1;
    139 #endif
    140 }
    141 
    142 int
    143 u_socket_listen_on_port(uint16_t portnum)
    144 {
    145 #if defined(PIPE_HAVE_SOCKETS)
    146    int s;
    147    struct sockaddr_in sa;
    148    memset(&sa, 0, sizeof(struct sockaddr_in));
    149 
    150    sa.sin_family = AF_INET;
    151    sa.sin_port = htons(portnum);
    152 
    153    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    154    if (s < 0)
    155       return -1;
    156 
    157    if (bind(s, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) == -1) {
    158       u_socket_close(s);
    159       return -1;
    160    }
    161 
    162    listen(s, 0);
    163 
    164    return s;
    165 #else
    166    assert(0);
    167    return -1;
    168 #endif
    169 }
    170 
    171 void
    172 u_socket_block(int s, boolean block)
    173 {
    174 #if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) \
    175     || defined(PIPE_OS_APPLE) || defined(PIPE_OS_SOLARIS)
    176    int old = fcntl(s, F_GETFL, 0);
    177    if (old == -1)
    178       return;
    179 
    180    /* TODO obey block */
    181    if (block)
    182       fcntl(s, F_SETFL, old & ~O_NONBLOCK);
    183    else
    184       fcntl(s, F_SETFL, old | O_NONBLOCK);
    185 #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
    186    u_long iMode = block ? 0 : 1;
    187    ioctlsocket(s, FIONBIO, &iMode);
    188 #else
    189    assert(0);
    190 #endif
    191 }
    192