added sys::chroot()
This commit is contained in:
parent
44937ce12a
commit
13eba6b85d
@ -59,6 +59,14 @@
|
||||
#define CLOSE_KEEPFD (1 << 0)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* IMPLEMENTATION NOTE:
|
||||
* - hard failure only if it cannot make a final return value. (e.g. fnc_errmsg, fnc_fork, fnc_getpid)
|
||||
* - soft failure if it cannot make a value for pass-by-referece argument (e.g. fnc_pipe)
|
||||
* - soft failure for all other types of errors
|
||||
*/
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
typedef enum syslog_type_t syslog_type_t;
|
||||
@ -250,18 +258,20 @@ static HAWK_INLINE sys_node_t* get_sys_list_node (sys_list_t* sys_list, hawk_int
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static sys_node_t* get_sys_list_node_with_arg (hawk_rtx_t* rtx, sys_list_t* sys_list, hawk_val_t* arg, int node_type)
|
||||
static sys_node_t* get_sys_list_node_with_arg (hawk_rtx_t* rtx, sys_list_t* sys_list, hawk_val_t* arg, int node_type, hawk_int_t* rx)
|
||||
{
|
||||
hawk_int_t id;
|
||||
sys_node_t* sys_node;
|
||||
|
||||
if (hawk_rtx_valtoint(rtx, arg, &id) <= -1)
|
||||
{
|
||||
*rx = ERRNUM_TO_RC(hawk_rtx_geterrnum(rtx));
|
||||
set_errmsg_on_sys_list (rtx, sys_list, HAWK_T("illegal handle value"));
|
||||
return HAWK_NULL;
|
||||
}
|
||||
else if (!(sys_node = get_sys_list_node(sys_list, id)))
|
||||
{
|
||||
*rx = ERRNUM_TO_RC(HAWK_EINVAL);
|
||||
set_errmsg_on_sys_list (rtx, sys_list, HAWK_T("invalid handle - %zd"), (hawk_oow_t)id);
|
||||
return HAWK_NULL;
|
||||
}
|
||||
@ -269,6 +279,7 @@ static sys_node_t* get_sys_list_node_with_arg (hawk_rtx_t* rtx, sys_list_t* sys_
|
||||
if (sys_node->ctx.type != node_type)
|
||||
{
|
||||
/* the handle is found but is not of the desired type */
|
||||
*rx = ERRNUM_TO_RC(HAWK_EINVAL);
|
||||
set_errmsg_on_sys_list (rtx, sys_list, HAWK_T("wrong handle type"));
|
||||
return HAWK_NULL;
|
||||
}
|
||||
@ -297,30 +308,24 @@ static int fnc_close (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
sys_list_t* sys_list;
|
||||
sys_node_t* sys_node;
|
||||
hawk_int_t rx = ERRNUM_TO_RC(HAWK_EOTHER);
|
||||
hawk_int_t rx = ERRNUM_TO_RC(HAWK_ENOERR);
|
||||
hawk_int_t cflags = 0;
|
||||
|
||||
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_FD);
|
||||
|
||||
if (hawk_rtx_getnargs(rtx) >= 2 && (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 1), &cflags) <= -1 || cflags < 0)) cflags = 0;
|
||||
sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_FD, &rx);
|
||||
|
||||
if (sys_node)
|
||||
{
|
||||
/* although free_sys_node can handle other types, sys::close() is allowed to
|
||||
* close nodes of the SYS_NODE_DATA_FD type only */
|
||||
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 */
|
||||
{
|
||||
sys_node->ctx.u.fd = -1; /* you may leak the original file descriptor. */
|
||||
}
|
||||
|
||||
free_sys_node (rtx, sys_list, sys_node);
|
||||
rx = ERRNUM_TO_RC(HAWK_ENOERR);
|
||||
}
|
||||
else
|
||||
{
|
||||
rx = ERRNUM_TO_RC(HAWK_EINVAL);
|
||||
/* error information set in get_sys_list_node_with_arg() */
|
||||
}
|
||||
|
||||
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx));
|
||||
@ -403,7 +408,7 @@ static int fnc_openfd (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
/* wrap a raw system file descriptor into the internal management node */
|
||||
|
||||
sys_list_t* sys_list;
|
||||
hawk_int_t rx = ERRNUM_TO_RC(HAWK_EOTHER);
|
||||
hawk_int_t rx;
|
||||
hawk_int_t fd;
|
||||
|
||||
sys_list = rtx_to_sys_list(rtx, fi);
|
||||
@ -428,7 +433,7 @@ static int fnc_openfd (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
rx = set_error_on_sys_list(rtx, sys_list, HAWK_EINVAL, HAWK_T("invalid file descriptor %jd"), (hawk_intmax_t)fd);
|
||||
}
|
||||
|
||||
/*HAWK_ASSERT (HAWK_IN_QUICKINT_RANGE(rx));*/
|
||||
HAWK_ASSERT (HAWK_IN_QUICKINT_RANGE(rx));
|
||||
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx));
|
||||
return 0;
|
||||
}
|
||||
@ -438,16 +443,16 @@ static int fnc_read (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
sys_list_t* sys_list;
|
||||
sys_node_t* sys_node;
|
||||
hawk_int_t rx = ERRNUM_TO_RC(HAWK_EOTHER);
|
||||
hawk_int_t rx;
|
||||
hawk_int_t reqsize = 8192;
|
||||
|
||||
if (hawk_rtx_getnargs(rtx) >= 3 && (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 2), &reqsize) <= -1 || reqsize <= 0)) reqsize = 8192;
|
||||
if (reqsize > HAWK_QUICKINT_MAX) reqsize = HAWK_QUICKINT_MAX;
|
||||
|
||||
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_FD);
|
||||
sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_FD, &rx);
|
||||
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 (reqsize > HAWK_QUICKINT_MAX) reqsize = HAWK_QUICKINT_MAX;
|
||||
|
||||
if (reqsize > sys_list->ctx.readbuf_capa)
|
||||
{
|
||||
hawk_bch_t* tmp = hawk_rtx_reallocmem(rtx, sys_list->ctx.readbuf, reqsize);
|
||||
@ -472,19 +477,22 @@ static int fnc_read (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
int x;
|
||||
|
||||
sv = hawk_rtx_makembsval(rtx, sys_list->ctx.readbuf, rx);
|
||||
if (!sv) return -1;
|
||||
if (!sv)
|
||||
{
|
||||
rx = copy_error_to_sys_list(rtx, sys_list);
|
||||
goto done;
|
||||
}
|
||||
|
||||
hawk_rtx_refupval (rtx, sv);
|
||||
x = hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 1), sv);
|
||||
hawk_rtx_refdownval (rtx, sv);
|
||||
if (x <= -1) return -1;
|
||||
if (x <= -1)
|
||||
{
|
||||
rx = copy_error_to_sys_list(rtx, sys_list);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rx = ERRNUM_TO_RC(HAWK_EINVAL);
|
||||
/* error information set in get_sys_list_node_with_arg() */
|
||||
}
|
||||
|
||||
done:
|
||||
/* the value in 'rx' never exceeds HAWK_QUICKINT_MAX as 'reqsize' has been limited to
|
||||
@ -497,10 +505,10 @@ static int fnc_write (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
sys_list_t* sys_list;
|
||||
sys_node_t* sys_node;
|
||||
hawk_int_t rx = ERRNUM_TO_RC(HAWK_EOTHER);
|
||||
hawk_int_t rx;
|
||||
|
||||
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_FD);
|
||||
sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_FD, &rx);
|
||||
if (sys_node)
|
||||
{
|
||||
hawk_bch_t* dptr;
|
||||
@ -520,11 +528,6 @@ static int fnc_write (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
rx = copy_error_to_sys_list(rtx, sys_list);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rx = ERRNUM_TO_RC(HAWK_EINVAL);
|
||||
/* error information set in get_sys_list_node_with_arg() */
|
||||
}
|
||||
|
||||
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx));
|
||||
return 0;
|
||||
@ -555,22 +558,22 @@ static int fnc_dup (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
sys_list_t* sys_list;
|
||||
sys_node_t* sys_node, * sys_node2 = HAWK_NULL;
|
||||
hawk_int_t rx = ERRNUM_TO_RC(HAWK_EOTHER);
|
||||
hawk_int_t rx;
|
||||
hawk_int_t oflags = 0;
|
||||
|
||||
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_FD);
|
||||
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_FD);
|
||||
if (!sys_node2) goto fail_einval;
|
||||
if (hawk_rtx_getnargs(rtx) >= 3 && (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 2), &oflags) <= -1 || oflags < 0)) oflags = 0;
|
||||
}
|
||||
|
||||
sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_FD, &rx);
|
||||
if (sys_node)
|
||||
{
|
||||
int fd;
|
||||
|
||||
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_FD, &rx);
|
||||
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 (sys_node2)
|
||||
{
|
||||
#if defined(HAVE_DUP3)
|
||||
@ -628,13 +631,9 @@ static int fnc_dup (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fail_einval:
|
||||
rx = ERRNUM_TO_RC(HAWK_EINVAL);
|
||||
/* error information set in get_sys_list_node_with_arg() */
|
||||
}
|
||||
|
||||
done:
|
||||
HAWK_ASSERT (HAWK_IN_QUICKINT_RANGE(rx)); /* assume a file descriptor never gets larger than HAWK_QUICKINT_MAX */
|
||||
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx));
|
||||
return 0;
|
||||
}
|
||||
@ -730,7 +729,7 @@ static int fnc_pipe (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
/* create low-level pipes */
|
||||
|
||||
sys_list_t* sys_list;
|
||||
hawk_int_t rx = ERRNUM_TO_RC(HAWK_EOTHER);
|
||||
hawk_int_t rx;
|
||||
int fds[2];
|
||||
hawk_int_t flags = 0;
|
||||
|
||||
@ -763,6 +762,7 @@ static int fnc_pipe (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
|
||||
if (nflags > 0)
|
||||
{
|
||||
/* don't care about failure */
|
||||
fcntl (fds[0], F_SETFD, nflags);
|
||||
fcntl (fds[1], F_SETFD, nflags);
|
||||
}
|
||||
@ -776,13 +776,8 @@ static int fnc_pipe (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
int x;
|
||||
|
||||
v = hawk_rtx_makeintval(rtx, node1->id);
|
||||
if (!v)
|
||||
{
|
||||
fail:
|
||||
free_sys_node (rtx, sys_list, node1);
|
||||
free_sys_node (rtx, sys_list, node2);
|
||||
return -1;
|
||||
}
|
||||
if (!v) goto fail;
|
||||
|
||||
hawk_rtx_refupval (rtx, v);
|
||||
x = hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 0), v);
|
||||
hawk_rtx_refdownval (rtx, v);
|
||||
@ -795,13 +790,18 @@ static int fnc_pipe (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
hawk_rtx_refdownval (rtx, v);
|
||||
if (x <= -1) goto fail;
|
||||
|
||||
rx = ERRNUM_TO_RC(HAWK_ENOERR);
|
||||
/* successful so far */
|
||||
rx = ERRNUM_TO_RC(HAWK_ENOERR);
|
||||
}
|
||||
else
|
||||
{
|
||||
fail:
|
||||
rx = copy_error_to_sys_list(rtx, sys_list);
|
||||
|
||||
if (node2) free_sys_node (rtx, sys_list, node2);
|
||||
else close(fds[1]);
|
||||
if (node1) free_sys_node (rtx, sys_list, node1);
|
||||
else close(fds[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -819,10 +819,10 @@ static int fnc_fchown (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
sys_list_t* sys_list;
|
||||
sys_node_t* sys_node;
|
||||
hawk_int_t rx = ERRNUM_TO_RC(HAWK_EOTHER);
|
||||
hawk_int_t rx;
|
||||
|
||||
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_FD);
|
||||
sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_FD, &rx);
|
||||
if (sys_node)
|
||||
{
|
||||
hawk_int_t uid, gid;
|
||||
@ -834,15 +834,38 @@ static int fnc_fchown (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
}
|
||||
else
|
||||
{
|
||||
rx = (fchown(sys_node->ctx.u.fd, uid, gid) == -1)?
|
||||
rx = fchown(sys_node->ctx.u.fd, uid, gid) <= -1?
|
||||
set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL):
|
||||
ERRNUM_TO_RC(HAWK_ENOERR);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fnc_fchmod (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
sys_list_t* sys_list;
|
||||
sys_node_t* sys_node;
|
||||
hawk_int_t rx;
|
||||
|
||||
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_FD, &rx);
|
||||
if (sys_node)
|
||||
{
|
||||
rx = ERRNUM_TO_RC(HAWK_EINVAL);
|
||||
/* error information set in get_sys_list_node_with_arg() */
|
||||
hawk_int_t mode;
|
||||
|
||||
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 1), &mode) <= -1)
|
||||
{
|
||||
rx = copy_error_to_sys_list(rtx, sys_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
rx = fchmod(sys_node->ctx.u.fd, mode) <= -1?
|
||||
set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL):
|
||||
ERRNUM_TO_RC(HAWK_ENOERR);
|
||||
}
|
||||
}
|
||||
|
||||
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx));
|
||||
@ -926,21 +949,15 @@ static int fnc_closedir (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
sys_list_t* sys_list;
|
||||
sys_node_t* sys_node;
|
||||
hawk_int_t rx = ERRNUM_TO_RC(HAWK_EOTHER);
|
||||
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_DIR);
|
||||
sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_DIR, &rx);
|
||||
if (sys_node)
|
||||
{
|
||||
/* although free_sys_node() can handle other types, sys::closedir() is allowed to
|
||||
* close nodes of the SYS_NODE_DATA_DIR type only */
|
||||
free_sys_node (rtx, sys_list, sys_node);
|
||||
rx = ERRNUM_TO_RC(HAWK_ENOERR);
|
||||
}
|
||||
else
|
||||
{
|
||||
rx = ERRNUM_TO_RC(HAWK_EINVAL);
|
||||
/* error information set in get_sys_list_node_with_arg() */
|
||||
}
|
||||
|
||||
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx));
|
||||
@ -951,53 +968,36 @@ static int fnc_readdir (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
sys_list_t* sys_list;
|
||||
sys_node_t* sys_node;
|
||||
hawk_int_t rx = ERRNUM_TO_RC(HAWK_EOTHER);
|
||||
hawk_int_t rx = 0; /* no more entry */
|
||||
|
||||
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_DIR);
|
||||
sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_DIR, &rx);
|
||||
if (sys_node)
|
||||
{
|
||||
int y;
|
||||
hawk_dir_ent_t ent;
|
||||
hawk_val_t* tmp;
|
||||
|
||||
y = hawk_dir_read(sys_node->ctx.u.dir, &ent);
|
||||
if (y <= -1)
|
||||
rx = hawk_dir_read(sys_node->ctx.u.dir, &ent); /* assume -1 on error, 0 on no more entry, 1 when an entry is available */
|
||||
if (rx <= -1)
|
||||
{
|
||||
goto fail;
|
||||
fail:
|
||||
rx = copy_error_to_sys_list(rtx, sys_list);
|
||||
}
|
||||
else if (y == 0)
|
||||
{
|
||||
rx = 0; /* no more entry */
|
||||
}
|
||||
else
|
||||
else if (rx > 0)
|
||||
{
|
||||
hawk_val_t* tmp;
|
||||
int x;
|
||||
|
||||
tmp = hawk_rtx_makestrvalwithoocstr(rtx, ent.name);
|
||||
if (!tmp)
|
||||
{
|
||||
fail:
|
||||
rx = copy_error_to_sys_list(rtx, sys_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
int n;
|
||||
hawk_rtx_refupval (rtx, tmp);
|
||||
n = hawk_rtx_setrefval (rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 1), tmp);
|
||||
hawk_rtx_refdownval (rtx, tmp);
|
||||
if (n <= -1) return -1;
|
||||
if (!tmp) goto fail;
|
||||
|
||||
rx = 1; /* has entry */
|
||||
}
|
||||
hawk_rtx_refupval (rtx, tmp);
|
||||
x = hawk_rtx_setrefval (rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 1), tmp);
|
||||
hawk_rtx_refdownval (rtx, tmp);
|
||||
if (x <= -1) goto fail;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rx = ERRNUM_TO_RC(HAWK_EINVAL);
|
||||
/* error information set in get_sys_list_node_with_arg() */
|
||||
}
|
||||
|
||||
/* the value in 'rx' never exceeds HAWK_QUICKINT_MAX as 'reqsize' has been limited to
|
||||
* it before the call to 'read'. so it's safe not to check the result of hawk_rtx_makeintval() */
|
||||
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx));
|
||||
return 0;
|
||||
}
|
||||
@ -1006,10 +1006,10 @@ static int fnc_resetdir (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
sys_list_t* sys_list;
|
||||
sys_node_t* sys_node;
|
||||
hawk_int_t rx = ERRNUM_TO_RC(HAWK_EOTHER);
|
||||
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_DIR);
|
||||
sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_DIR, &rx);
|
||||
|
||||
if (sys_node)
|
||||
{
|
||||
@ -1021,7 +1021,6 @@ static int fnc_resetdir (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
if (path)
|
||||
{
|
||||
if (hawk_dir_reset(sys_node->ctx.u.dir, path) <= -1) goto fail;
|
||||
rx = ERRNUM_TO_RC(HAWK_ENOERR); /* success */
|
||||
hawk_rtx_freevaloocstr (rtx, a1, path);
|
||||
}
|
||||
else
|
||||
@ -1030,11 +1029,6 @@ static int fnc_resetdir (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
rx = copy_error_to_sys_list(rtx, sys_list);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rx = ERRNUM_TO_RC(HAWK_EINVAL);
|
||||
/* error information set in get_sys_list_node_with_arg() */
|
||||
}
|
||||
|
||||
/* no error check for hawk_rtx_makeintval() here since ret
|
||||
* is 0 or -1. it will never fail for those numbers */
|
||||
@ -1065,7 +1059,7 @@ static int fnc_fork (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
#endif
|
||||
|
||||
retv = hawk_rtx_makeintval(rtx, rx);
|
||||
if (retv == HAWK_NULL) return -1;
|
||||
if (retv == HAWK_NULL) return -1; /* hard failure. unable to create a return value */
|
||||
|
||||
hawk_rtx_setretval (rtx, retv);
|
||||
return 0;
|
||||
@ -1082,13 +1076,7 @@ static int fnc_wait (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
sys_list_t* sys_list = rtx_to_sys_list(rtx, fi);
|
||||
|
||||
nargs = hawk_rtx_getnargs(rtx);
|
||||
if (nargs >= 3 && hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 2), &opts) <= -1)
|
||||
{
|
||||
fail:
|
||||
rx = copy_error_to_sys_list(rtx, sys_list);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (nargs >= 3 && hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 2), &opts) <= -1) goto fail;
|
||||
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &pid) <= -1) goto fail;
|
||||
|
||||
#if defined(_WIN32)
|
||||
@ -1105,30 +1093,34 @@ static int fnc_wait (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
status = 0;
|
||||
#else
|
||||
rx = waitpid(pid, &status, opts);
|
||||
if (rx <= -1) rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL);
|
||||
#endif
|
||||
|
||||
done:
|
||||
retv = hawk_rtx_makeintval(rtx, rx);
|
||||
if (!retv) return -1;
|
||||
|
||||
if (nargs >= 2)
|
||||
if (rx <= -1)
|
||||
{
|
||||
hawk_val_t* sv;
|
||||
int x;
|
||||
|
||||
sv = hawk_rtx_makeintval(rtx, status);
|
||||
if (!sv) return -1;
|
||||
|
||||
hawk_rtx_refupval (rtx, sv);
|
||||
x = hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 1), sv);
|
||||
hawk_rtx_refdownval (rtx, sv);
|
||||
if (x <= -1)
|
||||
rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nargs >= 2)
|
||||
{
|
||||
hawk_rtx_freemem (rtx, retv);
|
||||
return -1;
|
||||
hawk_val_t* sv;
|
||||
int x;
|
||||
|
||||
sv = hawk_rtx_makeintval(rtx, status);
|
||||
if (!sv) goto fail;
|
||||
|
||||
hawk_rtx_refupval (rtx, sv);
|
||||
x = hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 1), sv);
|
||||
hawk_rtx_refdownval (rtx, sv);
|
||||
if (x <= -1)
|
||||
{
|
||||
fail:
|
||||
rx = copy_error_to_sys_list(rtx, sys_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
retv = hawk_rtx_makeintval(rtx, rx);
|
||||
if (!retv) return -1; /* hard failure. unable to make a return value */
|
||||
|
||||
hawk_rtx_setretval (rtx, retv);
|
||||
return 0;
|
||||
@ -1137,21 +1129,23 @@ done:
|
||||
static int fnc_wifexited (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
hawk_int_t wstatus;
|
||||
hawk_val_t* retv;
|
||||
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &wstatus) <= -1) return -1;
|
||||
retv = hawk_rtx_makeintval(rtx, WIFEXITED(wstatus));
|
||||
if (!retv) return -1;
|
||||
hawk_rtx_setretval (rtx, retv);
|
||||
int rv;
|
||||
rv = (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &wstatus) <= -1)? 0: !!WIFEXITED(wstatus);
|
||||
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fnc_wexitstatus (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
hawk_int_t wstatus;
|
||||
int rv;
|
||||
|
||||
hawk_val_t* retv;
|
||||
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &wstatus) <= -1) return -1;
|
||||
retv = hawk_rtx_makeintval(rtx, WEXITSTATUS(wstatus));
|
||||
rv = (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &wstatus) <= -1)? -1: WEXITSTATUS(wstatus);
|
||||
|
||||
retv = hawk_rtx_makeintval(rtx, rv);
|
||||
if (!retv) return -1;
|
||||
|
||||
hawk_rtx_setretval (rtx, retv);
|
||||
return 0;
|
||||
}
|
||||
@ -1159,21 +1153,23 @@ static int fnc_wexitstatus (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
static int fnc_wifsignaled (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
hawk_int_t wstatus;
|
||||
hawk_val_t* retv;
|
||||
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &wstatus) <= -1) return -1;
|
||||
retv = hawk_rtx_makeintval(rtx, WIFSIGNALED(wstatus));
|
||||
if (!retv) return -1;
|
||||
hawk_rtx_setretval (rtx, retv);
|
||||
int rv;
|
||||
rv = (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &wstatus) <= -1)? 0: !!WIFSIGNALED(wstatus);
|
||||
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fnc_wtermsig (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
hawk_int_t wstatus;
|
||||
int rv;
|
||||
|
||||
hawk_val_t* retv;
|
||||
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &wstatus) <= -1) return -1;
|
||||
retv = hawk_rtx_makeintval(rtx, WTERMSIG(wstatus));
|
||||
rv = (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &wstatus) <= -1)? -1: WTERMSIG(wstatus);
|
||||
|
||||
retv = hawk_rtx_makeintval(rtx, rv);
|
||||
if (!retv) return -1;
|
||||
|
||||
hawk_rtx_setretval (rtx, retv);
|
||||
return 0;
|
||||
}
|
||||
@ -1181,11 +1177,9 @@ static int fnc_wtermsig (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
static int fnc_wcoredump (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
hawk_int_t wstatus;
|
||||
hawk_val_t* retv;
|
||||
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &wstatus) <= -1) return -1;
|
||||
retv = hawk_rtx_makeintval(rtx, WCOREDUMP(wstatus));
|
||||
if (!retv) return -1;
|
||||
hawk_rtx_setretval (rtx, retv);
|
||||
int rv;
|
||||
rv = hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &wstatus) <= -1? 0: !!WCOREDUMP(wstatus);
|
||||
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1980,12 +1974,12 @@ static int fnc_getifcfg (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
}
|
||||
|
||||
tmp = hawk_rtx_makemapvalwithdata(rtx, md);
|
||||
if (!tmp) return -1; /* hard failure */
|
||||
if (!tmp) goto fail;
|
||||
|
||||
hawk_rtx_refupval (rtx, tmp);
|
||||
x = hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 2), tmp);
|
||||
hawk_rtx_refdownval (rtx, tmp);
|
||||
if (x <= -1) return -1; /* hard failure */
|
||||
if (x <= -1) goto fail;
|
||||
|
||||
rx = ERRNUM_TO_RC(HAWK_ENOERR);
|
||||
}
|
||||
@ -2003,101 +1997,184 @@ static int fnc_getifcfg (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
|
||||
static int fnc_system (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
sys_list_t* sys_list;
|
||||
hawk_val_t* v, * a0;
|
||||
hawk_ooch_t* str;
|
||||
hawk_oow_t len;
|
||||
int n = 0;
|
||||
hawk_int_t rx;
|
||||
|
||||
a0 = hawk_rtx_getarg (rtx, 0);
|
||||
str = hawk_rtx_getvaloocstr (rtx, a0, &len);
|
||||
if (str == HAWK_NULL) return -1;
|
||||
sys_list = rtx_to_sys_list(rtx, fi);
|
||||
|
||||
/* the target name contains a null character.
|
||||
* make system return -1 */
|
||||
a0 = hawk_rtx_getarg(rtx, 0);
|
||||
str = hawk_rtx_getvaloocstr(rtx, a0, &len);
|
||||
if (!str)
|
||||
{
|
||||
rx = copy_error_to_sys_list(rtx, sys_list);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* the target name contains a null character. make system return -1 */
|
||||
if (hawk_find_oochar(str, len, '\0'))
|
||||
{
|
||||
n = -1;
|
||||
goto skip_system;
|
||||
rx = set_error_on_sys_list(rtx, sys_list, HAWK_EINVAL, HAWK_T("invalid command of length %zu containing '\\0'"), len);
|
||||
goto done;
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
n = _tsystem (str);
|
||||
rx = _tsystem(str);
|
||||
if (rx <= -1) rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL);
|
||||
#elif defined(HAWK_OOCH_IS_BCH)
|
||||
n = system (str);
|
||||
rx = system(str);
|
||||
if (rx <= -1) rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL);
|
||||
#else
|
||||
|
||||
{
|
||||
hawk_bch_t* mbs;
|
||||
mbs = hawk_rtx_duputobcstr(rtx, str, HAWK_NULL);
|
||||
if (mbs == HAWK_NULL)
|
||||
if (mbs)
|
||||
{
|
||||
n = -1;
|
||||
goto skip_system;
|
||||
rx = system(mbs);
|
||||
hawk_rtx_freemem (rtx, mbs);
|
||||
if (rx <= -1) rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
rx = copy_error_to_sys_list(rtx, sys_list);
|
||||
}
|
||||
n = system (mbs);
|
||||
hawk_rtx_freemem (rtx, mbs);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
skip_system:
|
||||
hawk_rtx_freevaloocstr (rtx, a0, str);
|
||||
|
||||
v = hawk_rtx_makeintval(rtx, (hawk_int_t)n);
|
||||
if (v == HAWK_NULL) return -1;
|
||||
done:
|
||||
if (str) hawk_rtx_freevaloocstr (rtx, a0, str);
|
||||
|
||||
HAWK_ASSERT (HAWK_IN_QUICKINT_RANGE(rx));
|
||||
hawk_rtx_setretval (rtx, v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
static int fnc_chmod (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
|
||||
static int fnc_chroot (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
sys_list_t* sys_list;
|
||||
hawk_val_t* v, * a0;
|
||||
hawk_ooch_t* str;
|
||||
hawk_oow_t len;
|
||||
int n = 0;
|
||||
hawk_int_t mode;
|
||||
hawk_int_t rx;
|
||||
|
||||
sys_list = rtx_to_sys_list(rtx, fi);
|
||||
|
||||
a0 = hawk_rtx_getarg(rtx, 0);
|
||||
str = hawk_rtx_getvaloocstr(rtx, a0, &len);
|
||||
if (!str) return -1;
|
||||
if (!str)
|
||||
{
|
||||
rx = copy_error_to_sys_list(rtx, sys_list);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* the target name contains a null character.
|
||||
* make system return -1 */
|
||||
/* the target name contains a null character. make system return -1 */
|
||||
if (hawk_find_oochar(str, len, '\0'))
|
||||
{
|
||||
n = -1;
|
||||
goto skip_mkdir;
|
||||
rx = set_error_on_sys_list(rtx, sys_list, HAWK_EINVAL, HAWK_T("invalid path of length %zu containing '\\0'"), len);
|
||||
goto done;
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* TOOD: implement this*/
|
||||
rx = set_error_on_sys_list(rtx, sys_list, HAWK_ENOIMPL, HAWK_NULL);
|
||||
#elif defined(__OS2__)
|
||||
/* TOOD: implement this*/
|
||||
rx = set_error_on_sys_list(rtx, sys_list, HAWK_ENOIMPL, HAWK_NULL);
|
||||
#elif defined(__DOS__)
|
||||
/* TOOD: implement this*/
|
||||
rx = set_error_on_sys_list(rtx, sys_list, HAWK_ENOIMPL, HAWK_NULL);
|
||||
#elif defined(HAWK_OOCH_IS_BCH)
|
||||
rx = chroot(str, mode);
|
||||
if (rx <= -1) rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL);
|
||||
#else
|
||||
{
|
||||
hawk_bch_t* mbs;
|
||||
mbs = hawk_rtx_duputobcstr(rtx, str, HAWK_NULL);
|
||||
if (mbs)
|
||||
{
|
||||
rx = chroot(mbs);
|
||||
hawk_rtx_freemem (rtx, mbs);
|
||||
if (rx <= -1) rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
rx = copy_error_to_sys_list(rtx, sys_list);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
done:
|
||||
if (str) hawk_rtx_freevaloocstr (rtx, a0, str);
|
||||
|
||||
HAWK_ASSERT (HAWK_IN_QUICKINT_RANGE(rx));
|
||||
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
static int fnc_chmod (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
sys_list_t* sys_list;
|
||||
hawk_val_t* v, * a0;
|
||||
hawk_ooch_t* str;
|
||||
hawk_oow_t len;
|
||||
hawk_int_t rx;
|
||||
hawk_int_t mode;
|
||||
|
||||
sys_list = rtx_to_sys_list(rtx, fi);
|
||||
|
||||
a0 = hawk_rtx_getarg(rtx, 0);
|
||||
str = hawk_rtx_getvaloocstr(rtx, a0, &len);
|
||||
if (!str)
|
||||
{
|
||||
rx = copy_error_to_sys_list(rtx, sys_list);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* the target name contains a null character. make system return -1 */
|
||||
if (hawk_find_oochar(str, len, '\0'))
|
||||
{
|
||||
rx = set_error_on_sys_list(rtx, sys_list, HAWK_EINVAL, HAWK_T("invalid path of length %zu containing '\\0'"), len);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 1), &mode) <= -1 || mode < 0) mode = DEFAULT_MODE;
|
||||
|
||||
#if defined(_WIN32)
|
||||
n = _tchmod(str, mode);
|
||||
rx = _tchmod(str, mode);
|
||||
if (rx <= -1) rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL);
|
||||
#elif defined(HAWK_OOCH_IS_BCH)
|
||||
n = chmod(str, mode);
|
||||
rx = chmod(str, mode);
|
||||
if (rx <= -1) rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL);
|
||||
#else
|
||||
{
|
||||
hawk_bch_t* mbs;
|
||||
mbs = hawk_rtx_duputobcstr(rtx, str, HAWK_NULL);
|
||||
if (mbs == HAWK_NULL)
|
||||
if (mbs)
|
||||
{
|
||||
n = -1;
|
||||
goto skip_mkdir;
|
||||
rx = chmod(mbs, mode);
|
||||
hawk_rtx_freemem (rtx, mbs);
|
||||
if (rx <= -1) rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
rx = copy_error_to_sys_list(rtx, sys_list);
|
||||
}
|
||||
n = chmod(mbs, mode);
|
||||
hawk_rtx_freemem (rtx, mbs);
|
||||
}
|
||||
#endif
|
||||
|
||||
skip_mkdir:
|
||||
hawk_rtx_freevaloocstr (rtx, a0, str);
|
||||
done:
|
||||
if (str) hawk_rtx_freevaloocstr (rtx, a0, str);
|
||||
|
||||
v = hawk_rtx_makeintval(rtx, (hawk_int_t)n);
|
||||
if (v == HAWK_NULL) return -1;
|
||||
|
||||
hawk_rtx_setretval (rtx, v);
|
||||
HAWK_ASSERT (HAWK_IN_QUICKINT_RANGE(rx));
|
||||
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2580,11 +2657,13 @@ static fnctab_t fnctab[] =
|
||||
{ HAWK_T("WIFSIGNALED"), { { 1, 1, HAWK_NULL }, fnc_wifsignaled, 0 } },
|
||||
{ HAWK_T("WTERMSIG"), { { 1, 1, HAWK_NULL }, fnc_wtermsig, 0 } },
|
||||
{ HAWK_T("chmod"), { { 2, 2, HAWK_NULL }, fnc_chmod, 0 } },
|
||||
{ HAWK_T("chroot"), { { 2, 2, HAWK_NULL }, fnc_chroot, 0 } },
|
||||
{ HAWK_T("close"), { { 1, 2, HAWK_NULL }, fnc_close, 0 } },
|
||||
{ HAWK_T("closedir"), { { 1, 1, HAWK_NULL }, fnc_closedir, 0 } },
|
||||
{ HAWK_T("closelog"), { { 0, 0, HAWK_NULL }, fnc_closelog, 0 } },
|
||||
{ HAWK_T("dup"), { { 1, 3, HAWK_NULL }, fnc_dup, 0 } },
|
||||
{ HAWK_T("errmsg"), { { 0, 0, HAWK_NULL }, fnc_errmsg, 0 } },
|
||||
{ HAWK_T("fchmod"), { { 2, 2, HAWK_NULL }, fnc_fchmod, 0 } },
|
||||
{ HAWK_T("fchown"), { { 3, 3, HAWK_NULL }, fnc_fchown, 0 } },
|
||||
{ HAWK_T("fork"), { { 0, 0, HAWK_NULL }, fnc_fork, 0 } },
|
||||
{ HAWK_T("getegid"), { { 0, 0, HAWK_NULL }, fnc_getegid, 0 } },
|
||||
|
Loading…
Reference in New Issue
Block a user