diff --git a/lib/kc3/0.1/socket.kc3 b/lib/kc3/0.1/socket.kc3
index 2887651..09a92b5 100644
--- a/lib/kc3/0.1/socket.kc3
+++ b/lib/kc3/0.1/socket.kc3
@@ -4,8 +4,14 @@ defmodule Socket do
dlopen(__DIR__ + "socket.so")
+ def clean = cfn Void "socket_clean" ()
+
def close = cfn Void "socket_close" (Socket)
+ def init = cfn Bool "socket_init" ()
+
def listen = cfn Socket "socket_init_listen" (Result, Str, Str)
+ true = init()
+
end
diff --git a/libkc3/str.c b/libkc3/str.c
index 29db4df..2aba3df 100644
--- a/libkc3/str.c
+++ b/libkc3/str.c
@@ -13,6 +13,7 @@
#include <math.h>
#include <stdarg.h>
#include <string.h>
+#include <time.h>
#include "alloc.h"
#include "assert.h"
#include "buf.h"
@@ -749,18 +750,26 @@ DEF_STR_INIT_STRUCT(fn)
s_str * str_init_ftime (s_str *str, s_time *time, const s_str *format)
{
char *buf;
+ sw r;
uw size;
time_t t;
s_str tmp;
const struct tm *utc = NULL;
t = time->tv_sec;
- if (! (utc = gmtime(&t)))
+ if (! (utc = gmtime(&t))) {
+ err_puts("str_init_ftime: gmtime");
+ assert(! "str_init_ftime: gmtime");
return NULL;
+ }
size = format->size * 32;
if (! (buf = alloc(size)))
return NULL;
- if (! strftime(buf, size - 1, format->ptr.pchar, utc))
+ r = strftime(buf, size, format->ptr.pchar, utc);
+ if ((! r) || (r == (sw) size)) {
+ err_puts("str_init_ftime: strftime");
+ assert(! "str_init_ftime: strftime");
goto clean;
+ }
if (! str_init_1_alloc(&tmp, buf))
goto clean;
free(buf);
diff --git a/libkc3/time.c b/libkc3/time.c
index 3e7966b..9c5fe80 100644
--- a/libkc3/time.c
+++ b/libkc3/time.c
@@ -11,6 +11,7 @@
* THIS SOFTWARE.
*/
#include <stdlib.h>
+#include <time.h>
#include "alloc.h"
#include "assert.h"
#include "str.h"
diff --git a/socket/socket.c b/socket/socket.c
index 342dc1b..c6693f6 100644
--- a/socket/socket.c
+++ b/socket/socket.c
@@ -26,6 +26,13 @@
#include "socket.h"
#include "socket_buf.h"
+void socket_clean (void)
+{
+#ifdef WIN32
+ WSACleanup();
+#endif
+}
+
void socket_close (p_socket s)
{
assert(s);
@@ -33,6 +40,19 @@ void socket_close (p_socket s)
*s = -1;
}
+bool socket_init (void)
+{
+#ifdef WIN32
+ static WSADATA wsa_data;
+ s32 r;
+ if ((r = WSAStartup(MAKEWORD(2,2), &wsa_data))) {
+ printf("WSAStartup failed with error: %d\n", r);
+ return false;
+ }
+#endif
+ return true;
+}
+
p_socket socket_init_accept (p_socket s, p_socket listening)
{
struct sockaddr *addr;
diff --git a/socket/socket.h b/socket/socket.h
index 09b7311..b1f8881 100644
--- a/socket/socket.h
+++ b/socket/socket.h
@@ -15,6 +15,11 @@
#include "types.h"
+/* Call socket_init before any socket operation. Call socket_clean after
+ all socket operations were completed. */
+void socket_clean (void);
+bool socket_init (void);
+
/* Stack-allocation compatible functions. */
p_socket socket_init_accept (p_socket s, p_socket listening);
p_socket socket_init_listen (p_socket s, const s_str *host,