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
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);
}
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
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;
}
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);
pd->close_on_exec = !!(flags & FD_CLOEXEC); /* sync */
return pd->close_on_exec;
+#endif
}
EOLIAN static void