/**************************************************************************** * This file is part of the project Gwenhywfar. * Gwenhywfar (c) by 2023 Martin Preuss, all rights reserved. * * The license for this file can be found in the file COPYING which you * should have received along with this file. ****************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include "./fdobject_p.h" #include #include #include #include #include GWEN_INHERIT(AQH_OBJECT, AQH_FDOBJECT) /* ------------------------------------------------------------------------------------------------ * forward declarations * ------------------------------------------------------------------------------------------------ */ static void GWENHYWFAR_CB _freeData(void *bp, void *p); static void _cbEnable(AQH_OBJECT *o); static void _cbDisable(AQH_OBJECT *o); /* ------------------------------------------------------------------------------------------------ * implementations * ------------------------------------------------------------------------------------------------ */ AQH_OBJECT *AQH_FdObject_new(AQH_EVENT_LOOP *eventLoop, int fd, int mode) { AQH_OBJECT *o; AQH_FDOBJECT *xo; o=AQH_Object_new(eventLoop); GWEN_NEW_OBJECT(AQH_FDOBJECT, xo); GWEN_INHERIT_SETDATA(AQH_OBJECT, AQH_FDOBJECT, o, xo, _freeData); xo->fd=fd; xo->fdMode=mode; AQH_Object_SetEnableFn(o, _cbEnable); AQH_Object_SetDisableFn(o, _cbDisable); return o; } void GWENHYWFAR_CB _freeData(GWEN_UNUSED void *bp, void *p) { AQH_FDOBJECT *xo; xo=(AQH_FDOBJECT*)p; GWEN_FREE_OBJECT(xo); } int AQH_FdObject_GetFdMode(const AQH_OBJECT *o) { if (o) { AQH_FDOBJECT *xo; xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_FDOBJECT, o); if (xo) return xo->fdMode; } return 0; } void AQH_FdObject_SetFdMode(AQH_OBJECT *o, int i) { if (o) { AQH_FDOBJECT *xo; xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_FDOBJECT, o); if (xo) xo->fdMode=i; } } int AQH_FdObject_GetFd(const AQH_OBJECT *o) { if (o) { AQH_FDOBJECT *xo; xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_FDOBJECT, o); if (xo) return xo->fd; } return -1; } int AQH_FdObject_Read(AQH_OBJECT *o, uint8_t *ptrBuffer, uint32_t lenBuffer) { if (o && ptrBuffer && lenBuffer) { AQH_FDOBJECT *xo; xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_FDOBJECT, o); if (xo) { if (xo->fd!=-1) { ssize_t rv; rv=recv(xo->fd, ptrBuffer, lenBuffer, MSG_DONTWAIT); if (rv==0) { DBG_INFO(AQH_LOGDOMAIN, "EOF met"); return 0; } else if (rv>0) { /* data received */ return (int) rv; } else { if (rv==EINTR || errno==EWOULDBLOCK || errno==EAGAIN) { /* temporarily no data, try again */ return GWEN_ERROR_TRY_AGAIN; } else { DBG_ERROR(AQH_LOGDOMAIN, "Error on read: %s (%d)", strerror(errno), errno); xo->fd=-1; return GWEN_ERROR_IO; } } } else { DBG_ERROR(AQH_LOGDOMAIN, "Previous error, not reading."); return GWEN_ERROR_IO; } } } return GWEN_ERROR_INVALID; } void _cbEnable(AQH_OBJECT *o) { if (o && !(AQH_Object_GetFlags(o) & AQH_OBJECT_FLAGS_ENABLED)) { AQH_EVENT_LOOP *eventLoop; eventLoop=AQH_Object_GetEventLoop(o); if (eventLoop) { AQH_EventLoop_AddFdObject(eventLoop, o); AQH_Object_AddFlags(o, AQH_OBJECT_FLAGS_ENABLED); } } } void _cbDisable(AQH_OBJECT *o) { if (o && (AQH_Object_GetFlags(o) & AQH_OBJECT_FLAGS_ENABLED)) { AQH_EVENT_LOOP *eventLoop; eventLoop=AQH_Object_GetEventLoop(o); if (eventLoop) { AQH_EventLoop_DelFdObject(eventLoop, o); AQH_Object_SubFlags(o, AQH_OBJECT_FLAGS_ENABLED); } } }