barbieri pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=4814f937e2e1b7705daf3c5cf7e32d9cb0fe120c

commit 4814f937e2e1b7705daf3c5cf7e32d9cb0fe120c
Author: Gustavo Sverzut Barbieri <barbi...@profusion.mobi>
Date:   Thu Sep 8 16:12:18 2016 -0300

    efl_net_socket_fd: make it more win32 friendly.
    
    it seems that on windows read() and write() won't work with sockets,
    so use recv() and send().
    
    Note that this code is still untested on windows, at least the errors
    must be fetched using WSAGetLastError() instead of errno directly, but
    I don't have a Windows machine I can test.
---
 src/lib/ecore_con/ecore_con_private.h | 74 ++++++++++++++++++++++++++++
 src/lib/ecore_con/efl_net_socket_fd.c | 92 ++++++++++++++++++++++++++++++-----
 2 files changed, 155 insertions(+), 11 deletions(-)

diff --git a/src/lib/ecore_con/ecore_con_private.h 
b/src/lib/ecore_con/ecore_con_private.h
index e2fab7a..69102d7 100644
--- a/src/lib/ecore_con/ecore_con_private.h
+++ b/src/lib/ecore_con/ecore_con_private.h
@@ -377,4 +377,78 @@ Eina_Bool efl_net_ip_port_fmt(char *buf, int buflen, const 
struct sockaddr *addr
 
 int efl_net_socket4(int domain, int type, int protocol, Eina_Bool 
close_on_exec);
 
+static inline Eina_Error
+efl_net_socket_error_get(void)
+{
+#ifndef _WIN32
+   return errno;
+#else
+   Eina_Error err = WSAGetLastError();
+
+   if (0) { }
+
+   /* used by send() */
+#if defined(WSAEACCES) && (WSAEACCES != EACCES)
+   else if (err == WSAEACCES) err = EACCES;
+#endif
+#if defined(WSAEWOULDBLOCK) && (WSAEWOULDBLOCK != EAGAIN)
+   else if (err == WSAEWOULDBLOCK) err = EAGAIN;
+#endif
+#if defined(WSAEBADF) && (WSAEBADF != EBADF)
+   else if (err == WSAEBADF) err = EBADF;
+#endif
+#if defined(WSAECONNRESET) && (WSAECONNRESET != ECONNRESET)
+   else if (err == WSAECONNRESET) err = ECONNRESET;
+#endif
+#if defined(WSAEDESTADDRREQ) && (WSAEDESTADDRREQ != EDESTADDRREQ)
+   else if (err == WSAEDESTADDRREQ) err = EDESTADDRREQ;
+#endif
+#if defined(WSAEFAULT) && (WSAEFAULT != EFAULT)
+   else if (err == WSAEFAULT) err = EFAULT;
+#endif
+#if defined(WSAEINTR) && (WSAEINTR != EINTR)
+   else if (err == WSAEINTR) err = EINTR;
+#endif
+#if defined(WSAEINVAL) && (WSAEINVAL != EINVAL)
+   else if (err == WSAEINVAL) err = EINVAL;
+#endif
+#if defined(WSAEISCONN) && (WSAEISCONN != EISCONN)
+   else if (err == WSAEISCONN) err = EISCONN;
+#endif
+#if defined(WSAEMSGSIZE) && (WSAEMSGSIZE != EMSGSIZE)
+   else if (err == WSAEMSGSIZE) err = EMSGSIZE;
+#endif
+#if defined(WSAENOBUFS) && (WSAENOBUFS != ENOBUFS)
+   else if (err == WSAENOBUFS) err = ENOBUFS;
+#endif
+#if defined(WSA_NOT_ENOUGH_MEMORY) && (WSA_NOT_ENOUGH_MEMORY != ENOMEM)
+   else if (err == WSA_NOT_ENOUGH_MEMORY) err = ENOMEM;
+#endif
+#if defined(WSAENOTCONN) && (WSAENOTCONN != ENOTCONN)
+   else if (err == WSAENOTCONN) err = ENOTCONN;
+#endif
+#if defined(WSAENOTSOCK) && (WSAENOTSOCK != ENOTSOCK)
+   else if (err == WSAENOTSOCK) err = ENOTSOCK;
+#endif
+#if defined(WSAEOPNOTSUPP) && (WSAEOPNOTSUPP != EOPNOTSUPP)
+   else if (err == WSAEOPNOTSUPP) err = EOPNOTSUPP;
+#endif
+#if defined(WSAESHUTDOWN) && (WSAESHUTDOWN != EPIPE)
+   else if (err == WSAESHUTDOWN) err = EPIPE;
+#endif
+
+   /* extras used by recv() */
+#if defined(WSAECONNREFUSED) && (WSAECONNREFUSED != ECONNREFUSED)
+   else if (err == WSAECONNREFUSED) err = ECONNREFUSED;
+#endif
+
+   /* extras used by getsockopt() */
+#if defined(WSAENOPROTOOPT) && (WSAENOPROTOOPT != ENOPROTOOPT)
+   else if (err == WSAENOPROTOOPT) err = ENOPROTOOPT;
+#endif
+
+   return err;
+#endif
+}
+
 #endif
diff --git a/src/lib/ecore_con/efl_net_socket_fd.c 
b/src/lib/ecore_con/efl_net_socket_fd.c
index 0cc9152..339e7ef 100644
--- a/src/lib/ecore_con/efl_net_socket_fd.c
+++ b/src/lib/ecore_con/efl_net_socket_fd.c
@@ -120,7 +120,7 @@ _efl_net_socket_fd_efl_loop_fd_fd_set(Eo *o, 
Efl_Net_Socket_Fd_Data *pd, int fd)
         struct sockaddr_storage addr;
         socklen_t addrlen = sizeof(addr);
         if (getsockname(fd, (struct sockaddr *)&addr, &addrlen) < 0)
-          ERR("getsockname(%d): %s", fd, strerror(errno));
+          ERR("getsockname(%d): %s", fd, 
eina_error_msg_get(efl_net_socket_error_get()));
         else
           efl_net_socket_fd_family_set(o, addr.ss_family);
      }
@@ -157,25 +157,84 @@ _efl_net_socket_fd_efl_io_closer_close(Eo *o, 
Efl_Net_Socket_Fd_Data *pd EINA_UN
 EOLIAN static Eina_Error
 _efl_net_socket_fd_efl_io_reader_read(Eo *o, Efl_Net_Socket_Fd_Data *pd 
EINA_UNUSED, Eina_Rw_Slice *rw_slice)
 {
-   Eina_Error ret;
+   int fd = efl_io_reader_fd_reader_fd_get(o);
+   ssize_t r;
 
-   ret = efl_io_reader_read(efl_super(o, MY_CLASS), rw_slice);
-   if (rw_slice && rw_slice->len > 0)
-     efl_io_reader_can_read_set(o, EINA_FALSE); /* wait Efl.Loop.Fd "read" */
+   EINA_SAFETY_ON_NULL_RETURN_VAL(rw_slice, EINVAL);
+   if (fd < 0) goto error;
+   do
+     {
+        r = recv(fd, rw_slice->mem, rw_slice->len, 0);
+        if (r < 0)
+          {
+             Eina_Error err = efl_net_socket_error_get();
 
-   return ret;
+             if (err == EINTR) continue;
+
+             rw_slice->len = 0;
+             rw_slice->mem = NULL;
+
+             if (err == EAGAIN) efl_io_reader_can_read_set(o, EINA_FALSE);
+             return err;
+          }
+     }
+   while (r < 0);
+
+   rw_slice->len = r;
+   efl_io_reader_can_read_set(o, EINA_FALSE); /* wait Efl.Loop.Fd "read" */
+   if (r == 0)
+     efl_io_reader_eos_set(o, EINA_TRUE);
+
+   return 0;
+
+ error:
+   rw_slice->len = 0;
+   rw_slice->mem = NULL;
+   return EINVAL;
 }
 
 EOLIAN static Eina_Error
 _efl_net_socket_fd_efl_io_writer_write(Eo *o, Efl_Net_Socket_Fd_Data *pd 
EINA_UNUSED, Eina_Slice *ro_slice, Eina_Slice *remaining)
 {
-   Eina_Error ret;
+   int fd = efl_io_writer_fd_writer_fd_get(o);
+   ssize_t r;
 
-   ret = efl_io_writer_write(efl_super(o, MY_CLASS), ro_slice, remaining);
-   if (ro_slice && ro_slice->len > 0)
-     efl_io_writer_can_write_set(o, EINA_FALSE); /* wait Efl.Loop.Fd "write" */
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ro_slice, EINVAL);
+   if (fd < 0) goto error;
 
-   return ret;
+   do
+     {
+        r = send(fd, ro_slice->mem, ro_slice->len, 0);
+        if (r < 0)
+          {
+             Eina_Error err = efl_net_socket_error_get();
+
+             if (err == EINTR) continue;
+
+             if (remaining) *remaining = *ro_slice;
+             ro_slice->len = 0;
+             ro_slice->mem = NULL;
+             if (err == EAGAIN) efl_io_writer_can_write_set(o, EINA_FALSE);
+             return err;
+          }
+     }
+   while (r < 0);
+
+   if (remaining)
+     {
+        remaining->len = ro_slice->len - r;
+        remaining->bytes = ro_slice->bytes + r;
+     }
+   ro_slice->len = r;
+   efl_io_writer_can_write_set(o, EINA_FALSE); /* wait Efl.Loop.Fd "write" */
+
+   return 0;
+
+ error:
+   if (remaining) *remaining = *ro_slice;
+   ro_slice->len = 0;
+   ro_slice->mem = NULL;
+   return EINVAL;
 }
 
 EOLIAN static void
@@ -205,6 +264,11 @@ _efl_net_socket_fd_efl_net_socket_address_remote_get(Eo *o 
EINA_UNUSED, Efl_Net_
 EOLIAN static Eina_Bool
 _efl_net_socket_fd_close_on_exec_set(Eo *o, Efl_Net_Socket_Fd_Data *pd, 
Eina_Bool close_on_exec)
 {
+#ifdef _WIN32
+   DBG("close on exec is not supported on windows");
+   pd->close_on_exec = close_on_exec;
+   return EINA_FALSE;
+#else
    int flags, fd;
 
    pd->close_on_exec = close_on_exec;
@@ -229,11 +293,16 @@ _efl_net_socket_fd_close_on_exec_set(Eo *o, 
Efl_Net_Socket_Fd_Data *pd, Eina_Boo
      }
 
    return EINA_TRUE;
+#endif
 }
 
 EOLIAN static Eina_Bool
 _efl_net_socket_fd_close_on_exec_get(Eo *o, Efl_Net_Socket_Fd_Data *pd)
 {
+#ifdef _WIN32
+   DBG("close on exec is not supported on windows");
+   return pd->close_on_exec;
+#else
    int flags, fd;
 
    fd = efl_loop_fd_get(o);
@@ -251,6 +320,7 @@ _efl_net_socket_fd_close_on_exec_get(Eo *o, 
Efl_Net_Socket_Fd_Data *pd)
 
    pd->close_on_exec = !!(flags & FD_CLOEXEC); /* sync */
    return pd->close_on_exec;
+#endif
 }
 
 EOLIAN static void

-- 


Reply via email to