efl/src/lib/ecore/efl_io_closer_fd.c

134 lines
3.1 KiB
C

#define EFL_IO_CLOSER_FD_PROTECTED 1
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <Ecore.h>
#include <fcntl.h>
#include "ecore_private.h"
#define MY_CLASS EFL_IO_CLOSER_FD_MIXIN
typedef struct _Efl_Io_Closer_Fd_Data
{
int fd;
Eina_Bool close_on_exec;
Eina_Bool close_on_invalidate;
} Efl_Io_Closer_Fd_Data;
static Efl_Object *
_efl_io_closer_fd_efl_object_constructor(Eo *obj, Efl_Io_Closer_Fd_Data *pd)
{
pd->fd = -1;
return efl_constructor(efl_super(obj, MY_CLASS));
}
EOLIAN static void
_efl_io_closer_fd_closer_fd_set(Eo *o EINA_UNUSED, Efl_Io_Closer_Fd_Data *pd, int fd)
{
pd->fd = fd;
}
EOLIAN static int
_efl_io_closer_fd_closer_fd_get(const Eo *o EINA_UNUSED, Efl_Io_Closer_Fd_Data *pd)
{
return pd->fd;
}
EOLIAN static Eina_Error
_efl_io_closer_fd_efl_io_closer_close(Eo *o, Efl_Io_Closer_Fd_Data *pd EINA_UNUSED)
{
int fd;
Eina_Error err = 0;
fd = efl_io_closer_fd_get(o);
EINA_SAFETY_ON_TRUE_RETURN_VAL(fd < 0, EBADF);
efl_io_closer_fd_set(o, -1);
if (close(fd) < 0) err = errno;
efl_event_callback_call(o, EFL_IO_CLOSER_EVENT_CLOSED, NULL);
return err;
}
EOLIAN static Eina_Bool
_efl_io_closer_fd_efl_io_closer_closed_get(const Eo *o, Efl_Io_Closer_Fd_Data *pd EINA_UNUSED)
{
return efl_io_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;
(void)o;
#else
int fd;
Eina_Bool old = pd->close_on_exec;
pd->close_on_exec = close_on_exec;
fd = efl_io_closer_fd_get(o);
if (fd < 0) return EINA_TRUE; /* postpone until fd_set(), users
* must apply MANUALLY if it's not
* already set!
*/
if (!eina_file_close_on_exec(fd, close_on_exec))
{
ERR("eina_file_close_on_exec(%d) failed", fd);
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(const Eo *o, Efl_Io_Closer_Fd_Data *pd)
{
#ifdef _WIN32
return pd->close_on_exec;
(void)o;
#else
int flags, fd;
fd = efl_io_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_invalidate_set(Eo *o EINA_UNUSED, Efl_Io_Closer_Fd_Data *pd, Eina_Bool close_on_invalidate)
{
pd->close_on_invalidate = close_on_invalidate;
}
EOLIAN static Eina_Bool
_efl_io_closer_fd_efl_io_closer_close_on_invalidate_get(const Eo *o EINA_UNUSED, Efl_Io_Closer_Fd_Data *pd)
{
return pd->close_on_invalidate;
}
#include "efl_io_closer_fd.eo.c"