forked from enlightenment/efl
efl_io_closer: add close_on_exec and close_on_destructor properties.
the purpose of these properties are to make it more uniform the handling of these auto-close behavior.
This commit is contained in:
parent
7c2671b1f7
commit
ea7bc821d5
|
@ -58,8 +58,7 @@ _echo_copier_done(void *data EINA_UNUSED, const Efl_Event *event)
|
|||
{
|
||||
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
|
||||
|
@ -73,7 +72,6 @@ _echo_copier_error(void *data EINA_UNUSED, const Efl_Event *event)
|
|||
fprintf(stderr, "ERROR: echo copier %p failed %d, close and del.\n",
|
||||
copier, *perr);
|
||||
|
||||
efl_io_closer_close(copier);
|
||||
efl_del(copier);
|
||||
}
|
||||
|
||||
|
@ -123,7 +121,7 @@ _send_recv_done(Send_Recv_Data *d, Eo *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);
|
||||
}
|
||||
|
||||
|
@ -305,7 +303,8 @@ _server_client_add(void *data EINA_UNUSED, const Efl_Event *event)
|
|||
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",
|
||||
|
@ -346,7 +345,8 @@ _server_client_add(void *data EINA_UNUSED, const Efl_Event *event)
|
|||
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",
|
||||
|
@ -361,7 +361,8 @@ _server_client_add(void *data EINA_UNUSED, const Efl_Event *event)
|
|||
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",
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#endif
|
||||
|
||||
#include <Ecore.h>
|
||||
#include <fcntl.h>
|
||||
#include "ecore_private.h"
|
||||
|
||||
#define MY_CLASS EFL_IO_CLOSER_FD_CLASS
|
||||
|
@ -12,6 +13,8 @@
|
|||
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
|
||||
|
@ -46,4 +49,83 @@ _efl_io_closer_fd_efl_io_closer_closed_get(Eo *o, Efl_Io_Closer_Fd_Data *pd EINA
|
|||
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"
|
||||
|
|
|
@ -17,5 +17,7 @@ mixin Efl.Io.Closer.Fd (Efl.Io.Closer) {
|
|||
implements {
|
||||
Efl.Io.Closer.close;
|
||||
Efl.Io.Closer.closed.get;
|
||||
Efl.Io.Closer.close_on_exec;
|
||||
Efl.Io.Closer.close_on_destructor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ typedef struct _Efl_Io_Copier_Data
|
|||
} 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);
|
||||
|
@ -394,6 +396,8 @@ _efl_io_copier_source_set(Eo *o, Efl_Io_Copier_Data *pd, Efl_Io_Reader *source)
|
|||
|
||||
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);
|
||||
}
|
||||
|
@ -471,6 +475,8 @@ _efl_io_copier_destination_set(Eo *o, Efl_Io_Copier_Data *pd, Efl_Io_Writer *des
|
|||
|
||||
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);
|
||||
}
|
||||
|
@ -648,6 +654,8 @@ EOLIAN static Eo *
|
|||
_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);
|
||||
|
||||
|
@ -680,6 +688,10 @@ _efl_io_copier_efl_object_destructor(Eo *o, Efl_Io_Copier_Data *pd)
|
|||
{
|
||||
_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);
|
||||
|
||||
|
@ -712,4 +724,44 @@ _efl_io_copier_efl_object_destructor(Eo *o, Efl_Io_Copier_Data *pd)
|
|||
}
|
||||
}
|
||||
|
||||
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"
|
||||
|
|
|
@ -15,6 +15,10 @@ class Efl.Io.Copier (Efl.Loop_User, Efl.Io.Closer) {
|
|||
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
|
||||
]]
|
||||
|
||||
|
@ -108,5 +112,7 @@ class Efl.Io.Copier (Efl.Loop_User, Efl.Io.Closer) {
|
|||
Efl.Object.finalize;
|
||||
Efl.Io.Closer.close;
|
||||
Efl.Io.Closer.closed.get;
|
||||
Efl.Io.Closer.close_on_exec;
|
||||
Efl.Io.Closer.close_on_destructor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,8 +65,15 @@ _efl_io_file_efl_loop_fd_fd_file_set(Eo *o, Efl_Io_File_Data *pd, int fd)
|
|||
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
|
||||
|
@ -88,10 +95,24 @@ _efl_io_file_mode_get(Eo *o EINA_UNUSED, Efl_Io_File_Data *pd)
|
|||
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));
|
||||
|
@ -192,4 +213,15 @@ _efl_io_file_efl_io_positioner_seek(Eo *o, Efl_Io_File_Data *pd, int64_t offset,
|
|||
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"
|
||||
|
|
|
@ -1,14 +1,24 @@
|
|||
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 {
|
||||
}
|
||||
|
||||
|
@ -36,6 +46,7 @@ class Efl.Io.File (Efl.Loop.Fd, Efl.File, Efl.Io.Reader.Fd, Efl.Io.Writer.Fd, Ef
|
|||
}
|
||||
|
||||
implements {
|
||||
Efl.Object.constructor;
|
||||
Efl.Object.destructor;
|
||||
Efl.Object.finalize;
|
||||
Efl.Loop.Fd.fd_file.set;
|
||||
|
@ -43,6 +54,7 @@ class Efl.Io.File (Efl.Loop.Fd, Efl.File, Efl.Io.Reader.Fd, Efl.Io.Writer.Fd, Ef
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#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__)
|
||||
|
@ -210,6 +211,8 @@ typedef struct
|
|||
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;
|
||||
|
@ -1096,7 +1099,7 @@ _efl_net_dialer_http_socket_open(void *data, curlsocktype purpose EINA_UNUSED, s
|
|||
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);
|
||||
|
@ -1192,7 +1195,8 @@ _efl_net_dialer_http_efl_object_destructor(Eo *o, Efl_Net_Dialer_Http_Data *pd)
|
|||
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);
|
||||
|
@ -1597,6 +1601,61 @@ _efl_net_dialer_http_efl_io_closer_closed_get(Eo *o EINA_UNUSED, Efl_Net_Dialer_
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -342,6 +342,8 @@ class Efl.Net.Dialer.Http (Efl.Loop_User, Efl.Net.Dialer, Efl.Io.Sizer) {
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,10 @@ typedef struct _Efl_Net_Dialer_Tcp_Data
|
|||
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);
|
||||
|
@ -115,7 +119,7 @@ _efl_net_dialer_tcp_connected(void *data, const struct sockaddr *addr EINA_UNUSE
|
|||
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);
|
||||
}
|
||||
|
@ -148,7 +152,7 @@ _efl_net_dialer_tcp_connect(Eo *o, Efl_Net_Dialer_Tcp_Data *pd)
|
|||
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:
|
||||
|
|
|
@ -953,8 +953,6 @@ _efl_net_dialer_websocket_efl_object_destructor(Eo *o, Efl_Net_Dialer_Websocket_
|
|||
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;
|
||||
|
||||
|
@ -1355,6 +1353,30 @@ _efl_net_dialer_websocket_efl_io_closer_closed_get(Eo *o EINA_UNUSED, Efl_Net_Di
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -305,5 +305,7 @@ class Efl.Net.Dialer.Websocket (Efl.Loop_User, Efl.Net.Dialer) {
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ class Efl.Net.Server.Fd (Efl.Loop.Fd, Efl.Net.Server) {
|
|||
|
||||
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 {
|
||||
|
|
|
@ -162,6 +162,8 @@ _efl_net_server_tcp_efl_net_server_fd_client_add(Eo *o, void *pd EINA_UNUSED, in
|
|||
{
|
||||
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)
|
||||
{
|
||||
|
@ -177,7 +179,7 @@ _efl_net_server_tcp_efl_net_server_fd_client_add(Eo *o, void *pd EINA_UNUSED, in
|
|||
{
|
||||
DBG("client %s was not handled, closing it...",
|
||||
efl_net_socket_address_remote_get(client));
|
||||
efl_io_closer_close(client);
|
||||
efl_del(client);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ typedef struct _Efl_Net_Socket_Fd_Data
|
|||
Eina_Stringshare *address_local;
|
||||
Eina_Stringshare *address_remote;
|
||||
int family;
|
||||
Eina_Bool close_on_exec;
|
||||
} Efl_Net_Socket_Fd_Data;
|
||||
|
||||
static void
|
||||
|
@ -73,12 +72,21 @@ EOLIAN static Efl_Object *
|
|||
_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);
|
||||
|
@ -88,12 +96,13 @@ _efl_net_socket_fd_efl_object_destructor(Eo *o, Efl_Net_Socket_Fd_Data *pd)
|
|||
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()");
|
||||
|
@ -261,68 +270,6 @@ _efl_net_socket_fd_efl_net_socket_address_remote_get(Eo *o EINA_UNUSED, Efl_Net_
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -4,6 +4,10 @@ class Efl.Net.Socket.Fd (Efl.Loop.Fd, Efl.Io.Reader.Fd, Efl.Io.Writer.Fd, Efl.Io
|
|||
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
|
||||
]]
|
||||
|
||||
|
@ -23,17 +27,6 @@ class Efl.Net.Socket.Fd (Efl.Loop.Fd, Efl.Io.Reader.Fd, Efl.Io.Writer.Fd, Efl.Io
|
|||
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 {
|
||||
|
|
|
@ -317,6 +317,31 @@ _efl_io_buffer_efl_io_closer_closed_get(Eo *o EINA_UNUSED, Efl_Io_Buffer_Data *p
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -119,6 +119,8 @@ class Efl.Io.Buffer (Efl.Object, Efl.Io.Reader, Efl.Io.Writer, Efl.Io.Closer, Ef
|
|||
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;
|
||||
|
|
|
@ -41,6 +41,36 @@ mixin Efl.Io.Closer {
|
|||
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 {
|
||||
|
|
|
@ -427,4 +427,29 @@ _efl_io_queue_efl_io_closer_closed_get(Eo *o EINA_UNUSED, Efl_Io_Queue_Data *pd)
|
|||
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"
|
||||
|
|
|
@ -90,5 +90,7 @@ class Efl.Io.Queue (Efl.Object, Efl.Io.Reader, Efl.Io.Writer, Efl.Io.Closer) {
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue