efl/src/lib/ecore_con/ecore_con_local_win32.c

726 lines
19 KiB
C
Raw Normal View History

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <process.h>
#include <Ecore.h>
#include "Ecore_Con.h"
#include "ecore_con_private.h"
#define BUFSIZE 512
static int _ecore_con_local_init_count = 0;
int
ecore_con_local_init(void)
{
if (++_ecore_con_local_init_count != 1)
return _ecore_con_local_init_count;
return _ecore_con_local_init_count;
}
int
ecore_con_local_shutdown(void)
{
if (--_ecore_con_local_init_count != 0)
return _ecore_con_local_init_count;
return _ecore_con_local_init_count;
}
static Eina_Bool
_ecore_con_local_win32_server_read_client_handler(void *data, Ecore_Win32_Handler *wh)
{
Ecore_Con_Client *obj = data;
Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
2013-12-19 21:07:50 -08:00
void *buf;
DWORD n;
Eina_Bool broken_pipe = EINA_FALSE;
Efl_Network_Server_Data *host_svr = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
2013-12-19 21:07:50 -08:00
2014-08-27 07:46:31 -07:00
if (!ResetEvent(host_svr->event_read))
2013-12-19 21:07:50 -08:00
return ECORE_CALLBACK_RENEW;
2014-08-27 07:46:31 -07:00
buf = malloc(host_svr->nbr_bytes);
2013-12-19 21:07:50 -08:00
if (!buf)
return ECORE_CALLBACK_RENEW;
2014-08-27 07:46:31 -07:00
if (ReadFile(host_svr->pipe, buf, host_svr->nbr_bytes, &n, NULL))
2013-12-19 21:07:50 -08:00
{
if (!cl->delete_me)
2014-08-27 07:46:31 -07:00
ecore_con_event_client_data(obj, buf, host_svr->nbr_bytes, EINA_FALSE);
host_svr->want_write = 1;
2013-12-19 21:07:50 -08:00
}
else
{
if (GetLastError() == ERROR_BROKEN_PIPE)
broken_pipe = EINA_TRUE;
}
if (broken_pipe)
{
#if 0
ecore_con_event_client_error(cl, evil_last_error_get());
#endif
2014-08-27 07:46:31 -07:00
_ecore_con_client_kill(obj);
2013-12-19 21:07:50 -08:00
return ECORE_CALLBACK_CANCEL;
}
2014-08-27 07:46:31 -07:00
if (host_svr->want_write)
ecore_con_local_win32_client_flush(obj);
ecore_main_win32_handler_del(wh);
2013-12-19 21:07:50 -08:00
return ECORE_CALLBACK_DONE;
}
static Eina_Bool
_ecore_con_local_win32_server_peek_client_handler(void *data, Ecore_Win32_Handler *wh)
{
Ecore_Con_Client *obj = data;
Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
Efl_Network_Server_Data *host_svr = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
#if 0
char *msg;
#endif
2014-08-27 07:46:31 -07:00
if (!ResetEvent(host_svr->event_peek))
return ECORE_CALLBACK_RENEW;
#if 0
ecore_con_event_server_error(host_svr, evil_last_error_get());
#endif
_ecore_con_server_kill(cl->host_server);
return ECORE_CALLBACK_CANCEL;
ecore_main_win32_handler_del(wh);
return ECORE_CALLBACK_DONE;
}
static Eina_Bool
_ecore_con_local_win32_client_peek_server_handler(void *data, Ecore_Win32_Handler *wh)
{
2014-08-27 07:46:31 -07:00
Ecore_Con_Server *obj = data;
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
#if 0
char *msg;
#endif
if (!ResetEvent(svr->event_peek))
return ECORE_CALLBACK_RENEW;
#if 0
ecore_con_event_server_error(svr, evil_last_error_get());
#endif
_ecore_con_server_kill(obj);
return ECORE_CALLBACK_CANCEL;
ecore_main_win32_handler_del(wh);
return ECORE_CALLBACK_DONE;
}
static Eina_Bool
_ecore_con_local_win32_client_read_server_handler(void *data, Ecore_Win32_Handler *wh)
{
2014-08-27 07:46:31 -07:00
Ecore_Con_Server *obj = data;
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
2013-12-19 21:07:50 -08:00
void *buf;
DWORD n;
Eina_Bool broken_pipe = EINA_FALSE;
if (!ResetEvent(svr->event_read))
return ECORE_CALLBACK_RENEW;
buf = malloc(svr->nbr_bytes);
if (!buf)
return ECORE_CALLBACK_RENEW;
if (ReadFile(svr->pipe, buf, svr->nbr_bytes, &n, NULL))
{
if (!svr->delete_me)
ecore_con_event_server_data(obj, buf, svr->nbr_bytes, EINA_FALSE);
2013-12-19 21:07:50 -08:00
svr->want_write = 1;
}
else
{
if (GetLastError() == ERROR_BROKEN_PIPE)
broken_pipe = EINA_TRUE;
}
if (broken_pipe)
{
#if 0
ecore_con_event_server_error(svr, evil_last_error_get());
#endif
_ecore_con_server_kill(obj);
2013-12-19 21:07:50 -08:00
return ECORE_CALLBACK_CANCEL;
}
2013-12-19 21:07:50 -08:00
if (svr->want_write)
ecore_con_local_win32_server_flush(obj);
ecore_main_win32_handler_del(wh);
2013-12-19 21:07:50 -08:00
return ECORE_CALLBACK_DONE;
}
/* thread to read data sent by the server to the client */
static unsigned int __stdcall
_ecore_con_local_win32_client_read_server_thread(void *data)
{
2014-08-27 07:46:31 -07:00
Ecore_Con_Server *obj = data;
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
DWORD nbr_bytes = 0;
svr->read_stopped = EINA_FALSE;
while (!svr->read_stop)
{
if (PeekNamedPipe(svr->pipe, NULL, 0, NULL, &nbr_bytes, NULL))
{
if (nbr_bytes <= 0)
continue;
svr->nbr_bytes = nbr_bytes;
if (!SetEvent(svr->event_read))
continue;
}
else
{
if (GetLastError() == ERROR_BROKEN_PIPE)
{
if (!SetEvent(svr->event_peek))
continue;
break;
}
}
}
svr->read_stopped = EINA_TRUE;
_endthreadex(0);
return 0;
}
/* thread to read data sent by the client to the server */
static unsigned int __stdcall
_ecore_con_local_win32_server_read_client_thread(void *data)
{
Ecore_Con_Client *obj = data;
Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
Efl_Network_Server_Data *host_svr = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
DWORD nbr_bytes = 0;
2014-08-27 07:46:31 -07:00
host_svr->read_stopped = EINA_FALSE;
2014-08-27 07:46:31 -07:00
while (!host_svr->read_stop)
{
2014-08-27 07:46:31 -07:00
if (PeekNamedPipe(host_svr->pipe, NULL, 0, NULL, &nbr_bytes, NULL))
{
if (nbr_bytes <= 0)
continue;
2014-08-27 07:46:31 -07:00
host_svr->nbr_bytes = nbr_bytes;
if (!SetEvent(host_svr->event_read))
continue;
}
else
{
if (GetLastError() == ERROR_BROKEN_PIPE)
{
2014-08-27 07:46:31 -07:00
if (!SetEvent(host_svr->event_peek))
continue;
break;
}
}
}
2014-08-27 07:46:31 -07:00
host_svr->read_stopped = EINA_TRUE;
_endthreadex(0);
return 0;
}
static Eina_Bool
_ecore_con_local_win32_client_add(void *data, Ecore_Win32_Handler *wh)
{
Ecore_Con_Server *obj = data;
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
Ecore_Win32_Handler *handler_read;
Ecore_Win32_Handler *handler_peek;
if (!svr->pipe)
return ECORE_CALLBACK_CANCEL;
if (svr->delete_me)
return ECORE_CALLBACK_CANCEL;
if ((svr->client_limit >= 0) && (!svr->reject_excess_clients) &&
(svr->client_count >= (unsigned int)svr->client_limit))
return ECORE_CALLBACK_CANCEL;
Ecore_Con_Client *cl_obj = efl_add(EFL_NETWORK_CLIENT_CLASS, efl_main_loop_get());
Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
if (!cl)
{
ERR("allocation failed");
return ECORE_CALLBACK_CANCEL;
}
cl->host_server = obj;
svr->event_read = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!svr->event_read)
{
ERR("Can not create event read");
goto free_cl;
}
handler_read = ecore_main_win32_handler_add(svr->event_read,
_ecore_con_local_win32_server_read_client_handler,
obj);
if (!handler_read)
{
ERR("Can not create handler read");
goto close_event_read;
}
svr->event_peek = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!svr->event_peek)
{
ERR("Can not create event peek");
goto del_handler_read;
}
handler_peek = ecore_main_win32_handler_add(svr->event_peek,
_ecore_con_local_win32_server_peek_client_handler,
obj);
if (!handler_peek)
{
ERR("Can not create handler peek");
goto close_event_peek;
}
svr->read_stopped = EINA_TRUE;
svr->thread_read = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_server_read_client_thread, cl, CREATE_SUSPENDED, NULL);
if (!svr->thread_read)
{
ERR("Can not launch thread");
goto del_handler_peek;
}
svr->clients = eina_list_append(svr->clients, obj);
svr->client_count++;
if (!cl->delete_me)
ecore_con_event_client_add(obj);
ecore_main_win32_handler_del(wh);
ResumeThread(svr->thread_read);
return ECORE_CALLBACK_DONE;
2013-12-19 21:07:50 -08:00
del_handler_peek:
ecore_main_win32_handler_del(handler_peek);
2013-12-19 21:07:50 -08:00
close_event_peek:
CloseHandle(svr->event_peek);
2013-12-19 21:07:50 -08:00
del_handler_read:
ecore_main_win32_handler_del(handler_read);
2013-12-19 21:07:50 -08:00
close_event_read:
2014-08-27 07:46:31 -07:00
CloseHandle(svr->event_read);
2013-12-19 21:07:50 -08:00
free_cl:
efl_del(cl_obj);
return ECORE_CALLBACK_CANCEL;
}
static unsigned int __stdcall
_ecore_con_local_win32_listening(void *data)
{
Ecore_Con_Server *obj = data;
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
BOOL res;
while (1)
{
res = ConnectNamedPipe(svr->pipe, NULL);
if (!res)
{
ERR("Opening the connection to the client failed");
CloseHandle(svr->pipe);
svr->pipe = NULL;
}
break;
}
DBG("Client connected");
_endthreadex(0);
return 0;
}
ecore_con: Rename EAPI macro to ECORE_CON_API in Ecore Con library Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass ```__attribute__ ((visibility ("default")))``` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as ```__atttribute__((visibility("default")))```. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
2020-09-15 06:16:24 -07:00
ECORE_CON_API char *
ecore_con_local_path_new(Eina_Bool is_system, const char *name, int port)
{
char buf[256];
if (!is_system)
snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s%ld", name, GetProcessId(GetCurrentProcess()));
else
{
const char *computername;
computername = getenv("COMPUTERNAME");
snprintf(buf, sizeof(buf), "\\\\%s\\pipe\\%s%ld", computername, name, GetProcessId(GetCurrentProcess()));
}
return strdup(buf);
(void)port; // CHECK-ME: shouldn't we use port to be similar to UNIX?
}
Eina_Bool
ecore_con_local_listen(Ecore_Con_Server *obj)
{
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
HANDLE thread_listening;
Ecore_Win32_Handler *handler;
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
{
ERR("Your system does not support abstract sockets!");
return EINA_FALSE;
}
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
svr->path = ecore_con_local_path_new(EINA_FALSE, svr->name, svr->port);
else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
svr->path = ecore_con_local_path_new(EINA_TRUE, svr->name, svr->port);
if (!svr->path)
{
ERR("Allocation failed");
return EINA_FALSE;
}
/*
* synchronuous
* block mode
* wait mode
*/
svr->pipe = CreateNamedPipe(svr->path,
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
BUFSIZE,
BUFSIZE,
5000,
NULL);
if (svr->pipe == INVALID_HANDLE_VALUE)
{
DBG("Creation of the named pipe '%s' failed", svr->path);
goto free_path;
}
/*
* We use ConnectNamedPipe() to wait for a client to connect.
* As the function is blocking, to let the main loop continuing
* its iterations, we call ConnectNamedPipe() in a thread
*/
thread_listening = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_listening, obj, CREATE_SUSPENDED, NULL);
if (!thread_listening)
{
ERR("Creation of the listening thread failed");
goto close_pipe;
}
handler = ecore_main_win32_handler_add(thread_listening,
_ecore_con_local_win32_client_add,
obj);
if (!handler)
{
ERR("Creation of the client add handler failed");
goto del_handler;
}
svr->read_stopped = EINA_TRUE;
ResumeThread(thread_listening);
return EINA_TRUE;
2013-12-19 21:07:50 -08:00
del_handler:
ecore_main_win32_handler_del(handler);
2013-12-19 21:07:50 -08:00
close_pipe:
CloseHandle(svr->pipe);
2013-12-19 21:07:50 -08:00
free_path:
free(svr->path);
svr->path = NULL;
return EINA_FALSE;
}
void
ecore_con_local_win32_server_del(Ecore_Con_Server *obj)
{
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
return;
if (((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) &&
((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM))
return;
svr->read_stop = 1;
/* FIXME: we should try to stop these thread in one way or another */
/* should we use ecore_thread ? */
/* while (!svr->read_stopped) */
/* Sleep(100); */
if (svr->event_peek)
CloseHandle(svr->event_peek);
svr->event_peek = NULL;
if (svr->event_read)
CloseHandle(svr->event_read);
svr->event_read = NULL;
free(svr->path);
svr->path = NULL;
if (svr->pipe)
CloseHandle(svr->pipe);
svr->pipe = NULL;
}
void
ecore_con_local_win32_client_del(Ecore_Con_Client *obj)
{
Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
Efl_Network_Server_Data *svr = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
return;
if (((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) &&
((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM))
return;
svr->read_stop = 1;
while (!svr->read_stopped)
Sleep(100);
if (svr->event_peek)
CloseHandle(svr->event_peek);
svr->event_peek = NULL;
if (svr->event_read)
CloseHandle(svr->event_read);
svr->event_read = NULL;
free(svr->path);
svr->path = NULL;
if (svr->pipe)
CloseHandle(svr->pipe);
svr->pipe = NULL;
}
Eina_Bool
ecore_con_local_connect(Ecore_Con_Server *obj,
Eina_Bool (*cb_done)(void *data,
Ecore_Fd_Handler *fd_handler))
{
#warning "I am pretty sure cb_done should be used."
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
char *buf = NULL;
Ecore_Win32_Handler *handler_read;
Ecore_Win32_Handler *handler_peek;
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
{
WRN("Your system does not support abstract sockets!");
return EINA_FALSE;
}
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
buf = ecore_con_local_path_new(EINA_FALSE, svr->name, svr->port);
else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
buf = ecore_con_local_path_new(EINA_TRUE, svr->name, svr->port);
EINA_SAFETY_ON_NULL_RETURN_VAL(buf, EINA_FALSE);
while (1)
{
svr->pipe = CreateFile(buf,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if (svr->pipe != INVALID_HANDLE_VALUE)
break;
/* if pipe not busy, we exit */
if (GetLastError() != ERROR_PIPE_BUSY)
{
DBG("Connection to a server failed");
free(buf);
return EINA_FALSE;
2013-12-19 21:07:50 -08:00
}
/* pipe busy, so we wait for it */
if (!WaitNamedPipe(buf, NMPWAIT_WAIT_FOREVER))
{
DBG("Can not wait for a server");
goto close_pipe;
}
}
svr->path = buf;
buf = NULL;
svr->event_read = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!svr->event_read)
{
ERR("Can not create event read");
goto free_path;
}
handler_read = ecore_main_win32_handler_add(svr->event_read,
_ecore_con_local_win32_client_read_server_handler,
obj);
if (!handler_read)
{
ERR("Can not create handler read");
goto close_event_read;
}
svr->event_peek = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!svr->event_peek)
{
ERR("Can not create event peek");
goto del_handler_read;
}
handler_peek = ecore_main_win32_handler_add(svr->event_peek,
_ecore_con_local_win32_client_peek_server_handler,
obj);
if (!handler_peek)
{
ERR("Can not create handler peek");
goto close_event_peek;
}
svr->thread_read = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_client_read_server_thread, obj, CREATE_SUSPENDED, NULL);
if (!svr->thread_read)
{
ERR("Can not launch thread");
goto del_handler_peek;
}
if (!svr->delete_me) ecore_con_event_server_add(obj);
ResumeThread(svr->thread_read);
free(buf);
return EINA_TRUE;
2013-12-19 21:07:50 -08:00
del_handler_peek:
ecore_main_win32_handler_del(handler_peek);
2013-12-19 21:07:50 -08:00
close_event_peek:
CloseHandle(svr->event_peek);
2013-12-19 21:07:50 -08:00
del_handler_read:
ecore_main_win32_handler_del(handler_read);
2013-12-19 21:07:50 -08:00
close_event_read:
CloseHandle(svr->event_read);
2013-12-19 21:07:50 -08:00
free_path:
free(svr->path);
svr->path = NULL;
2013-12-19 21:07:50 -08:00
close_pipe:
CloseHandle(svr->pipe);
free(buf);
return EINA_FALSE;
}
Eina_Bool
ecore_con_local_win32_server_flush(Ecore_Con_Server *obj)
{
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
size_t num;
BOOL res;
DWORD written;
/* This check should never be true */
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
return EINA_TRUE;
if (((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) &&
((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM))
return EINA_FALSE;
num = eina_binbuf_length_get(svr->buf) - svr->write_buf_offset;
if (num == 0) return EINA_TRUE;
res = WriteFile(svr->pipe, eina_binbuf_string_get(svr->buf) + svr->write_buf_offset, num, &written, NULL);
if (!res)
{
ecore_con_event_server_error(obj, evil_last_error_get());
_ecore_con_server_kill(obj);
}
svr->write_buf_offset += written;
if (svr->write_buf_offset >= eina_binbuf_length_get(svr->buf))
{
svr->write_buf_offset = 0;
eina_binbuf_free(svr->buf);
svr->buf = NULL;
svr->want_write = 0;
}
else if (written < (DWORD)num)
svr->want_write = 1;
return EINA_TRUE;
}
Eina_Bool
ecore_con_local_win32_client_flush(Ecore_Con_Client *obj)
{
Efl_Network_Client_Data *cl = efl_data_scope_get(obj, EFL_NETWORK_CLIENT_CLASS);
Ecore_Con_Type type;
size_t num;
BOOL res;
DWORD written;
Efl_Network_Server_Data *svr = efl_data_scope_get(cl->host_server, EFL_NETWORK_SERVER_CLASS);
type = svr->type & ECORE_CON_TYPE;
/* This check should never be true */
if (type == ECORE_CON_LOCAL_ABSTRACT)
return EINA_TRUE;
if ((type != ECORE_CON_LOCAL_USER) &&
(type != ECORE_CON_LOCAL_SYSTEM))
return EINA_FALSE;
num = eina_binbuf_length_get(cl->buf) - cl->buf_offset;
if (num == 0) return EINA_TRUE;
res = WriteFile(svr->pipe, eina_binbuf_string_get(cl->buf) + cl->buf_offset, num, &written, NULL);
if (!res)
{
ecore_con_event_client_error(obj, evil_last_error_get());
_ecore_con_client_kill(obj);
}
cl->buf_offset += written;
if (cl->buf_offset >= eina_binbuf_length_get(cl->buf))
{
cl->buf_offset = 0;
eina_binbuf_free(cl->buf);
cl->buf = NULL;
svr->want_write = 0;
}
else if (written < (DWORD)num)
svr->want_write = 1;
return EINA_TRUE;
}
2013-12-19 21:07:50 -08:00