diff options
Diffstat (limited to 'src/base')
| -rw-r--r-- | src/base/detect.h | 45 | ||||
| -rw-r--r-- | src/base/math.h | 11 | ||||
| -rw-r--r-- | src/base/system.c | 202 | ||||
| -rw-r--r-- | src/base/system.h | 41 |
4 files changed, 224 insertions, 75 deletions
diff --git a/src/base/detect.h b/src/base/detect.h index 0b66acef..f9ca5779 100644 --- a/src/base/detect.h +++ b/src/base/detect.h @@ -25,7 +25,7 @@ #endif /* unix family */ -#if defined(__FreeBSD__) +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) #define CONF_FAMILY_UNIX 1 #define CONF_FAMILY_STRING "unix" #define CONF_PLATFORM_FREEBSD 1 @@ -46,6 +46,13 @@ #define CONF_PLATFORM_STRING "linux" #endif +#if defined(__GNU__) || defined(__gnu__) + #define CONF_FAMILY_UNIX 1 + #define CONF_FAMILY_STRING "unix" + #define CONF_PLATFORM_HURD 1 + #define CONF_PLATFORM_STRING "gnu" +#endif + #if defined(MACOSX) || defined(__APPLE__) || defined(__DARWIN__) #define CONF_FAMILY_UNIX 1 #define CONF_FAMILY_STRING "unix" @@ -69,35 +76,61 @@ #endif +/* use gcc endianness definitions when available */ +#if defined(__GNUC__) && !defined(__APPLE__) + #if defined(__FreeBSD__) || defined(__OpenBSD__) + #include <sys/endian.h> + #else + #include <endian.h> + #endif + + #if __BYTE_ORDER == __LITTLE_ENDIAN + #define CONF_ARCH_ENDIAN_LITTLE 1 + #elif __BYTE_ORDER == __BIG_ENDIAN + #define CONF_ARCH_ENDIAN_BIG 1 + #endif +#endif + + /* architectures */ #if defined(i386) || defined(__i386__) || defined(__x86__) || defined(CONF_PLATFORM_WIN32) #define CONF_ARCH_IA32 1 #define CONF_ARCH_STRING "ia32" - #define CONF_ARCH_ENDIAN_LITTLE 1 + #if !defined(CONF_ARCH_ENDIAN_LITTLE) && !defined(CONF_ARCH_ENDIAN_BIG) + #define CONF_ARCH_ENDIAN_LITTLE 1 + #endif #endif #if defined(__ia64__) #define CONF_ARCH_IA64 1 #define CONF_ARCH_STRING "ia64" - #define CONF_ARCH_ENDIAN_LITTLE 1 + #if !defined(CONF_ARCH_ENDIAN_LITTLE) && !defined(CONF_ARCH_ENDIAN_BIG) + #define CONF_ARCH_ENDIAN_LITTLE 1 + #endif #endif #if defined(__amd64__) || defined(__x86_64__) #define CONF_ARCH_AMD64 1 #define CONF_ARCH_STRING "amd64" - #define CONF_ARCH_ENDIAN_LITTLE 1 + #if !defined(CONF_ARCH_ENDIAN_LITTLE) && !defined(CONF_ARCH_ENDIAN_BIG) + #define CONF_ARCH_ENDIAN_LITTLE 1 + #endif #endif #if defined(__powerpc__) || defined(__ppc__) #define CONF_ARCH_PPC 1 #define CONF_ARCH_STRING "ppc" - #define CONF_ARCH_ENDIAN_BIG 1 + #if !defined(CONF_ARCH_ENDIAN_LITTLE) && !defined(CONF_ARCH_ENDIAN_BIG) + #define CONF_ARCH_ENDIAN_BIG 1 + #endif #endif #if defined(__sparc__) #define CONF_ARCH_SPARC 1 #define CONF_ARCH_STRING "sparc" - #define CONF_ARCH_ENDIAN_BIG 1 + #if !defined(CONF_ARCH_ENDIAN_LITTLE) && !defined(CONF_ARCH_ENDIAN_BIG) + #define CONF_ARCH_ENDIAN_BIG 1 + #endif #endif diff --git a/src/base/math.h b/src/base/math.h index 1234f681..d58dbf10 100644 --- a/src/base/math.h +++ b/src/base/math.h @@ -39,6 +39,17 @@ inline float frandom() { return rand()/(float)(RAND_MAX); } inline int f2fx(float v) { return (int)(v*(float)(1<<10)); } inline float fx2f(int v) { return v*(1.0f/(1<<10)); } +inline int gcd(int a, int b) +{ + while(b != 0) + { + int c = a % b; + a = b; + b = c; + } + return a; +} + class fxp { int value; diff --git a/src/base/system.c b/src/base/system.c index 94481f21..466e3ca6 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -42,10 +42,6 @@ #include <fcntl.h> #include <direct.h> #include <errno.h> - - #ifndef EWOULDBLOCK - #define EWOULDBLOCK WSAEWOULDBLOCK - #endif #else #error NOT IMPLEMENTED #endif @@ -316,9 +312,12 @@ int io_seek(IOHANDLE io, int offset, int origin) break; case IOSEEK_END: real_origin = SEEK_END; + break; + default: + return -1; } - return fseek((FILE*)io, offset, origin); + return fseek((FILE*)io, offset, real_origin); } long int io_tell(IOHANDLE io) @@ -408,6 +407,17 @@ void thread_sleep(int milliseconds) #endif } +void thread_detach(void *thread) +{ +#if defined(CONF_FAMILY_UNIX) + pthread_detach((pthread_t)(thread)); +#elif defined(CONF_FAMILY_WINDOWS) + CloseHandle(thread); +#else + #error not implemented +#endif +} + @@ -571,13 +581,23 @@ int net_addr_comp(const NETADDR *a, const NETADDR *b) void net_addr_str(const NETADDR *addr, char *string, int max_length) { if(addr->type == NETTYPE_IPV4) - str_format(string, max_length, "%d.%d.%d.%d:%d", addr->ip[0], addr->ip[1], addr->ip[2], addr->ip[3], addr->port); + { + if(addr->port != 0) + str_format(string, max_length, "%d.%d.%d.%d:%d", addr->ip[0], addr->ip[1], addr->ip[2], addr->ip[3], addr->port); + else + str_format(string, max_length, "%d.%d.%d.%d", addr->ip[0], addr->ip[1], addr->ip[2], addr->ip[3]); + } else if(addr->type == NETTYPE_IPV6) { - str_format(string, max_length, "[%x:%x:%x:%x:%x:%x:%x:%x]:%d", - (addr->ip[0]<<8)|addr->ip[1], (addr->ip[2]<<8)|addr->ip[3], (addr->ip[4]<<8)|addr->ip[5], (addr->ip[6]<<8)|addr->ip[7], - (addr->ip[8]<<8)|addr->ip[9], (addr->ip[10]<<8)|addr->ip[11], (addr->ip[12]<<8)|addr->ip[13], (addr->ip[14]<<8)|addr->ip[15], - addr->port); + if(addr->port != 0) + str_format(string, max_length, "[%x:%x:%x:%x:%x:%x:%x:%x]:%d", + (addr->ip[0]<<8)|addr->ip[1], (addr->ip[2]<<8)|addr->ip[3], (addr->ip[4]<<8)|addr->ip[5], (addr->ip[6]<<8)|addr->ip[7], + (addr->ip[8]<<8)|addr->ip[9], (addr->ip[10]<<8)|addr->ip[11], (addr->ip[12]<<8)|addr->ip[13], (addr->ip[14]<<8)|addr->ip[15], + addr->port); + else + str_format(string, max_length, "[%x:%x:%x:%x:%x:%x:%x:%x]", + (addr->ip[0]<<8)|addr->ip[1], (addr->ip[2]<<8)|addr->ip[3], (addr->ip[4]<<8)|addr->ip[5], (addr->ip[6]<<8)|addr->ip[7], + (addr->ip[8]<<8)|addr->ip[9], (addr->ip[10]<<8)|addr->ip[11], (addr->ip[12]<<8)|addr->ip[13], (addr->ip[14]<<8)|addr->ip[15]); } else str_format(string, max_length, "unknown type %d", addr->type); @@ -799,8 +819,6 @@ static int priv_net_close_all_sockets(NETSOCKET sock) static int priv_net_create_socket(int domain, int type, struct sockaddr *addr, int sockaddrlen) { int sock, e; - unsigned long mode = 1; - int broadcast = 1; /* create socket */ sock = socket(domain, type, 0); @@ -811,11 +829,13 @@ static int priv_net_create_socket(int domain, int type, struct sockaddr *addr, i } /* set to IPv6 only if thats what we are creating */ +#if defined(IPV6_V6ONLY) /* windows sdk 6.1 and higher */ if(domain == AF_INET6) { int ipv6only = 1; setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&ipv6only, sizeof(ipv6only)); } +#endif /* bind the socket */ e = bind(sock, addr, sockaddrlen); @@ -826,16 +846,6 @@ static int priv_net_create_socket(int domain, int type, struct sockaddr *addr, i return -1; } - /* set non-blocking */ -#if defined(CONF_FAMILY_WINDOWS) - ioctlsocket(sock, FIONBIO, &mode); -#else - ioctl(sock, FIONBIO, &mode); -#endif - - /* set boardcast */ - setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof(broadcast)); - /* return the newly created socket */ return sock; } @@ -844,6 +854,7 @@ NETSOCKET net_udp_create(NETADDR bindaddr) { NETSOCKET sock = invalid_socket; NETADDR tmpbindaddr = bindaddr; + int broadcast = 1; if(bindaddr.type&NETTYPE_IPV4) { @@ -859,6 +870,12 @@ NETSOCKET net_udp_create(NETADDR bindaddr) sock.type |= NETTYPE_IPV4; sock.ipv4sock = socket; } + + /* set non-blocking */ + net_set_non_blocking(sock); + + /* set boardcast */ + setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof(broadcast)); } if(bindaddr.type&NETTYPE_IPV6) @@ -875,6 +892,12 @@ NETSOCKET net_udp_create(NETADDR bindaddr) sock.type |= NETTYPE_IPV6; sock.ipv6sock = socket; } + + /* set non-blocking */ + net_set_non_blocking(sock); + + /* set boardcast */ + setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof(broadcast)); } /* return */ @@ -984,32 +1007,48 @@ int net_udp_close(NETSOCKET sock) return priv_net_close_all_sockets(sock); } -// TODO: make TCP stuff work again -NETSOCKET net_tcp_create(const NETADDR *a) +NETSOCKET net_tcp_create(NETADDR bindaddr) { - /* TODO: IPv6 support */ NETSOCKET sock = invalid_socket; + NETADDR tmpbindaddr = bindaddr; - if(a->type&NETTYPE_IPV4) + if(bindaddr.type&NETTYPE_IPV4) { struct sockaddr_in addr; + int socket = -1; + + /* bind, we should check for error */ + tmpbindaddr.type = NETTYPE_IPV4; + netaddr_to_sockaddr_in(&tmpbindaddr, &addr); + socket = priv_net_create_socket(AF_INET, SOCK_STREAM, (struct sockaddr *)&addr, sizeof(addr)); + if(socket >= 0) + { + sock.type |= NETTYPE_IPV4; + sock.ipv4sock = socket; + } + } - /* create socket */ - sock.type |= NETTYPE_IPV4; - sock.ipv4sock = socket(AF_INET, SOCK_STREAM, 0); - if(sock.ipv4sock < 0) - return invalid_socket; + if(bindaddr.type&NETTYPE_IPV6) + { + struct sockaddr_in6 addr; + int socket = -1; /* bind, we should check for error */ - netaddr_to_sockaddr_in(a, &addr); - bind(sock.ipv4sock, (struct sockaddr *)&addr, sizeof(addr)); + tmpbindaddr.type = NETTYPE_IPV6; + netaddr_to_sockaddr_in6(&tmpbindaddr, &addr); + socket = priv_net_create_socket(AF_INET6, SOCK_STREAM, (struct sockaddr *)&addr, sizeof(addr)); + if(socket >= 0) + { + sock.type |= NETTYPE_IPV6; + sock.ipv6sock = socket; + } } /* return */ return sock; } -int net_tcp_set_non_blocking(NETSOCKET sock) +int net_set_non_blocking(NETSOCKET sock) { unsigned long mode = 1; if(sock.ipv4sock >= 0) @@ -1033,7 +1072,7 @@ int net_tcp_set_non_blocking(NETSOCKET sock) return 0; } -int net_tcp_set_blocking(NETSOCKET sock) +int net_set_blocking(NETSOCKET sock) { unsigned long mode = 0; if(sock.ipv4sock >= 0) @@ -1059,30 +1098,31 @@ int net_tcp_set_blocking(NETSOCKET sock) int net_tcp_listen(NETSOCKET sock, int backlog) { + int err = -1; if(sock.ipv4sock >= 0) - listen(sock.ipv4sock, backlog); + err = listen(sock.ipv4sock, backlog); if(sock.ipv6sock >= 0) - listen(sock.ipv6sock, backlog); - return 0; + err = listen(sock.ipv6sock, backlog); + return err; } int net_tcp_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR *a) { int s; socklen_t sockaddr_len; - struct sockaddr addr; *new_sock = invalid_socket; - sockaddr_len = sizeof(addr); - if(sock.ipv4sock >= 0) { - s = accept(sock.ipv4sock, &addr, &sockaddr_len); + struct sockaddr_in addr; + sockaddr_len = sizeof(addr); + s = accept(sock.ipv4sock, (struct sockaddr *)&addr, &sockaddr_len); + if (s != -1) { - sockaddr_to_netaddr(&addr, a); + sockaddr_to_netaddr((const struct sockaddr *)&addr, a); new_sock->type = NETTYPE_IPV4; new_sock->ipv4sock = s; return s; @@ -1091,55 +1131,74 @@ int net_tcp_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR *a) if(sock.ipv6sock >= 0) { - s = accept(sock.ipv6sock, &addr, &sockaddr_len); + struct sockaddr_in6 addr; + sockaddr_len = sizeof(addr); + s = accept(sock.ipv6sock, (struct sockaddr *)&addr, &sockaddr_len); + if (s != -1) { - sockaddr_to_netaddr(&addr, a); + sockaddr_to_netaddr((const struct sockaddr *)&addr, a); new_sock->type = NETTYPE_IPV6; new_sock->ipv6sock = s; return s; } } - return 0; + return -1; } int net_tcp_connect(NETSOCKET sock, const NETADDR *a) { - /*struct sockaddr addr; - netaddr_to_sockaddr(a, &addr); - return connect(sock, &addr, sizeof(addr)); - */ - return 0; + if(a->type&NETTYPE_IPV4) + { + struct sockaddr_in addr; + netaddr_to_sockaddr_in(a, &addr); + return connect(sock.ipv4sock, (struct sockaddr *)&addr, sizeof(addr)); + } + + if(a->type&NETTYPE_IPV6) + { + struct sockaddr_in6 addr; + netaddr_to_sockaddr_in6(a, &addr); + return connect(sock.ipv6sock, (struct sockaddr *)&addr, sizeof(addr)); + } + + return -1; } -int net_tcp_connect_non_blocking(NETSOCKET sock, const NETADDR *a) +int net_tcp_connect_non_blocking(NETSOCKET sock, NETADDR bindaddr) { - /* struct sockaddr addr; */ int res = 0; - /* - netaddr_to_sockaddr(a, &addr); - net_tcp_set_non_blocking(sock); - res = connect(sock, &addr, sizeof(addr)); - net_tcp_set_blocking(sock); - */ + net_set_non_blocking(sock); + res = net_tcp_connect(sock, &bindaddr); + net_set_blocking(sock); return res; } int net_tcp_send(NETSOCKET sock, const void *data, int size) { - int bytes = 0; - /* bytes = send((int)sock, (const char*)data, size, 0); */ + int bytes = -1; + + if(sock.ipv4sock >= 0) + bytes = send((int)sock.ipv4sock, (const char*)data, size, 0); + if(sock.ipv6sock >= 0) + bytes = send((int)sock.ipv6sock, (const char*)data, size, 0); + return bytes; } int net_tcp_recv(NETSOCKET sock, void *data, int maxsize) { - int bytes = 0; - /* bytes = recv((int)sock, (char*)data, maxsize, 0); */ + int bytes = -1; + + if(sock.ipv4sock >= 0) + bytes = recv((int)sock.ipv4sock, (char*)data, maxsize, 0); + if(sock.ipv6sock >= 0) + bytes = recv((int)sock.ipv6sock, (char*)data, maxsize, 0); + return bytes; } @@ -1150,12 +1209,20 @@ int net_tcp_close(NETSOCKET sock) int net_errno() { +#if defined(CONF_FAMILY_WINDOWS) + return WSAGetLastError(); +#else return errno; +#endif } int net_would_block() { +#if defined(CONF_FAMILY_WINDOWS) + return net_errno() == WSAEWOULDBLOCK; +#else return net_errno() == EWOULDBLOCK; +#endif } int net_init() @@ -1522,6 +1589,15 @@ int str_comp_nocase(const char *a, const char *b) #endif } +int str_comp_nocase_num(const char *a, const char *b, const int num) +{ +#if defined(CONF_FAMILY_WINDOWS) + return _strnicmp(a, b, num); +#else + return strncasecmp(a, b, num); +#endif +} + int str_comp(const char *a, const char *b) { return strcmp(a, b); diff --git a/src/base/system.h b/src/base/system.h index a486b89d..aaa5b43f 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -367,6 +367,16 @@ void thread_destroy(void *thread); */ void thread_yield(); +/* + Function: thread_detach + Puts the thread in the detached thread, guaranteeing that + resources of the thread will be freed immediately when the + thread terminates. + + Parameters: + thread - Thread to detach +*/ +void thread_detach(void *thread); /* Group: Locks */ typedef void* LOCK; @@ -581,7 +591,7 @@ int net_udp_close(NETSOCKET sock); Returns: On success it returns an handle to the socket. On failure it returns NETSOCKET_INVALID. */ -NETSOCKET net_tcp_create(const NETADDR *a); +NETSOCKET net_tcp_create(NETADDR bindaddr); /* Function: net_tcp_listen @@ -815,6 +825,25 @@ char *str_skip_whitespaces(char *str); */ int str_comp_nocase(const char *a, const char *b); +/* + Function: str_comp_nocase_num + Compares up to num characters of two strings case insensitive. + + Parameters: + a - String to compare. + b - String to compare. + num - Maximum characters to compare + + Returns: + <0 - String a is lesser than string b + 0 - String a is equal to string b + >0 - String a is greater than string b + + Remarks: + - Only garanted to work with a-z/A-Z. + - The strings are treated as zero-termineted strings. +*/ +int str_comp_nocase_num(const char *a, const char *b, const int num); /* Function: str_comp @@ -1065,21 +1094,21 @@ int fs_rename(const char *oldname, const char *newname); DOCTODO: serp */ -int net_tcp_connect_non_blocking(NETSOCKET sock, const NETADDR *a); +int net_tcp_connect_non_blocking(NETSOCKET sock, NETADDR bindaddr); /* - Function: net_tcp_set_non_blocking + Function: net_set_non_blocking DOCTODO: serp */ -int net_tcp_set_non_blocking(NETSOCKET sock); +int net_set_non_blocking(NETSOCKET sock); /* - Function: net_tcp_set_non_blocking + Function: net_set_non_blocking DOCTODO: serp */ -int net_tcp_set_blocking(NETSOCKET sock); +int net_set_blocking(NETSOCKET sock); /* Function: net_errno |