{
Eo *copier = event->object;
fprintf(stderr, "INFO: echo copier done, close and del %p\n", copier);
- efl_io_closer_close(copier);
- efl_del(copier);
+ efl_del(copier); /* set to close_on_destructor, will auto close copier and client */
}
static void
fprintf(stderr, "ERROR: echo copier %p failed %d, close and del.\n",
copier, *perr);
- efl_io_closer_close(copier);
efl_del(copier);
}
efl_del(copier);
if (d->send_copier || d->recv_copier) return;
- efl_io_closer_close(d->client);
+ efl_io_closer_close(d->client); /* manually close once both copiers are done */
_send_recv_free(d);
}
Eo *echo_copier = efl_add(EFL_IO_COPIER_CLASS, efl_parent_get(client),
efl_io_copier_source_set(efl_added, client),
efl_io_copier_destination_set(efl_added, client),
- efl_event_callback_array_add(efl_added, echo_copier_cbs(), client)
+ efl_event_callback_array_add(efl_added, echo_copier_cbs(), client),
+ efl_io_closer_close_on_destructor_set(efl_added, EINA_TRUE) /* we want to auto-close as we have a single copier */
);
fprintf(stderr, "INFO: using an echo copier=%p for client %s\n",
d->send_copier = efl_add(EFL_IO_COPIER_CLASS, efl_parent_get(client),
efl_io_copier_source_set(efl_added, send_buffer),
efl_io_copier_destination_set(efl_added, client),
- efl_event_callback_array_add(efl_added, send_copier_cbs(), d)
+ efl_event_callback_array_add(efl_added, send_copier_cbs(), d),
+ efl_io_closer_close_on_destructor_set(efl_added, EINA_FALSE) /* we must wait both copiers to finish before we close! */
);
fprintf(stderr, "INFO: using sender buffer %p with copier %p for client %s\n",
d->recv_copier = efl_add(EFL_IO_COPIER_CLASS, efl_parent_get(client),
efl_io_copier_source_set(efl_added, client),
efl_io_copier_destination_set(efl_added, recv_buffer),
- efl_event_callback_array_add(efl_added, recv_copier_cbs(), d)
+ efl_event_callback_array_add(efl_added, recv_copier_cbs(), d),
+ efl_io_closer_close_on_destructor_set(efl_added, EINA_FALSE) /* we must wait both copiers to finish before we close! */
);
fprintf(stderr, "INFO: using receiver buffer %p with copier %p for client %s\n",
#endif
#include <Ecore.h>
+#include <fcntl.h>
#include "ecore_private.h"
#define MY_CLASS EFL_IO_CLOSER_FD_CLASS
typedef struct _Efl_Io_Closer_Fd_Data
{
int fd;
+ Eina_Bool close_on_exec;
+ Eina_Bool close_on_destructor;
} Efl_Io_Closer_Fd_Data;
EOLIAN static void
return efl_io_closer_fd_closer_fd_get(o) < 0;
}
+EOLIAN static Eina_Bool
+_efl_io_closer_fd_efl_io_closer_close_on_exec_set(Eo *o, Efl_Io_Closer_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;
+ Eina_Bool old = pd->close_on_exec;
+
+ pd->close_on_exec = close_on_exec;
+
+ fd = efl_io_closer_fd_closer_fd_get(o);
+ if (fd < 0) return EINA_TRUE; /* postpone until fd_set(), users
+ * must apply MANUALLY if it's not
+ * already set!
+ */
+
+ flags = fcntl(fd, F_GETFD);
+ if (flags < 0)
+ {
+ ERR("fcntl(%d, F_GETFD): %s", fd, strerror(errno));
+ pd->close_on_exec = old;
+ return EINA_FALSE;
+ }
+ if (close_on_exec)
+ flags |= FD_CLOEXEC;
+ else
+ flags &= (~FD_CLOEXEC);
+ if (fcntl(fd, F_SETFD, flags) < 0)
+ {
+ ERR("fcntl(%d, F_SETFD, %#x): %s", fd, flags, strerror(errno));
+ pd->close_on_exec = old;
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+#endif
+}
+
+EOLIAN static Eina_Bool
+_efl_io_closer_fd_efl_io_closer_close_on_exec_get(Eo *o, Efl_Io_Closer_Fd_Data *pd)
+{
+#ifdef _WIN32
+ return pd->close_on_exec;
+#else
+ int flags, fd;
+
+ fd = efl_io_closer_fd_closer_fd_get(o);
+ if (fd < 0) return pd->close_on_exec;
+
+ /* if there is a fd, always query it directly as it may be modified
+ * elsewhere by nasty users.
+ */
+ flags = fcntl(fd, F_GETFD);
+ if (flags < 0)
+ {
+ ERR("fcntl(%d, F_GETFD): %s", fd, strerror(errno));
+ return EINA_FALSE;
+ }
+
+ pd->close_on_exec = !!(flags & FD_CLOEXEC); /* sync */
+ return pd->close_on_exec;
+#endif
+}
+
+EOLIAN static void
+_efl_io_closer_fd_efl_io_closer_close_on_destructor_set(Eo *o EINA_UNUSED, Efl_Io_Closer_Fd_Data *pd, Eina_Bool close_on_destructor)
+{
+ pd->close_on_destructor = close_on_destructor;
+}
+
+EOLIAN static Eina_Bool
+_efl_io_closer_fd_efl_io_closer_close_on_destructor_get(Eo *o EINA_UNUSED, Efl_Io_Closer_Fd_Data *pd)
+{
+ return pd->close_on_destructor;
+}
+
#include "efl_io_closer_fd.eo.c"
implements {
Efl.Io.Closer.close;
Efl.Io.Closer.closed.get;
+ Efl.Io.Closer.close_on_exec;
+ Efl.Io.Closer.close_on_destructor;
}
}
} progress;
Eina_Bool closed;
Eina_Bool done;
+ Eina_Bool close_on_exec;
+ Eina_Bool close_on_destructor;
} Efl_Io_Copier_Data;
static void _efl_io_copier_write(Eo *o, Efl_Io_Copier_Data *pd);
if (efl_isa(pd->source, EFL_IO_CLOSER_MIXIN))
{
+ efl_io_closer_close_on_exec_set(pd->source, efl_io_closer_close_on_exec_get(o));
+ efl_io_closer_close_on_destructor_set(pd->source, efl_io_closer_close_on_destructor_get(o));
efl_event_callback_add(pd->source, EFL_IO_CLOSER_EVENT_CLOSED,
_efl_io_copier_source_closed, o);
}
if (efl_isa(pd->destination, EFL_IO_CLOSER_MIXIN))
{
+ efl_io_closer_close_on_exec_set(pd->destination, efl_io_closer_close_on_exec_get(o));
+ efl_io_closer_close_on_destructor_set(pd->destination, efl_io_closer_close_on_destructor_get(o));
efl_event_callback_add(pd->destination, EFL_IO_CLOSER_EVENT_CLOSED,
_efl_io_copier_destination_closed, o);
}
_efl_io_copier_efl_object_constructor(Eo *o, Efl_Io_Copier_Data *pd)
{
pd->buf = eina_binbuf_new();
+ pd->close_on_exec = EINA_TRUE;
+ pd->close_on_destructor = EINA_TRUE;
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->buf, NULL);
{
_COPIER_DBG(o, pd);
+ if (efl_io_closer_close_on_destructor_get(o) &&
+ (!efl_io_closer_closed_get(o)))
+ efl_io_closer_close(o);
+
efl_io_copier_source_set(o, NULL);
efl_io_copier_destination_set(o, NULL);
}
}
+EOLIAN static Eina_Bool
+_efl_io_copier_efl_io_closer_close_on_exec_set(Eo *o EINA_UNUSED, Efl_Io_Copier_Data *pd, Eina_Bool close_on_exec)
+{
+ if (pd->close_on_exec == close_on_exec) return EINA_TRUE;
+ pd->close_on_exec = close_on_exec;
+
+ if (pd->source && efl_isa(pd->source, EFL_IO_CLOSER_MIXIN))
+ efl_io_closer_close_on_exec_set(pd->source, close_on_exec);
+
+ if (pd->destination && efl_isa(pd->destination, EFL_IO_CLOSER_MIXIN))
+ efl_io_closer_close_on_exec_set(pd->destination, close_on_exec);
+
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_io_copier_efl_io_closer_close_on_exec_get(Eo *o EINA_UNUSED, Efl_Io_Copier_Data *pd)
+{
+ return pd->close_on_exec;
+}
+
+EOLIAN static void
+_efl_io_copier_efl_io_closer_close_on_destructor_set(Eo *o EINA_UNUSED, Efl_Io_Copier_Data *pd, Eina_Bool close_on_destructor)
+{
+ if (pd->close_on_destructor == close_on_destructor) return;
+ pd->close_on_destructor = close_on_destructor;
+
+ if (pd->source && efl_isa(pd->source, EFL_IO_CLOSER_MIXIN))
+ efl_io_closer_close_on_destructor_set(pd->source, close_on_destructor);
+
+ if (pd->destination && efl_isa(pd->destination, EFL_IO_CLOSER_MIXIN))
+ efl_io_closer_close_on_destructor_set(pd->destination, close_on_destructor);
+}
+
+EOLIAN static Eina_Bool
+_efl_io_copier_efl_io_closer_close_on_destructor_get(Eo *o EINA_UNUSED, Efl_Io_Copier_Data *pd)
+{
+ return pd->close_on_destructor;
+}
+
#include "efl_io_copier.eo.c"
If @Efl.Io.Closer.close is called, then it will be called on
@.source and @.destination if they implement those interfaces.
+ @Efl.Io.Closer.close_on_exec and
+ @Efl.Io.Closer.close_on_destructor are respected and applied to
+ both source and destination. Both default to $true.
+
@since 1.19
]]
Efl.Object.finalize;
Efl.Io.Closer.close;
Efl.Io.Closer.closed.get;
+ Efl.Io.Closer.close_on_exec;
+ Efl.Io.Closer.close_on_destructor;
}
}
EOLIAN static void
_efl_io_file_flags_set(Eo *o, Efl_Io_File_Data *pd, uint32_t flags)
{
+ Eina_Bool close_on_exec;
+
EINA_SAFETY_ON_TRUE_RETURN(efl_finalized_get(o));
+
pd->flags = flags;
+
+ close_on_exec = !!(flags & O_CLOEXEC);
+ if (close_on_exec != efl_io_closer_close_on_exec_get(o))
+ efl_io_closer_close_on_exec_set(o, close_on_exec);
}
EOLIAN static uint32_t
return pd->mode;
}
+EOLIAN static Eo *
+_efl_io_file_efl_object_constructor(Eo *o, Efl_Io_File_Data *pd)
+{
+ pd->flags = O_RDONLY | O_CLOEXEC;
+
+ o = efl_constructor(efl_super(o, MY_CLASS));
+
+ efl_io_closer_close_on_exec_set(o, EINA_TRUE);
+ efl_io_closer_close_on_destructor_set(o, EINA_TRUE);
+
+ return o;
+}
+
EOLIAN static void
_efl_io_file_efl_object_destructor(Eo *o, Efl_Io_File_Data *pd)
{
- if (!efl_io_closer_closed_get(o))
+ if (efl_io_closer_close_on_destructor_get(o) &&
+ (!efl_io_closer_closed_get(o)))
efl_io_closer_close(o);
efl_destructor(efl_super(o, MY_CLASS));
return 0;
}
+EOLIAN static Eina_Bool
+_efl_io_file_efl_io_closer_close_on_exec_set(Eo *o, Efl_Io_File_Data *pd, Eina_Bool close_on_exec)
+{
+ if (close_on_exec)
+ pd->flags |= O_CLOEXEC;
+ else
+ pd->flags &= (~O_CLOEXEC);
+
+ return efl_io_closer_close_on_exec_set(efl_super(o, MY_CLASS), close_on_exec);
+}
+
#include "efl_io_file.eo.c"
class Efl.Io.File (Efl.Loop.Fd, Efl.File, Efl.Io.Reader.Fd, Efl.Io.Writer.Fd, Efl.Io.Closer.Fd, Efl.Io.Sizer.Fd, Efl.Io.Positioner.Fd) {
[[File access (open, close, read, write, lseek, ftruncate)
- Files are closed automatically (@Efl.Io.Closer.Fd) on destruction.
+ @Efl.Io.Closer.close_on_exec and
+ @Efl.Io.Closer.close_on_destructor are respected and default to
+ $true. @Efl.Io.Closer.close_on_exec.set sets flag O_CLOEXEC.
@since 1.19
]]
methods {
@property flags {
- [[bitwise OR'ed flags to open the file, like O_CREAT, O_CLOEXEC...]]
+ [[bitwise OR'ed flags to open the file, like O_CREAT, O_APPEND...
+
+ Defaults to O_RDONLY | O_CLOEXEC.
+
+ The flag O_CLOEXEC will be also managed by
+ @Efl.Io.Closer.close_on_exec.set. Setting the property
+ after the file is opened will change its blocking
+ behavior.
+ ]]
get {
}
}
implements {
+ Efl.Object.constructor;
Efl.Object.destructor;
Efl.Object.finalize;
Efl.Loop.Fd.fd_file.set;
Efl.Io.Reader.read;
Efl.Io.Writer.write;
Efl.Io.Closer.close;
+ Efl.Io.Closer.close_on_exec.set;
Efl.Io.Sizer.resize;
Efl.Io.Positioner.seek;
}
#include "ecore_con_url_curl.h"
#include <ctype.h>
+#include <fcntl.h>
/* improve usage of lazy-loaded library in _c-> */
#define curl_easy_strerror(...) _c->curl_easy_strerror(__VA_ARGS__)
uint8_t pause;
Eina_Bool connected;
Eina_Bool closed;
+ Eina_Bool close_on_exec;
+ Eina_Bool close_on_destructor;
Eina_Bool eos;
Eina_Bool can_read;
Eina_Bool can_write;
Eo *o = data;
Efl_Net_Dialer_Http_Data *pd = efl_data_scope_get(o, MY_CLASS);
- pd->fd = socket(addr->family, addr->socktype, addr->protocol);
+ pd->fd = efl_net_socket4(addr->family, addr->socktype, addr->protocol, pd->close_on_exec);
if (pd->fd < 0)
ERR("could not create curl socket family=%d, type=%d, protocol=%d",
addr->family, addr->socktype, addr->protocol);
pd->pending_close = NULL;
efl_io_closer_close(o);
}
- else if (!efl_io_closer_closed_get(o))
+ else if (efl_io_closer_close_on_destructor_get(o) &&
+ (!efl_io_closer_closed_get(o)))
efl_io_closer_close(o);
efl_net_dialer_http_response_headers_clear(o);
return pd->closed || (!!pd->pending_close);
}
+EOLIAN static Eina_Bool
+_efl_net_dialer_http_efl_io_closer_close_on_exec_set(Eo *o EINA_UNUSED, Efl_Net_Dialer_Http_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;
+ Eina_Bool old = pd->close_on_exec;
+
+ pd->close_on_exec = close_on_exec;
+
+ if (pd->fd < 0) return EINA_TRUE; /* postpone until _efl_net_dialer_http_socket_open */
+
+ flags = fcntl(pd->fd, F_GETFD);
+ if (flags < 0)
+ {
+ ERR("fcntl(%d, F_GETFD): %s", pd->fd, strerror(errno));
+ pd->close_on_exec = old;
+ return EINA_FALSE;
+ }
+ if (close_on_exec)
+ flags |= FD_CLOEXEC;
+ else
+ flags &= (~FD_CLOEXEC);
+ if (fcntl(pd->fd, F_SETFD, flags) < 0)
+ {
+ ERR("fcntl(%d, F_SETFD, %#x): %s", pd->fd, flags, strerror(errno));
+ pd->close_on_exec = old;
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+#endif
+}
+
+EOLIAN static Eina_Bool
+_efl_net_dialer_http_efl_io_closer_close_on_exec_get(Eo *o EINA_UNUSED, Efl_Net_Dialer_Http_Data *pd)
+{
+ return pd->close_on_exec;
+}
+
+EOLIAN static void
+_efl_net_dialer_http_efl_io_closer_close_on_destructor_set(Eo *o EINA_UNUSED, Efl_Net_Dialer_Http_Data *pd, Eina_Bool close_on_destructor)
+{
+ pd->close_on_destructor = close_on_destructor;
+}
+
+EOLIAN static Eina_Bool
+_efl_net_dialer_http_efl_io_closer_close_on_destructor_get(Eo *o EINA_UNUSED, Efl_Net_Dialer_Http_Data *pd)
+{
+ return pd->close_on_destructor;
+}
+
EOLIAN static Eina_Error
_efl_net_dialer_http_efl_io_sizer_resize(Eo *o, Efl_Net_Dialer_Http_Data *pd, uint64_t size)
{
Efl.Io.Writer.can_write.set;
Efl.Io.Closer.close;
Efl.Io.Closer.closed.get;
+ Efl.Io.Closer.close_on_exec;
+ Efl.Io.Closer.close_on_destructor;
Efl.Io.Sizer.resize;
Efl.Io.Sizer.size.get;
}
EOLIAN static void
_efl_net_dialer_tcp_efl_object_destructor(Eo *o, Efl_Net_Dialer_Tcp_Data *pd)
{
+ if (efl_io_closer_close_on_destructor_get(o) &&
+ (!efl_io_closer_closed_get(o)))
+ efl_io_closer_close(o);
+
if (pd->connect.thread)
{
ecore_thread_cancel(pd->connect.thread);
addrinfo->ai_addrlen,
SOCK_STREAM,
IPPROTO_TCP,
- efl_net_socket_fd_close_on_exec_get(o),
+ efl_io_closer_close_on_exec_get(o),
_efl_net_dialer_tcp_connected,
o);
}
addrinfo->ai_addrlen,
SOCK_STREAM,
IPPROTO_TCP,
- efl_net_socket_fd_close_on_exec_get(o),
+ efl_io_closer_close_on_exec_get(o),
_efl_net_dialer_tcp_connected,
o);
end:
pd->close_timer = NULL;
}
- if (!efl_io_closer_closed_get(pd->http))
- efl_io_closer_close(pd->http);
efl_del(pd->http);
pd->http = NULL;
return pd->close_requested || efl_io_closer_closed_get(pd->http);
}
+EOLIAN static Eina_Bool
+_efl_net_dialer_websocket_efl_io_closer_close_on_exec_set(Eo *o EINA_UNUSED, Efl_Net_Dialer_Websocket_Data *pd, Eina_Bool close_on_exec)
+{
+ return efl_io_closer_close_on_exec_set(pd->http, close_on_exec);
+}
+
+EOLIAN static Eina_Bool
+_efl_net_dialer_websocket_efl_io_closer_close_on_exec_get(Eo *o EINA_UNUSED, Efl_Net_Dialer_Websocket_Data *pd)
+{
+ return efl_io_closer_close_on_exec_get(pd->http);
+}
+
+EOLIAN static void
+_efl_net_dialer_websocket_efl_io_closer_close_on_destructor_set(Eo *o EINA_UNUSED, Efl_Net_Dialer_Websocket_Data *pd, Eina_Bool close_on_destructor)
+{
+ efl_io_closer_close_on_destructor_set(pd->http, close_on_destructor);
+}
+
+EOLIAN static Eina_Bool
+_efl_net_dialer_websocket_efl_io_closer_close_on_destructor_get(Eo *o EINA_UNUSED, Efl_Net_Dialer_Websocket_Data *pd)
+{
+ return efl_io_closer_close_on_destructor_get(pd->http);
+}
+
EOLIAN static void
_efl_net_dialer_websocket_streaming_mode_set(Eo *o, Efl_Net_Dialer_Websocket_Data *pd, Efl_Net_Dialer_Websocket_Streaming_Mode streaming_mode)
{
Efl.Io.Writer.can_write.set;
Efl.Io.Closer.close;
Efl.Io.Closer.closed.get;
+ Efl.Io.Closer.close_on_exec;
+ Efl.Io.Closer.close_on_destructor;
}
}
Children socket will inherit the server's setting by
default. One can change the behavior using each instance
- @Efl.Net.Socket.Fd.close_on_exec.set.
+ @Efl.Io.Closer.close_on_exec.set.
]]
get { }
set {
{
Eo *client = efl_add(EFL_NET_SOCKET_TCP_CLASS, o,
efl_event_callback_array_add(efl_added, _efl_net_server_tcp_client_cbs(), o),
+ efl_io_closer_close_on_exec_set(efl_added, efl_net_server_fd_close_on_exec_get(o)),
+ efl_io_closer_close_on_destructor_set(efl_added, EINA_TRUE),
efl_loop_fd_set(efl_added, client_fd));
if (!client)
{
{
DBG("client %s was not handled, closing it...",
efl_net_socket_address_remote_get(client));
- efl_io_closer_close(client);
+ efl_del(client);
}
}
Eina_Stringshare *address_local;
Eina_Stringshare *address_remote;
int family;
- Eina_Bool close_on_exec;
} Efl_Net_Socket_Fd_Data;
static void
_efl_net_socket_fd_efl_object_constructor(Eo *o, Efl_Net_Socket_Fd_Data *pd EINA_UNUSED)
{
pd->family = AF_UNSPEC;
- return efl_constructor(efl_super(o, MY_CLASS));
+ o = efl_constructor(efl_super(o, MY_CLASS));
+
+ efl_io_closer_close_on_exec_set(o, EINA_TRUE);
+ efl_io_closer_close_on_destructor_set(o, EINA_TRUE);
+
+ return o;
}
EOLIAN static void
_efl_net_socket_fd_efl_object_destructor(Eo *o, Efl_Net_Socket_Fd_Data *pd)
{
+ if (efl_io_closer_close_on_destructor_get(o) &&
+ (!efl_io_closer_closed_get(o)))
+ efl_io_closer_close(o);
+
efl_destructor(efl_super(o, MY_CLASS));
eina_stringshare_replace(&pd->address_local, NULL);
static void
_efl_net_socket_fd_set(Eo *o, Efl_Net_Socket_Fd_Data *pd, int fd)
{
+ Eina_Bool close_on_exec = efl_io_closer_close_on_exec_get(o); /* get cached value, otherwise will query from set fd */
efl_io_reader_fd_reader_fd_set(o, fd);
efl_io_writer_fd_writer_fd_set(o, fd);
efl_io_closer_fd_closer_fd_set(o, fd);
/* apply postponed values */
- efl_net_socket_fd_close_on_exec_set(o, pd->close_on_exec);
+ efl_io_closer_close_on_exec_set(o, close_on_exec);
if (pd->family == AF_UNSPEC)
{
ERR("efl_loop_fd_set() must be called after efl_net_server_fd_family_set()");
return pd->address_remote;
}
-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;
-
- fd = efl_loop_fd_get(o);
- if (fd < 0) return EINA_TRUE; /* postpone until fd_set() */
-
- flags = fcntl(fd, F_GETFD);
- if (flags < 0)
- {
- ERR("fcntl(%d, F_GETFD): %s", fd, strerror(errno));
- return EINA_FALSE;
- }
- if (close_on_exec)
- flags |= FD_CLOEXEC;
- else
- flags &= (~FD_CLOEXEC);
- if (fcntl(fd, F_SETFD, flags) < 0)
- {
- ERR("fcntl(%d, F_SETFD, %#x): %s", fd, flags, strerror(errno));
- return EINA_FALSE;
- }
-
- 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);
- if (fd < 0) return pd->close_on_exec;
-
- /* if there is a fd, always query it directly as it may be modified
- * elsewhere by nasty users.
- */
- flags = fcntl(fd, F_GETFD);
- if (flags < 0)
- {
- ERR("fcntl(%d, F_GETFD): %s", fd, strerror(errno));
- return EINA_FALSE;
- }
-
- pd->close_on_exec = !!(flags & FD_CLOEXEC); /* sync */
- return pd->close_on_exec;
-#endif
-}
-
EOLIAN static void
_efl_net_socket_fd_family_set(Eo *o EINA_UNUSED, Efl_Net_Socket_Fd_Data *pd, int family)
{
This is the common class and takes an existing FD, usually
created by an dialer or server.
+ @Efl.Io.Closer.close_on_exec and
+ @Efl.Io.Closer.close_on_destructor are respected and default to
+ $true.
+
@since 1.19
]]
family: int;
}
}
-
- @property close_on_exec {
- [[Controls Close-on-Exec() using FD_CLOEXEC]]
- get { }
- set {
- return: bool (false); [[$true on success]]
- }
- values {
- close_on_exec: bool;
- }
- }
}
implements {
return pd->closed;
}
+EOLIAN static Eina_Bool
+_efl_io_buffer_efl_io_closer_close_on_exec_set(Eo *o EINA_UNUSED, Efl_Io_Buffer_Data *pd EINA_UNUSED, Eina_Bool close_on_exec)
+{
+ if (!close_on_exec) return EINA_FALSE;
+
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_io_buffer_efl_io_closer_close_on_exec_get(Eo *o EINA_UNUSED, Efl_Io_Buffer_Data *pd EINA_UNUSED)
+{
+ return EINA_TRUE;
+}
+
+EOLIAN static void
+_efl_io_buffer_efl_io_closer_close_on_destructor_set(Eo *o EINA_UNUSED, Efl_Io_Buffer_Data *pd EINA_UNUSED, Eina_Bool close_on_destructor EINA_UNUSED)
+{
+}
+
+EOLIAN static Eina_Bool
+_efl_io_buffer_efl_io_closer_close_on_destructor_get(Eo *o EINA_UNUSED, Efl_Io_Buffer_Data *pd EINA_UNUSED)
+{
+ return EINA_TRUE;
+}
+
EOLIAN static Eina_Error
_efl_io_buffer_efl_io_sizer_resize(Eo *o, Efl_Io_Buffer_Data *pd, uint64_t size)
{
Efl.Io.Writer.can_write.set;
Efl.Io.Closer.close;
Efl.Io.Closer.closed.get;
+ Efl.Io.Closer.close_on_exec;
+ Efl.Io.Closer.close_on_destructor;
Efl.Io.Sizer.resize;
Efl.Io.Sizer.size.get;
Efl.Io.Positioner.seek;
is_closed: bool;
}
}
+
+ @property close_on_exec {
+ [[If true will automatically close resources on exec() calls.
+
+ When using file descriptors this should set FD_CLOEXEC
+ so they are not inherited by the processes (children or
+ self) doing exec().
+ ]]
+ get @virtual_pure { }
+ set @virtual_pure {
+ [[If true, will close on exec() call.]]
+ return: bool; [[$true if could set, $false if not supported or failed.]]
+ }
+ values {
+ close_on_exec: bool;
+ }
+ }
+
+ @property close_on_destructor {
+ [[If true will automatically close() on object destructor.
+
+ If the object was deleted without close, this property
+ will state whenever it should be closed or not.
+ ]]
+ get @virtual_pure { }
+ set @virtual_pure { }
+ values {
+ close_on_destructor: bool;
+ }
+ }
}
events {
return pd->closed;
}
+EOLIAN static Eina_Bool
+_efl_io_queue_efl_io_closer_close_on_exec_set(Eo *o EINA_UNUSED, Efl_Io_Queue_Data *pd EINA_UNUSED, Eina_Bool close_on_exec)
+{
+ if (!close_on_exec) return EINA_FALSE;
+
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_io_queue_efl_io_closer_close_on_exec_get(Eo *o EINA_UNUSED, Efl_Io_Queue_Data *pd EINA_UNUSED)
+{
+ return EINA_TRUE;
+}
+
+EOLIAN static void
+_efl_io_queue_efl_io_closer_close_on_destructor_set(Eo *o EINA_UNUSED, Efl_Io_Queue_Data *pd EINA_UNUSED, Eina_Bool close_on_destructor EINA_UNUSED)
+{
+}
+
+EOLIAN static Eina_Bool
+_efl_io_queue_efl_io_closer_close_on_destructor_get(Eo *o EINA_UNUSED, Efl_Io_Queue_Data *pd EINA_UNUSED)
+{
+ return EINA_TRUE;
+}
+
#include "interfaces/efl_io_queue.eo.c"
Efl.Io.Writer.can_write.set;
Efl.Io.Closer.close;
Efl.Io.Closer.closed.get;
+ Efl.Io.Closer.close_on_exec;
+ Efl.Io.Closer.close_on_destructor;
}
}