some mux work. yet to be finished

This commit is contained in:
hyung-hwan 2020-01-28 23:32:04 +00:00
parent f45c45ee7e
commit e2accffa0e

View File

@ -103,7 +103,7 @@ typedef struct mod_ctx_t mod_ctx_t;
enum sys_node_data_type_t enum sys_node_data_type_t
{ {
SYS_NODE_DATA_TYPE_FD = (1 << 0), SYS_NODE_DATA_TYPE_FILE = (1 << 0),
SYS_NODE_DATA_TYPE_SCK = (1 << 1), SYS_NODE_DATA_TYPE_SCK = (1 << 1),
SYS_NODE_DATA_TYPE_DIR = (1 << 2), SYS_NODE_DATA_TYPE_DIR = (1 << 2),
SYS_NODE_DATA_TYPE_MUX = (1 << 3) SYS_NODE_DATA_TYPE_MUX = (1 << 3)
@ -120,9 +120,13 @@ struct sys_node_data_t
{ {
sys_node_data_type_t type; sys_node_data_type_t type;
int flags; int flags;
void* extra; /* if SYS_NODE_DATA_FLAG_IN_MUX is set, this is set to a valid pointer. it is of the void* type since sys_node_t is not available yet. */
union union
{
struct
{ {
int fd; int fd;
} file;
struct struct
{ {
int fd; int fd;
@ -222,9 +226,9 @@ static sys_node_t* new_sys_node_fd (hawk_rtx_t* rtx, sys_list_t* list, int fd)
node = __new_sys_node(rtx, list); node = __new_sys_node(rtx, list);
if (!node) return HAWK_NULL; if (!node) return HAWK_NULL;
node->ctx.type = SYS_NODE_DATA_TYPE_FD; node->ctx.type = SYS_NODE_DATA_TYPE_FILE;
node->ctx.flags = 0; node->ctx.flags = 0;
node->ctx.u.fd = fd; node->ctx.u.file.fd = fd;
return node; return node;
} }
@ -256,21 +260,64 @@ static sys_node_t* new_sys_node_mux (hawk_rtx_t* rtx, sys_list_t* list, int fd)
return node; return node;
} }
static void del_from_mux (hawk_rtx_t* rtx, sys_node_t* fd_node)
{
if (fd_node->ctx.flags & SYS_NODE_DATA_FLAG_IN_MUX)
{
sys_node_t* mux_node;
#if defined(USE_EPOLL)
struct epoll_event ev;
#endif
mux_node = (sys_node_t*)fd_node->ctx.extra;
switch (fd_node->ctx.type)
{
case SYS_NODE_DATA_TYPE_FILE:
#if defined(USE_EPOLL)
epoll_ctl (mux_node->ctx.u.mux.fd, EPOLL_CTL_DEL, fd_node->ctx.u.file.fd, &ev);
#endif
break;
case SYS_NODE_DATA_TYPE_SCK:
#if defined(USE_EPOLL)
epoll_ctl (mux_node->ctx.u.mux.fd, EPOLL_CTL_DEL, fd_node->ctx.u.sck.fd, &ev);
#endif
break;
default:
/* do nothing */
break;
}
fd_node->ctx.flags &= ~SYS_NODE_DATA_FLAG_IN_MUX;
fd_node->ctx.extra = HAWK_NULL;
}
}
static void purge_mux_members (hawk_rtx_t* rtx, sys_node_t* mux_node)
{
while (mux_node->ctx.extra)
{
del_from_mux (rtx, mux_node->ctx.extra);
}
}
static void free_sys_node (hawk_rtx_t* rtx, sys_list_t* list, sys_node_t* node) static void free_sys_node (hawk_rtx_t* rtx, sys_list_t* list, sys_node_t* node)
{ {
switch (node->ctx.type) switch (node->ctx.type)
{ {
case SYS_NODE_DATA_TYPE_FD: case SYS_NODE_DATA_TYPE_FILE:
if (node->ctx.u.fd >= 0) if (node->ctx.u.file.fd >= 0)
{ {
close (node->ctx.u.fd); del_from_mux (rtx, node);
node->ctx.u.fd = -1; close (node->ctx.u.file.fd);
node->ctx.u.file.fd = -1;
} }
break; break;
case SYS_NODE_DATA_TYPE_SCK: case SYS_NODE_DATA_TYPE_SCK:
if (node->ctx.u.sck.fd >= 0) if (node->ctx.u.sck.fd >= 0)
{ {
del_from_mux (rtx, node);
close (node->ctx.u.sck.fd); close (node->ctx.u.sck.fd);
node->ctx.u.sck.fd = -1; node->ctx.u.sck.fd = -1;
} }
@ -288,6 +335,8 @@ static void free_sys_node (hawk_rtx_t* rtx, sys_list_t* list, sys_node_t* node)
#if defined(USE_EPOLL) #if defined(USE_EPOLL)
if (node->ctx.u.mux.fd >= 0) if (node->ctx.u.mux.fd >= 0)
{ {
/* TODO: delete all member FILE and SCK from mux */
purge_mux_members (rtx, node);
close (node->ctx.u.mux.fd); close (node->ctx.u.mux.fd);
node->ctx.u.mux.fd = -1; node->ctx.u.mux.fd = -1;
} }
@ -371,17 +420,17 @@ static int fnc_close (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
hawk_int_t cflags = 0; hawk_int_t cflags = 0;
sys_list = rtx_to_sys_list(rtx, fi); sys_list = rtx_to_sys_list(rtx, fi);
sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_TYPE_FD, &rx); sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_TYPE_FILE, &rx);
if (sys_node) if (sys_node)
{ {
/* although free_sys_node can handle other types, sys::close() is allowed to /* although free_sys_node can handle other types, sys::close() is allowed to
* close nodes of the SYS_NODE_DATA_TYPE_FD type only */ * close nodes of the SYS_NODE_DATA_TYPE_FILE type only */
if (hawk_rtx_getnargs(rtx) >= 2 && (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 1), &cflags) <= -1 || cflags < 0)) cflags = 0; if (hawk_rtx_getnargs(rtx) >= 2 && (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 1), &cflags) <= -1 || cflags < 0)) cflags = 0;
if (cflags & CLOSE_KEEPFD) /* this flag applies to file descriptors only */ if (cflags & CLOSE_KEEPFD) /* this flag applies to file descriptors only */
{ {
sys_node->ctx.u.fd = -1; /* you may leak the original file descriptor. */ sys_node->ctx.u.file.fd = -1; /* you may leak the original file descriptor. */
} }
free_sys_node (rtx, sys_list, sys_node); free_sys_node (rtx, sys_list, sys_node);
@ -506,7 +555,7 @@ static int fnc_read (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
hawk_int_t reqsize = 8192; hawk_int_t reqsize = 8192;
sys_list = rtx_to_sys_list(rtx, fi); sys_list = rtx_to_sys_list(rtx, fi);
sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_TYPE_FD, &rx); sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_TYPE_FILE, &rx);
if (sys_node) if (sys_node)
{ {
if (hawk_rtx_getnargs(rtx) >= 3 && (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 2), &reqsize) <= -1 || reqsize <= 0)) reqsize = 8192; if (hawk_rtx_getnargs(rtx) >= 3 && (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 2), &reqsize) <= -1 || reqsize <= 0)) reqsize = 8192;
@ -524,7 +573,7 @@ static int fnc_read (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
sys_list->ctx.readbuf_capa = reqsize; sys_list->ctx.readbuf_capa = reqsize;
} }
rx = read(sys_node->ctx.u.fd, sys_list->ctx.readbuf, reqsize); rx = read(sys_node->ctx.u.file.fd, sys_list->ctx.readbuf, reqsize);
if (rx <= 0) if (rx <= 0)
{ {
if (rx <= -1) rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_T("unable to read")); if (rx <= -1) rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_T("unable to read"));
@ -567,7 +616,7 @@ static int fnc_write (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
hawk_int_t rx; hawk_int_t rx;
sys_list = rtx_to_sys_list(rtx, fi); sys_list = rtx_to_sys_list(rtx, fi);
sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_TYPE_FD, &rx); sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_TYPE_FILE, &rx);
if (sys_node) if (sys_node)
{ {
hawk_bch_t* dptr; hawk_bch_t* dptr;
@ -578,7 +627,7 @@ static int fnc_write (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
dptr = hawk_rtx_getvalbcstr(rtx, a1, &dlen); dptr = hawk_rtx_getvalbcstr(rtx, a1, &dlen);
if (dptr) if (dptr)
{ {
rx = write(sys_node->ctx.u.fd, dptr, dlen); rx = write(sys_node->ctx.u.file.fd, dptr, dlen);
if (rx <= -1) rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_T("unable to write")); if (rx <= -1) rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_T("unable to write"));
hawk_rtx_freevalbcstr (rtx, a1, dptr); hawk_rtx_freevalbcstr (rtx, a1, dptr);
} }
@ -621,14 +670,14 @@ static int fnc_dup (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
hawk_int_t oflags = 0; hawk_int_t oflags = 0;
sys_list = rtx_to_sys_list(rtx, fi); sys_list = rtx_to_sys_list(rtx, fi);
sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_TYPE_FD, &rx); sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_TYPE_FILE, &rx);
if (sys_node) if (sys_node)
{ {
int fd; int fd;
if (hawk_rtx_getnargs(rtx) >= 2) if (hawk_rtx_getnargs(rtx) >= 2)
{ {
sys_node2 = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 1), SYS_NODE_DATA_TYPE_FD, &rx); sys_node2 = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 1), SYS_NODE_DATA_TYPE_FILE, &rx);
if (!sys_node2) goto done; if (!sys_node2) goto done;
if (hawk_rtx_getnargs(rtx) >= 3 && (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 2), &oflags) <= -1 || oflags < 0)) oflags = 0; if (hawk_rtx_getnargs(rtx) >= 3 && (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 2), &oflags) <= -1 || oflags < 0)) oflags = 0;
} }
@ -636,9 +685,9 @@ static int fnc_dup (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
if (sys_node2) if (sys_node2)
{ {
#if defined(HAVE_DUP3) #if defined(HAVE_DUP3)
fd = dup3(sys_node->ctx.u.fd, sys_node2->ctx.u.fd, oflags); fd = dup3(sys_node->ctx.u.file.fd, sys_node2->ctx.u.file.fd, oflags);
#else #else
fd = dup2(sys_node->ctx.u.fd, sys_node2->ctx.u.fd); fd = dup2(sys_node->ctx.u.file.fd, sys_node2->ctx.u.file.fd);
#endif #endif
if (fd >= 0) if (fd >= 0)
{ {
@ -658,7 +707,7 @@ static int fnc_dup (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
} }
#endif #endif
sys_node2->ctx.u.fd = fd; /* dup2 or dup3 closes the descriptor implicitly */ sys_node2->ctx.u.file.fd = fd; /* dup2 or dup3 closes the descriptor implicitly */
rx = sys_node2->id; rx = sys_node2->id;
} }
else else
@ -668,7 +717,7 @@ static int fnc_dup (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
} }
else else
{ {
fd = dup(sys_node->ctx.u.fd); fd = dup(sys_node->ctx.u.file.fd);
if (fd >= 0) if (fd >= 0)
{ {
sys_node_t* new_node; sys_node_t* new_node;
@ -881,7 +930,7 @@ static int fnc_fchown (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
hawk_int_t rx; hawk_int_t rx;
sys_list = rtx_to_sys_list(rtx, fi); sys_list = rtx_to_sys_list(rtx, fi);
sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_TYPE_FD, &rx); sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_TYPE_FILE, &rx);
if (sys_node) if (sys_node)
{ {
hawk_int_t uid, gid; hawk_int_t uid, gid;
@ -893,7 +942,7 @@ static int fnc_fchown (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
} }
else else
{ {
rx = fchown(sys_node->ctx.u.fd, uid, gid) <= -1? rx = fchown(sys_node->ctx.u.file.fd, uid, gid) <= -1?
set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL): set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL):
ERRNUM_TO_RC(HAWK_ENOERR); ERRNUM_TO_RC(HAWK_ENOERR);
} }
@ -910,7 +959,7 @@ static int fnc_fchmod (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
hawk_int_t rx; hawk_int_t rx;
sys_list = rtx_to_sys_list(rtx, fi); sys_list = rtx_to_sys_list(rtx, fi);
sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_TYPE_FD, &rx); sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_TYPE_FILE, &rx);
if (sys_node) if (sys_node)
{ {
hawk_int_t mode; hawk_int_t mode;
@ -921,7 +970,7 @@ static int fnc_fchmod (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
} }
else else
{ {
rx = fchmod(sys_node->ctx.u.fd, mode) <= -1? rx = fchmod(sys_node->ctx.u.file.fd, mode) <= -1?
set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL): set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL):
ERRNUM_TO_RC(HAWK_ENOERR); ERRNUM_TO_RC(HAWK_ENOERR);
} }
@ -2773,7 +2822,7 @@ static HAWK_INLINE int ctl_epoll (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi, in
if (sys_node) if (sys_node)
{ {
sys_node2 = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 1), SYS_NODE_DATA_TYPE_FD | SYS_NODE_DATA_TYPE_SCK, &rx); sys_node2 = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 1), SYS_NODE_DATA_TYPE_FILE | SYS_NODE_DATA_TYPE_SCK, &rx);
if (sys_node2) if (sys_node2)
{ {
struct epoll_event ev; struct epoll_event ev;
@ -2795,8 +2844,8 @@ static HAWK_INLINE int ctl_epoll (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi, in
switch (sys_node2->ctx.type) switch (sys_node2->ctx.type)
{ {
case SYS_NODE_DATA_TYPE_FD: case SYS_NODE_DATA_TYPE_FILE:
evfd = sys_node2->ctx.u.fd; evfd = sys_node2->ctx.u.file.fd;
break; break;
case SYS_NODE_DATA_TYPE_SCK: case SYS_NODE_DATA_TYPE_SCK:
evfd = sys_node2->ctx.u.sck.fd; evfd = sys_node2->ctx.u.sck.fd;
@ -2815,9 +2864,15 @@ static HAWK_INLINE int ctl_epoll (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi, in
else else
{ {
if (cmd != EPOLL_CTL_DEL) if (cmd != EPOLL_CTL_DEL)
{
sys_node2->ctx.flags |= SYS_NODE_DATA_FLAG_IN_MUX; sys_node2->ctx.flags |= SYS_NODE_DATA_FLAG_IN_MUX;
sys_node2->ctx.extra = sys_node;
}
else else
{
sys_node2->ctx.flags &= ~SYS_NODE_DATA_FLAG_IN_MUX; sys_node2->ctx.flags &= ~SYS_NODE_DATA_FLAG_IN_MUX;
sys_node2->ctx.extra = HAWK_NULL;
}
} }
} }
} }
@ -2861,7 +2916,41 @@ static int fnc_modinpoll (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
static int fnc_waitonpoll (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) static int fnc_waitonpoll (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{ {
#if defined(USE_EPOLL) #if defined(USE_EPOLL)
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, ERRNUM_TO_RC(HAWK_ENOIMPL))); sys_list_t* sys_list;
sys_node_t* sys_node;
hawk_int_t rx = ERRNUM_TO_RC(HAWK_ENOERR);
sys_list = rtx_to_sys_list(rtx, fi);
sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_TYPE_MUX, &rx);
if (sys_node)
{
struct epoll_event events[64];
hawk_int_t tmout;
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 1), &tmout) <= -1) tmout = -1;
if (epoll_wait(sys_node->ctx.u.mux.fd, events, HAWK_COUNTOF(events), tmout) <= -1)
{
rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL);
}
else
{
/* TODO: */
/* arrange to return an array of file descriptros and.... what??? */
/* set ref value on argument 1 */
/*
ev["count"] = 10;
ev[1, "fd"] = 10;
ev[1, "events"] = R | W,
ev[2, "fd"] = 10;
ev[2, "events"] = R | W,
*/
}
}
done:
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx));
return 0; return 0;
#else #else
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, ERRNUM_TO_RC(HAWK_ENOIMPL))); hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, ERRNUM_TO_RC(HAWK_ENOIMPL)));
@ -3295,6 +3384,7 @@ static fnctab_t fnctab[] =
{ HAWK_T("unlink"), { { 1, 1, HAWK_NULL }, fnc_unlink, 0 } }, { HAWK_T("unlink"), { { 1, 1, HAWK_NULL }, fnc_unlink, 0 } },
{ HAWK_T("unsetenv"), { { 1, 1, HAWK_NULL }, fnc_unsetenv, 0 } }, { HAWK_T("unsetenv"), { { 1, 1, HAWK_NULL }, fnc_unsetenv, 0 } },
{ HAWK_T("wait"), { { 1, 3, HAWK_T("vrv") }, fnc_wait, 0 } }, { HAWK_T("wait"), { { 1, 3, HAWK_T("vrv") }, fnc_wait, 0 } },
{ HAWK_T("waitonpoll"), { { 3, 3, HAWK_T("vvr") }, fnc_waitonpoll, 0 } },
{ HAWK_T("write"), { { 2, 2, HAWK_NULL }, fnc_write, 0 } }, { HAWK_T("write"), { { 2, 2, HAWK_NULL }, fnc_write, 0 } },
{ HAWK_T("writelog"), { { 2, 2, HAWK_NULL }, fnc_writelog, 0 } } { HAWK_T("writelog"), { { 2, 2, HAWK_NULL }, fnc_writelog, 0 } }
}; };