added sys::chroot()
This commit is contained in:
		| @ -59,6 +59,14 @@ | |||||||
| #define CLOSE_KEEPFD (1 << 0) | #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; | 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; | 	hawk_int_t id; | ||||||
| 	sys_node_t* sys_node; | 	sys_node_t* sys_node; | ||||||
|  |  | ||||||
| 	if (hawk_rtx_valtoint(rtx, arg, &id) <= -1) | 	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")); | 		set_errmsg_on_sys_list (rtx, sys_list, HAWK_T("illegal handle value")); | ||||||
| 		return HAWK_NULL; | 		return HAWK_NULL; | ||||||
| 	} | 	} | ||||||
| 	else if (!(sys_node = get_sys_list_node(sys_list, id))) | 	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); | 		set_errmsg_on_sys_list (rtx, sys_list, HAWK_T("invalid handle - %zd"), (hawk_oow_t)id); | ||||||
| 		return HAWK_NULL; | 		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) | 	if (sys_node->ctx.type != node_type) | ||||||
| 	{ | 	{ | ||||||
| 		/* the handle is found but is not of the desired 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")); | 		set_errmsg_on_sys_list (rtx, sys_list, HAWK_T("wrong handle type")); | ||||||
| 		return HAWK_NULL; | 		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_list_t* sys_list; | ||||||
| 	sys_node_t* sys_node; | 	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; | 	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_FD); | 	sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_FD, &rx); | ||||||
|  |  | ||||||
| 	if (hawk_rtx_getnargs(rtx) >= 2 && (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 1), &cflags) <= -1 || cflags < 0)) cflags = 0; |  | ||||||
|  |  | ||||||
| 	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_FD type only */ | 		 * 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 */ | 		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.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); | ||||||
| 		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)); | 	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 */ | 	/* wrap a raw system file descriptor into the internal management node */ | ||||||
|  |  | ||||||
| 	sys_list_t* sys_list; | 	sys_list_t* sys_list; | ||||||
| 	hawk_int_t rx = ERRNUM_TO_RC(HAWK_EOTHER); | 	hawk_int_t rx; | ||||||
| 	hawk_int_t fd; | 	hawk_int_t fd; | ||||||
|  |  | ||||||
| 	sys_list = rtx_to_sys_list(rtx, fi); | 	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); | 		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)); | 	hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx)); | ||||||
| 	return 0; | 	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_list_t* sys_list; | ||||||
| 	sys_node_t* sys_node; | 	sys_node_t* sys_node; | ||||||
| 	hawk_int_t rx = ERRNUM_TO_RC(HAWK_EOTHER); | 	hawk_int_t rx; | ||||||
| 	hawk_int_t reqsize = 8192; | 	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_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 (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) | 		if (reqsize > sys_list->ctx.readbuf_capa) | ||||||
| 		{ | 		{ | ||||||
| 			hawk_bch_t* tmp = hawk_rtx_reallocmem(rtx, sys_list->ctx.readbuf, reqsize); | 			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; | 			int x; | ||||||
|  |  | ||||||
| 			sv = hawk_rtx_makembsval(rtx, sys_list->ctx.readbuf, rx); | 			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); | 			hawk_rtx_refupval (rtx, sv); | ||||||
| 			x = hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 1), sv); | 			x = hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 1), sv); | ||||||
| 			hawk_rtx_refdownval (rtx, 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: | done: | ||||||
| 	/* the value in 'rx' never exceeds HAWK_QUICKINT_MAX as 'reqsize' has been limited to | 	/* 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_list_t* sys_list; | ||||||
| 	sys_node_t* sys_node; | 	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_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 (sys_node) | ||||||
| 	{ | 	{ | ||||||
| 		hawk_bch_t* dptr; | 		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); | 			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)); | 	hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx)); | ||||||
| 	return 0; | 	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_list_t* sys_list; | ||||||
| 	sys_node_t* sys_node, * sys_node2 = HAWK_NULL; | 	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; | 	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_FD); | 	sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_FD, &rx); | ||||||
| 	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; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (sys_node) | 	if (sys_node) | ||||||
| 	{ | 	{ | ||||||
| 		int fd; | 		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 (sys_node2) | ||||||
| 		{ | 		{ | ||||||
| 		#if defined(HAVE_DUP3) | 		#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)); | 	hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx)); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| @ -730,7 +729,7 @@ static int fnc_pipe (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | |||||||
| 	/* create low-level pipes */ | 	/* create low-level pipes */ | ||||||
|  |  | ||||||
| 	sys_list_t* sys_list; | 	sys_list_t* sys_list; | ||||||
| 	hawk_int_t rx = ERRNUM_TO_RC(HAWK_EOTHER); | 	hawk_int_t rx; | ||||||
| 	int fds[2]; | 	int fds[2]; | ||||||
| 	hawk_int_t flags = 0; | 	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) | 			if (nflags > 0) | ||||||
| 			{ | 			{ | ||||||
|  | 				/* don't care about failure */ | ||||||
| 				fcntl (fds[0], F_SETFD, nflags); | 				fcntl (fds[0], F_SETFD, nflags); | ||||||
| 				fcntl (fds[1], 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; | 			int x; | ||||||
|  |  | ||||||
| 			v = hawk_rtx_makeintval(rtx, node1->id); | 			v = hawk_rtx_makeintval(rtx, node1->id); | ||||||
| 			if (!v)  | 			if (!v) goto fail; | ||||||
| 			{ |  | ||||||
| 			fail: |  | ||||||
| 				free_sys_node (rtx, sys_list, node1); |  | ||||||
| 				free_sys_node (rtx, sys_list, node2); |  | ||||||
| 				return -1; |  | ||||||
| 			} |  | ||||||
| 			hawk_rtx_refupval (rtx, v); | 			hawk_rtx_refupval (rtx, v); | ||||||
| 			x = hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 0), v); | 			x = hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 0), v); | ||||||
| 			hawk_rtx_refdownval (rtx, 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); | 			hawk_rtx_refdownval (rtx, v); | ||||||
| 			if (x <= -1) goto fail; | 			if (x <= -1) goto fail; | ||||||
|  |  | ||||||
| 			rx = ERRNUM_TO_RC(HAWK_ENOERR); | 			/* successful so far */ | ||||||
|  | 			rx =  ERRNUM_TO_RC(HAWK_ENOERR); | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
|  | 		fail: | ||||||
| 			rx = copy_error_to_sys_list(rtx, sys_list); | 			rx = copy_error_to_sys_list(rtx, sys_list); | ||||||
|  |  | ||||||
| 			if (node2) free_sys_node (rtx, sys_list, node2); | 			if (node2) free_sys_node (rtx, sys_list, node2); | ||||||
|  | 			else close(fds[1]); | ||||||
| 			if (node1) free_sys_node (rtx, sys_list, node1); | 			if (node1) free_sys_node (rtx, sys_list, node1); | ||||||
|  | 			else close(fds[0]); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	else | 	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_list_t* sys_list; | ||||||
| 	sys_node_t* sys_node; | 	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_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 (sys_node) | ||||||
| 	{ | 	{ | ||||||
| 		hawk_int_t uid, gid; | 		hawk_int_t uid, gid; | ||||||
| @ -834,15 +834,38 @@ 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.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); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	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); | 		hawk_int_t mode; | ||||||
| 		/* error information set in get_sys_list_node_with_arg() */ |  | ||||||
|  | 		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)); | 	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_list_t* sys_list; | ||||||
| 	sys_node_t* sys_node; | 	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_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) | 	if (sys_node) | ||||||
| 	{ | 	{ | ||||||
| 		/* although free_sys_node() can handle other types, sys::closedir() is allowed to | 		/* although free_sys_node() can handle other types, sys::closedir() is allowed to | ||||||
| 		 * close nodes of the SYS_NODE_DATA_DIR type only */ | 		 * close nodes of the SYS_NODE_DATA_DIR type only */ | ||||||
| 		free_sys_node (rtx, sys_list, sys_node); | 		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)); | 	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_list_t* sys_list; | ||||||
| 	sys_node_t* sys_node; | 	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_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) | 	if (sys_node) | ||||||
| 	{ | 	{ | ||||||
| 		int y; | 		int y; | ||||||
| 		hawk_dir_ent_t ent; | 		hawk_dir_ent_t ent; | ||||||
| 		hawk_val_t* tmp; |  | ||||||
|  |  | ||||||
| 		y = hawk_dir_read(sys_node->ctx.u.dir, &ent); | 		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 (y <= -1) | 		if (rx <= -1) | ||||||
| 		{ | 		{ | ||||||
| 			goto fail; | 		fail: | ||||||
|  | 			rx = copy_error_to_sys_list(rtx, sys_list); | ||||||
| 		} | 		} | ||||||
| 		else if (y == 0)  | 		else if (rx > 0) | ||||||
| 		{ |  | ||||||
| 			rx = 0; /* no more entry */ |  | ||||||
| 		} |  | ||||||
| 		else |  | ||||||
| 		{ | 		{ | ||||||
|  | 			hawk_val_t* tmp; | ||||||
|  | 			int x; | ||||||
|  |  | ||||||
| 			tmp = hawk_rtx_makestrvalwithoocstr(rtx, ent.name); | 			tmp = hawk_rtx_makestrvalwithoocstr(rtx, ent.name); | ||||||
| 			if (!tmp) | 			if (!tmp) goto fail; | ||||||
| 			{ |  | ||||||
| 			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; |  | ||||||
|  |  | ||||||
| 				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)); | 	hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx)); | ||||||
| 	return 0; | 	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_list_t* sys_list; | ||||||
| 	sys_node_t* sys_node; | 	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_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) | 	if (sys_node) | ||||||
| 	{ | 	{ | ||||||
| @ -1021,7 +1021,6 @@ static int fnc_resetdir (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | |||||||
| 		if (path) | 		if (path) | ||||||
| 		{ | 		{ | ||||||
| 			if (hawk_dir_reset(sys_node->ctx.u.dir, path) <= -1) goto fail; | 			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); | 			hawk_rtx_freevaloocstr (rtx, a1, path); | ||||||
| 		} | 		} | ||||||
| 		else | 		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); | 			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  | 	/* no error check for hawk_rtx_makeintval() here since ret  | ||||||
| 	 * is 0 or -1. it will never fail for those numbers */ | 	 * 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 | #endif | ||||||
|  |  | ||||||
| 	retv = hawk_rtx_makeintval(rtx, rx); | 	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); | 	hawk_rtx_setretval (rtx, retv); | ||||||
| 	return 0; | 	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); | 	sys_list_t* sys_list = rtx_to_sys_list(rtx, fi); | ||||||
|  |  | ||||||
| 	nargs = hawk_rtx_getnargs(rtx); | 	nargs = hawk_rtx_getnargs(rtx); | ||||||
| 	if (nargs >= 3 && hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 2), &opts) <= -1)  | 	if (nargs >= 3 && hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 2), &opts) <= -1) goto fail; | ||||||
| 	{ |  | ||||||
| 	fail: |  | ||||||
| 		rx = copy_error_to_sys_list(rtx, sys_list); |  | ||||||
| 		goto done; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &pid) <= -1) goto fail; | 	if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &pid) <= -1) goto fail; | ||||||
| 	 | 	 | ||||||
| #if defined(_WIN32) | #if defined(_WIN32) | ||||||
| @ -1105,30 +1093,34 @@ static int fnc_wait (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | |||||||
| 	status = 0; | 	status = 0; | ||||||
| #else | #else | ||||||
| 	rx = waitpid(pid, &status, opts); | 	rx = waitpid(pid, &status, opts); | ||||||
| 	if (rx <= -1) rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL); | 	if (rx <= -1)  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| done: |  | ||||||
| 	retv = hawk_rtx_makeintval(rtx, rx); |  | ||||||
| 	if (!retv) return -1; |  | ||||||
|  |  | ||||||
| 	if (nargs >= 2) |  | ||||||
| 	{ | 	{ | ||||||
| 		hawk_val_t* sv; | 		rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL); | ||||||
| 		int x; | 	} | ||||||
|  | 	else | ||||||
| 		sv = hawk_rtx_makeintval(rtx, status); | 	{ | ||||||
| 		if (!sv) return -1; | 		if (nargs >= 2) | ||||||
|  |  | ||||||
| 		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)   |  | ||||||
| 		{ | 		{ | ||||||
| 			hawk_rtx_freemem (rtx, retv); | 			hawk_val_t* sv; | ||||||
| 			return -1; | 			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); | 	hawk_rtx_setretval (rtx, retv); | ||||||
| 	return 0; | 	return 0; | ||||||
| @ -1137,21 +1129,23 @@ done: | |||||||
| static int fnc_wifexited (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | static int fnc_wifexited (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | ||||||
| { | { | ||||||
| 	hawk_int_t wstatus; | 	hawk_int_t wstatus; | ||||||
| 	hawk_val_t* retv; | 	int rv; | ||||||
| 	if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &wstatus) <= -1) return -1; | 	rv = (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &wstatus) <= -1)? 0: !!WIFEXITED(wstatus); | ||||||
| 	retv = hawk_rtx_makeintval(rtx, WIFEXITED(wstatus)); | 	hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rv)); | ||||||
| 	if (!retv) return -1; |  | ||||||
| 	hawk_rtx_setretval (rtx, retv); |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int fnc_wexitstatus (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | static int fnc_wexitstatus (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | ||||||
| { | { | ||||||
| 	hawk_int_t wstatus; | 	hawk_int_t wstatus; | ||||||
|  | 	int rv; | ||||||
|  |  | ||||||
| 	hawk_val_t* retv; | 	hawk_val_t* retv; | ||||||
| 	if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &wstatus) <= -1) return -1; | 	rv = (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &wstatus) <= -1)? -1: WEXITSTATUS(wstatus); | ||||||
| 	retv = hawk_rtx_makeintval(rtx, WEXITSTATUS(wstatus)); |  | ||||||
|  | 	retv = hawk_rtx_makeintval(rtx, rv); | ||||||
| 	if (!retv) return -1; | 	if (!retv) return -1; | ||||||
|  |  | ||||||
| 	hawk_rtx_setretval (rtx, retv); | 	hawk_rtx_setretval (rtx, retv); | ||||||
| 	return 0; | 	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) | static int fnc_wifsignaled (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | ||||||
| { | { | ||||||
| 	hawk_int_t wstatus; | 	hawk_int_t wstatus; | ||||||
| 	hawk_val_t* retv; | 	int rv; | ||||||
| 	if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &wstatus) <= -1) return -1; | 	rv = (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &wstatus) <= -1)? 0: !!WIFSIGNALED(wstatus); | ||||||
| 	retv = hawk_rtx_makeintval(rtx, WIFSIGNALED(wstatus)); | 	hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rv)); | ||||||
| 	if (!retv) return -1; |  | ||||||
| 	hawk_rtx_setretval (rtx, retv); |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int fnc_wtermsig (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | static int fnc_wtermsig (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | ||||||
| { | { | ||||||
| 	hawk_int_t wstatus; | 	hawk_int_t wstatus; | ||||||
|  | 	int rv; | ||||||
|  |  | ||||||
| 	hawk_val_t* retv; | 	hawk_val_t* retv; | ||||||
| 	if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &wstatus) <= -1) return -1; | 	rv = (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &wstatus) <= -1)? -1: WTERMSIG(wstatus); | ||||||
| 	retv = hawk_rtx_makeintval(rtx, WTERMSIG(wstatus)); |  | ||||||
|  | 	retv = hawk_rtx_makeintval(rtx, rv); | ||||||
| 	if (!retv) return -1; | 	if (!retv) return -1; | ||||||
|  |  | ||||||
| 	hawk_rtx_setretval (rtx, retv); | 	hawk_rtx_setretval (rtx, retv); | ||||||
| 	return 0; | 	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) | static int fnc_wcoredump (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | ||||||
| { | { | ||||||
| 	hawk_int_t wstatus; | 	hawk_int_t wstatus; | ||||||
| 	hawk_val_t* retv; | 	int rv; | ||||||
| 	if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &wstatus) <= -1) return -1; | 	rv = hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &wstatus) <= -1? 0: !!WCOREDUMP(wstatus); | ||||||
| 	retv = hawk_rtx_makeintval(rtx, WCOREDUMP(wstatus)); | 	hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rv)); | ||||||
| 	if (!retv) return -1; |  | ||||||
| 	hawk_rtx_setretval (rtx, retv); |  | ||||||
| 	return 0; | 	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); | 		tmp = hawk_rtx_makemapvalwithdata(rtx, md); | ||||||
| 		if (!tmp) return -1; /* hard failure */ | 		if (!tmp) goto fail; | ||||||
|  |  | ||||||
| 		hawk_rtx_refupval (rtx, tmp); | 		hawk_rtx_refupval (rtx, tmp); | ||||||
| 		x = hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 2), tmp); | 		x = hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 2), tmp); | ||||||
| 		hawk_rtx_refdownval (rtx, tmp); | 		hawk_rtx_refdownval (rtx, tmp); | ||||||
| 		if (x <= -1) return -1; /* hard failure */ | 		if (x <= -1) goto fail; | ||||||
|  |  | ||||||
| 		rx = ERRNUM_TO_RC(HAWK_ENOERR); | 		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) | 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_val_t* v, * a0; | ||||||
| 	hawk_ooch_t* str; | 	hawk_ooch_t* str; | ||||||
| 	hawk_oow_t len; | 	hawk_oow_t len; | ||||||
| 	int n = 0; | 	hawk_int_t rx; | ||||||
|  |  | ||||||
| 	a0 = hawk_rtx_getarg (rtx, 0); | 	sys_list = rtx_to_sys_list(rtx, fi); | ||||||
| 	str = hawk_rtx_getvaloocstr (rtx, a0, &len); |  | ||||||
| 	if (str == HAWK_NULL) return -1; |  | ||||||
|  |  | ||||||
| 	/* the target name contains a null character. | 	a0 = hawk_rtx_getarg(rtx, 0); | ||||||
| 	 * make system return -1 */ | 	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')) | 	if (hawk_find_oochar(str, len, '\0')) | ||||||
| 	{ | 	{ | ||||||
| 		n = -1; | 		rx = set_error_on_sys_list(rtx, sys_list, HAWK_EINVAL, HAWK_T("invalid command of length %zu containing '\\0'"), len); | ||||||
| 		goto skip_system; | 		goto done; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| #if defined(_WIN32) | #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) | #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 | #else | ||||||
|  |  | ||||||
| 	{ | 	{ | ||||||
| 		hawk_bch_t* mbs; | 		hawk_bch_t* mbs; | ||||||
| 		mbs = hawk_rtx_duputobcstr(rtx, str, HAWK_NULL); | 		mbs = hawk_rtx_duputobcstr(rtx, str, HAWK_NULL); | ||||||
| 		if (mbs == HAWK_NULL)  | 		if (mbs) | ||||||
| 		{ | 		{ | ||||||
| 			n = -1; | 			rx = system(mbs); | ||||||
| 			goto skip_system; | 			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 | #endif | ||||||
|  |  | ||||||
| skip_system: | done: | ||||||
| 	hawk_rtx_freevaloocstr (rtx, a0, str); | 	if (str) hawk_rtx_freevaloocstr (rtx, a0, str); | ||||||
|  |  | ||||||
| 	v = hawk_rtx_makeintval(rtx, (hawk_int_t)n); |  | ||||||
| 	if (v == HAWK_NULL) return -1; |  | ||||||
|  |  | ||||||
|  | 	HAWK_ASSERT (HAWK_IN_QUICKINT_RANGE(rx)); | ||||||
| 	hawk_rtx_setretval (rtx, v); | 	hawk_rtx_setretval (rtx, v); | ||||||
| 	return 0; | 	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_val_t* v, * a0; | ||||||
| 	hawk_ooch_t* str; | 	hawk_ooch_t* str; | ||||||
| 	hawk_oow_t len; | 	hawk_oow_t len; | ||||||
| 	int n = 0; | 	hawk_int_t rx; | ||||||
| 	hawk_int_t mode; |  | ||||||
|  | 	sys_list = rtx_to_sys_list(rtx, fi); | ||||||
|  |  | ||||||
| 	a0 = hawk_rtx_getarg(rtx, 0); | 	a0 = hawk_rtx_getarg(rtx, 0); | ||||||
| 	str = hawk_rtx_getvaloocstr(rtx, a0, &len); | 	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. | 	/* the target name contains a null character. make system return -1 */ | ||||||
| 	 * make system return -1 */ |  | ||||||
| 	if (hawk_find_oochar(str, len, '\0')) | 	if (hawk_find_oochar(str, len, '\0')) | ||||||
| 	{ | 	{ | ||||||
| 		n = -1; | 		rx = set_error_on_sys_list(rtx, sys_list, HAWK_EINVAL, HAWK_T("invalid path of length %zu containing '\\0'"), len); | ||||||
| 		goto skip_mkdir; | 		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 (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 1), &mode) <= -1 || mode < 0) mode = DEFAULT_MODE; | ||||||
|  |  | ||||||
| #if defined(_WIN32) | #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) | #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 | #else | ||||||
| 	{ | 	{ | ||||||
| 		hawk_bch_t* mbs; | 		hawk_bch_t* mbs; | ||||||
| 		mbs = hawk_rtx_duputobcstr(rtx, str, HAWK_NULL); | 		mbs = hawk_rtx_duputobcstr(rtx, str, HAWK_NULL); | ||||||
| 		if (mbs == HAWK_NULL)  | 		if (mbs) | ||||||
| 		{ | 		{ | ||||||
| 			n = -1; | 			rx = chmod(mbs, mode); | ||||||
| 			goto skip_mkdir; | 			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 | #endif | ||||||
|  |  | ||||||
| skip_mkdir: | done: | ||||||
| 	hawk_rtx_freevaloocstr (rtx, a0, str); | 	if (str) hawk_rtx_freevaloocstr (rtx, a0, str); | ||||||
|  |  | ||||||
| 	v = hawk_rtx_makeintval(rtx, (hawk_int_t)n); | 	HAWK_ASSERT (HAWK_IN_QUICKINT_RANGE(rx)); | ||||||
| 	if (v == HAWK_NULL) return -1; | 	hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx)); | ||||||
|  |  | ||||||
| 	hawk_rtx_setretval (rtx, v); |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -2580,11 +2657,13 @@ static fnctab_t fnctab[] = | |||||||
| 	{ HAWK_T("WIFSIGNALED"), { { 1, 1, HAWK_NULL     }, fnc_wifsignaled, 0  } }, | 	{ HAWK_T("WIFSIGNALED"), { { 1, 1, HAWK_NULL     }, fnc_wifsignaled, 0  } }, | ||||||
| 	{ HAWK_T("WTERMSIG"),    { { 1, 1, HAWK_NULL     }, fnc_wtermsig,    0  } }, | 	{ HAWK_T("WTERMSIG"),    { { 1, 1, HAWK_NULL     }, fnc_wtermsig,    0  } }, | ||||||
| 	{ HAWK_T("chmod"),       { { 2, 2, HAWK_NULL     }, fnc_chmod,       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("close"),       { { 1, 2, HAWK_NULL     }, fnc_close,       0  } }, | ||||||
| 	{ HAWK_T("closedir"),    { { 1, 1, HAWK_NULL     }, fnc_closedir,    0  } }, | 	{ HAWK_T("closedir"),    { { 1, 1, HAWK_NULL     }, fnc_closedir,    0  } }, | ||||||
| 	{ HAWK_T("closelog"),    { { 0, 0, HAWK_NULL     }, fnc_closelog,    0  } }, | 	{ HAWK_T("closelog"),    { { 0, 0, HAWK_NULL     }, fnc_closelog,    0  } }, | ||||||
| 	{ HAWK_T("dup"),         { { 1, 3, HAWK_NULL     }, fnc_dup,         0  } }, | 	{ HAWK_T("dup"),         { { 1, 3, HAWK_NULL     }, fnc_dup,         0  } }, | ||||||
| 	{ HAWK_T("errmsg"),      { { 0, 0, HAWK_NULL     }, fnc_errmsg,      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("fchown"),      { { 3, 3, HAWK_NULL     }, fnc_fchown,      0  } }, | ||||||
| 	{ HAWK_T("fork"),        { { 0, 0, HAWK_NULL     }, fnc_fork,        0  } }, | 	{ HAWK_T("fork"),        { { 0, 0, HAWK_NULL     }, fnc_fork,        0  } }, | ||||||
| 	{ HAWK_T("getegid"),     { { 0, 0, HAWK_NULL     }, fnc_getegid,     0  } }, | 	{ HAWK_T("getegid"),     { { 0, 0, HAWK_NULL     }, fnc_getegid,     0  } }, | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user