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;
|
Eo *copier = event->object;
|
||||||
fprintf(stderr, "INFO: echo copier done, close and del %p\n", copier);
|
fprintf(stderr, "INFO: echo copier done, close and del %p\n", copier);
|
||||||
efl_io_closer_close(copier);
|
efl_del(copier); /* set to close_on_destructor, will auto close copier and client */
|
||||||
efl_del(copier);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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",
|
fprintf(stderr, "ERROR: echo copier %p failed %d, close and del.\n",
|
||||||
copier, *perr);
|
copier, *perr);
|
||||||
|
|
||||||
efl_io_closer_close(copier);
|
|
||||||
efl_del(copier);
|
efl_del(copier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +121,7 @@ _send_recv_done(Send_Recv_Data *d, Eo *copier)
|
||||||
|
|
||||||
efl_del(copier);
|
efl_del(copier);
|
||||||
if (d->send_copier || d->recv_copier) return;
|
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);
|
_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),
|
Eo *echo_copier = efl_add(EFL_IO_COPIER_CLASS, efl_parent_get(client),
|
||||||
efl_io_copier_source_set(efl_added, client),
|
efl_io_copier_source_set(efl_added, client),
|
||||||
efl_io_copier_destination_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",
|
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),
|
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_source_set(efl_added, send_buffer),
|
||||||
efl_io_copier_destination_set(efl_added, client),
|
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",
|
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),
|
d->recv_copier = efl_add(EFL_IO_COPIER_CLASS, efl_parent_get(client),
|
||||||
efl_io_copier_source_set(efl_added, client),
|
efl_io_copier_source_set(efl_added, client),
|
||||||
efl_io_copier_destination_set(efl_added, recv_buffer),
|
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",
|
fprintf(stderr, "INFO: using receiver buffer %p with copier %p for client %s\n",
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <Ecore.h>
|
#include <Ecore.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include "ecore_private.h"
|
#include "ecore_private.h"
|
||||||
|
|
||||||
#define MY_CLASS EFL_IO_CLOSER_FD_CLASS
|
#define MY_CLASS EFL_IO_CLOSER_FD_CLASS
|
||||||
|
@ -12,6 +13,8 @@
|
||||||
typedef struct _Efl_Io_Closer_Fd_Data
|
typedef struct _Efl_Io_Closer_Fd_Data
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
Eina_Bool close_on_exec;
|
||||||
|
Eina_Bool close_on_destructor;
|
||||||
} Efl_Io_Closer_Fd_Data;
|
} Efl_Io_Closer_Fd_Data;
|
||||||
|
|
||||||
EOLIAN static void
|
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;
|
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"
|
#include "efl_io_closer_fd.eo.c"
|
||||||
|
|
|
@ -17,5 +17,7 @@ mixin Efl.Io.Closer.Fd (Efl.Io.Closer) {
|
||||||
implements {
|
implements {
|
||||||
Efl.Io.Closer.close;
|
Efl.Io.Closer.close;
|
||||||
Efl.Io.Closer.closed.get;
|
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;
|
} progress;
|
||||||
Eina_Bool closed;
|
Eina_Bool closed;
|
||||||
Eina_Bool done;
|
Eina_Bool done;
|
||||||
|
Eina_Bool close_on_exec;
|
||||||
|
Eina_Bool close_on_destructor;
|
||||||
} Efl_Io_Copier_Data;
|
} Efl_Io_Copier_Data;
|
||||||
|
|
||||||
static void _efl_io_copier_write(Eo *o, Efl_Io_Copier_Data *pd);
|
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))
|
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_event_callback_add(pd->source, EFL_IO_CLOSER_EVENT_CLOSED,
|
||||||
_efl_io_copier_source_closed, o);
|
_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))
|
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_event_callback_add(pd->destination, EFL_IO_CLOSER_EVENT_CLOSED,
|
||||||
_efl_io_copier_destination_closed, o);
|
_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)
|
_efl_io_copier_efl_object_constructor(Eo *o, Efl_Io_Copier_Data *pd)
|
||||||
{
|
{
|
||||||
pd->buf = eina_binbuf_new();
|
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);
|
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);
|
_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_source_set(o, NULL);
|
||||||
efl_io_copier_destination_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"
|
#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
|
If @Efl.Io.Closer.close is called, then it will be called on
|
||||||
@.source and @.destination if they implement those interfaces.
|
@.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
|
@since 1.19
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
@ -108,5 +112,7 @@ class Efl.Io.Copier (Efl.Loop_User, Efl.Io.Closer) {
|
||||||
Efl.Object.finalize;
|
Efl.Object.finalize;
|
||||||
Efl.Io.Closer.close;
|
Efl.Io.Closer.close;
|
||||||
Efl.Io.Closer.closed.get;
|
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
|
EOLIAN static void
|
||||||
_efl_io_file_flags_set(Eo *o, Efl_Io_File_Data *pd, uint32_t flags)
|
_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));
|
EINA_SAFETY_ON_TRUE_RETURN(efl_finalized_get(o));
|
||||||
|
|
||||||
pd->flags = flags;
|
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
|
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;
|
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
|
EOLIAN static void
|
||||||
_efl_io_file_efl_object_destructor(Eo *o, Efl_Io_File_Data *pd)
|
_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_io_closer_close(o);
|
||||||
|
|
||||||
efl_destructor(efl_super(o, MY_CLASS));
|
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;
|
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"
|
#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) {
|
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)
|
[[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
|
@since 1.19
|
||||||
]]
|
]]
|
||||||
|
|
||||||
methods {
|
methods {
|
||||||
@property flags {
|
@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 {
|
get {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +46,7 @@ class Efl.Io.File (Efl.Loop.Fd, Efl.File, Efl.Io.Reader.Fd, Efl.Io.Writer.Fd, Ef
|
||||||
}
|
}
|
||||||
|
|
||||||
implements {
|
implements {
|
||||||
|
Efl.Object.constructor;
|
||||||
Efl.Object.destructor;
|
Efl.Object.destructor;
|
||||||
Efl.Object.finalize;
|
Efl.Object.finalize;
|
||||||
Efl.Loop.Fd.fd_file.set;
|
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.Reader.read;
|
||||||
Efl.Io.Writer.write;
|
Efl.Io.Writer.write;
|
||||||
Efl.Io.Closer.close;
|
Efl.Io.Closer.close;
|
||||||
|
Efl.Io.Closer.close_on_exec.set;
|
||||||
Efl.Io.Sizer.resize;
|
Efl.Io.Sizer.resize;
|
||||||
Efl.Io.Positioner.seek;
|
Efl.Io.Positioner.seek;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "ecore_con_url_curl.h"
|
#include "ecore_con_url_curl.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
/* improve usage of lazy-loaded library in _c-> */
|
/* improve usage of lazy-loaded library in _c-> */
|
||||||
#define curl_easy_strerror(...) _c->curl_easy_strerror(__VA_ARGS__)
|
#define curl_easy_strerror(...) _c->curl_easy_strerror(__VA_ARGS__)
|
||||||
|
@ -210,6 +211,8 @@ typedef struct
|
||||||
uint8_t pause;
|
uint8_t pause;
|
||||||
Eina_Bool connected;
|
Eina_Bool connected;
|
||||||
Eina_Bool closed;
|
Eina_Bool closed;
|
||||||
|
Eina_Bool close_on_exec;
|
||||||
|
Eina_Bool close_on_destructor;
|
||||||
Eina_Bool eos;
|
Eina_Bool eos;
|
||||||
Eina_Bool can_read;
|
Eina_Bool can_read;
|
||||||
Eina_Bool can_write;
|
Eina_Bool can_write;
|
||||||
|
@ -1096,7 +1099,7 @@ _efl_net_dialer_http_socket_open(void *data, curlsocktype purpose EINA_UNUSED, s
|
||||||
Eo *o = data;
|
Eo *o = data;
|
||||||
Efl_Net_Dialer_Http_Data *pd = efl_data_scope_get(o, MY_CLASS);
|
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)
|
if (pd->fd < 0)
|
||||||
ERR("could not create curl socket family=%d, type=%d, protocol=%d",
|
ERR("could not create curl socket family=%d, type=%d, protocol=%d",
|
||||||
addr->family, addr->socktype, addr->protocol);
|
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;
|
pd->pending_close = NULL;
|
||||||
efl_io_closer_close(o);
|
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_io_closer_close(o);
|
||||||
|
|
||||||
efl_net_dialer_http_response_headers_clear(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);
|
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
|
EOLIAN static Eina_Error
|
||||||
_efl_net_dialer_http_efl_io_sizer_resize(Eo *o, Efl_Net_Dialer_Http_Data *pd, uint64_t size)
|
_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.Writer.can_write.set;
|
||||||
Efl.Io.Closer.close;
|
Efl.Io.Closer.close;
|
||||||
Efl.Io.Closer.closed.get;
|
Efl.Io.Closer.closed.get;
|
||||||
|
Efl.Io.Closer.close_on_exec;
|
||||||
|
Efl.Io.Closer.close_on_destructor;
|
||||||
Efl.Io.Sizer.resize;
|
Efl.Io.Sizer.resize;
|
||||||
Efl.Io.Sizer.size.get;
|
Efl.Io.Sizer.size.get;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,10 @@ typedef struct _Efl_Net_Dialer_Tcp_Data
|
||||||
EOLIAN static void
|
EOLIAN static void
|
||||||
_efl_net_dialer_tcp_efl_object_destructor(Eo *o, Efl_Net_Dialer_Tcp_Data *pd)
|
_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)
|
if (pd->connect.thread)
|
||||||
{
|
{
|
||||||
ecore_thread_cancel(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,
|
addrinfo->ai_addrlen,
|
||||||
SOCK_STREAM,
|
SOCK_STREAM,
|
||||||
IPPROTO_TCP,
|
IPPROTO_TCP,
|
||||||
efl_net_socket_fd_close_on_exec_get(o),
|
efl_io_closer_close_on_exec_get(o),
|
||||||
_efl_net_dialer_tcp_connected,
|
_efl_net_dialer_tcp_connected,
|
||||||
o);
|
o);
|
||||||
}
|
}
|
||||||
|
@ -148,7 +152,7 @@ _efl_net_dialer_tcp_connect(Eo *o, Efl_Net_Dialer_Tcp_Data *pd)
|
||||||
addrinfo->ai_addrlen,
|
addrinfo->ai_addrlen,
|
||||||
SOCK_STREAM,
|
SOCK_STREAM,
|
||||||
IPPROTO_TCP,
|
IPPROTO_TCP,
|
||||||
efl_net_socket_fd_close_on_exec_get(o),
|
efl_io_closer_close_on_exec_get(o),
|
||||||
_efl_net_dialer_tcp_connected,
|
_efl_net_dialer_tcp_connected,
|
||||||
o);
|
o);
|
||||||
end:
|
end:
|
||||||
|
|
|
@ -953,8 +953,6 @@ _efl_net_dialer_websocket_efl_object_destructor(Eo *o, Efl_Net_Dialer_Websocket_
|
||||||
pd->close_timer = NULL;
|
pd->close_timer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!efl_io_closer_closed_get(pd->http))
|
|
||||||
efl_io_closer_close(pd->http);
|
|
||||||
efl_del(pd->http);
|
efl_del(pd->http);
|
||||||
pd->http = NULL;
|
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);
|
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
|
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_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.Writer.can_write.set;
|
||||||
Efl.Io.Closer.close;
|
Efl.Io.Closer.close;
|
||||||
Efl.Io.Closer.closed.get;
|
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
|
Children socket will inherit the server's setting by
|
||||||
default. One can change the behavior using each instance
|
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 { }
|
get { }
|
||||||
set {
|
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,
|
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_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));
|
efl_loop_fd_set(efl_added, client_fd));
|
||||||
if (!client)
|
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...",
|
DBG("client %s was not handled, closing it...",
|
||||||
efl_net_socket_address_remote_get(client));
|
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_local;
|
||||||
Eina_Stringshare *address_remote;
|
Eina_Stringshare *address_remote;
|
||||||
int family;
|
int family;
|
||||||
Eina_Bool close_on_exec;
|
|
||||||
} Efl_Net_Socket_Fd_Data;
|
} Efl_Net_Socket_Fd_Data;
|
||||||
|
|
||||||
static void
|
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)
|
_efl_net_socket_fd_efl_object_constructor(Eo *o, Efl_Net_Socket_Fd_Data *pd EINA_UNUSED)
|
||||||
{
|
{
|
||||||
pd->family = AF_UNSPEC;
|
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
|
EOLIAN static void
|
||||||
_efl_net_socket_fd_efl_object_destructor(Eo *o, Efl_Net_Socket_Fd_Data *pd)
|
_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));
|
efl_destructor(efl_super(o, MY_CLASS));
|
||||||
|
|
||||||
eina_stringshare_replace(&pd->address_local, NULL);
|
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
|
static void
|
||||||
_efl_net_socket_fd_set(Eo *o, Efl_Net_Socket_Fd_Data *pd, int fd)
|
_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_reader_fd_reader_fd_set(o, fd);
|
||||||
efl_io_writer_fd_writer_fd_set(o, fd);
|
efl_io_writer_fd_writer_fd_set(o, fd);
|
||||||
efl_io_closer_fd_closer_fd_set(o, fd);
|
efl_io_closer_fd_closer_fd_set(o, fd);
|
||||||
|
|
||||||
/* apply postponed values */
|
/* 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)
|
if (pd->family == AF_UNSPEC)
|
||||||
{
|
{
|
||||||
ERR("efl_loop_fd_set() must be called after efl_net_server_fd_family_set()");
|
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;
|
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
|
EOLIAN static void
|
||||||
_efl_net_socket_fd_family_set(Eo *o EINA_UNUSED, Efl_Net_Socket_Fd_Data *pd, int family)
|
_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
|
This is the common class and takes an existing FD, usually
|
||||||
created by an dialer or server.
|
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
|
@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;
|
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 {
|
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;
|
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
|
EOLIAN static Eina_Error
|
||||||
_efl_io_buffer_efl_io_sizer_resize(Eo *o, Efl_Io_Buffer_Data *pd, uint64_t size)
|
_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.Writer.can_write.set;
|
||||||
Efl.Io.Closer.close;
|
Efl.Io.Closer.close;
|
||||||
Efl.Io.Closer.closed.get;
|
Efl.Io.Closer.closed.get;
|
||||||
|
Efl.Io.Closer.close_on_exec;
|
||||||
|
Efl.Io.Closer.close_on_destructor;
|
||||||
Efl.Io.Sizer.resize;
|
Efl.Io.Sizer.resize;
|
||||||
Efl.Io.Sizer.size.get;
|
Efl.Io.Sizer.size.get;
|
||||||
Efl.Io.Positioner.seek;
|
Efl.Io.Positioner.seek;
|
||||||
|
|
|
@ -41,6 +41,36 @@ mixin Efl.Io.Closer {
|
||||||
is_closed: bool;
|
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 {
|
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;
|
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"
|
#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.Writer.can_write.set;
|
||||||
Efl.Io.Closer.close;
|
Efl.Io.Closer.close;
|
||||||
Efl.Io.Closer.closed.get;
|
Efl.Io.Closer.closed.get;
|
||||||
|
Efl.Io.Closer.close_on_exec;
|
||||||
|
Efl.Io.Closer.close_on_destructor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue