added sys::setsockopt()
enhanced mux handling in mod-sys.c
This commit is contained in:
		| @ -348,12 +348,29 @@ static void del_from_mux (hawk_rtx_t* rtx, sys_node_t* fd_node) | |||||||
| 		{ | 		{ | ||||||
| 			case SYS_NODE_DATA_TYPE_FILE: | 			case SYS_NODE_DATA_TYPE_FILE: | ||||||
| 			case SYS_NODE_DATA_TYPE_SCK: | 			case SYS_NODE_DATA_TYPE_SCK: | ||||||
|  | 			{ | ||||||
|  | 				hawk_oow_t i; | ||||||
|  | 				sys_node_data_mux_t* mux_data; | ||||||
|  |  | ||||||
| 				mux_node = (sys_node_t*)fd_node->ctx.u.file.mux; | 				mux_node = (sys_node_t*)fd_node->ctx.u.file.mux; | ||||||
|  | 				mux_data = &mux_node->ctx.u.mux; | ||||||
|  |  | ||||||
|  | 				for (i = 0; i < mux_data->x_evt_count; i++) | ||||||
|  | 				{ | ||||||
|  | 				#if defined(USE_EPOLL) | ||||||
|  | 					if (mux_data->x_evt[i].data.ptr && fd_node->id == ((sys_node_t*)mux_data->x_evt[i].data.ptr)->id) | ||||||
|  | 					{ | ||||||
|  | 						/* nullify the event in the event array to prevent normal access by sys::getmuxevt() */ | ||||||
|  | 						mux_data->x_evt[i].data.ptr = HAWK_NULL; | ||||||
|  | 					} | ||||||
|  | 				#endif | ||||||
|  | 				} | ||||||
| 			#if defined(USE_EPOLL) | 			#if defined(USE_EPOLL) | ||||||
| 				epoll_ctl (mux_node->ctx.u.mux.fd, MUX_CTL_DEL, fd_node->ctx.u.file.fd, &ev); | 				epoll_ctl (mux_node->ctx.u.mux.fd, MUX_CTL_DEL, fd_node->ctx.u.file.fd, &ev); | ||||||
| 			#endif | 			#endif | ||||||
| 				unchain_sys_node_from_mux_node (mux_node, fd_node); | 				unchain_sys_node_from_mux_node (mux_node, fd_node); | ||||||
| 				break; | 				break; | ||||||
|  | 			} | ||||||
|  |  | ||||||
| 			default: | 			default: | ||||||
| 				/* do nothing */ | 				/* do nothing */ | ||||||
| @ -401,6 +418,14 @@ static void free_sys_node (hawk_rtx_t* rtx, sys_list_t* list, sys_node_t* node) | |||||||
| 				purge_mux_members (rtx, node); | 				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; | ||||||
|  |  | ||||||
|  | 				if (node->ctx.u.mux.x_evt) | ||||||
|  | 				{ | ||||||
|  | 					hawk_rtx_freemem (rtx, node->ctx.u.mux.x_evt); | ||||||
|  | 					node->ctx.u.mux.x_evt = HAWK_NULL; | ||||||
|  | 				} | ||||||
|  | 				node->ctx.u.mux.x_evt_max = 0; | ||||||
|  | 				node->ctx.u.mux.x_evt_count = 0; | ||||||
| 			} | 			} | ||||||
| 		#endif | 		#endif | ||||||
| 			break; | 			break; | ||||||
| @ -1697,72 +1722,73 @@ static int fnc_getegid (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int fnc_sleep (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | static int val_to_ntime (hawk_rtx_t* rtx, hawk_val_t* val, hawk_ntime_t* nt) | ||||||
| { | { | ||||||
| 	hawk_int_t lv; | 	hawk_int_t lv; | ||||||
| 	hawk_flt_t fv; | 	hawk_flt_t fv; | ||||||
|  | 	int x; | ||||||
|  |  | ||||||
|  | 	x = hawk_rtx_valtonum(rtx, val, &lv, &fv); | ||||||
|  | 	if (x == 0) | ||||||
|  | 	{ | ||||||
|  | 		nt->sec = lv; | ||||||
|  | 		nt->nsec = 0; | ||||||
|  | 	} | ||||||
|  | 	else if (x >= 1) | ||||||
|  | 	{ | ||||||
|  | 		nt->sec = (hawk_int_t)fv; | ||||||
|  | 		nt->nsec = HAWK_SEC_TO_NSEC(fv - nt->sec); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return x; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int fnc_sleep (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | ||||||
|  | { | ||||||
|  | 	hawk_ntime_t nt; | ||||||
| 	hawk_val_t* retv; | 	hawk_val_t* retv; | ||||||
| 	hawk_int_t rx; | 	hawk_int_t rx; | ||||||
|  | 	sys_list_t* sys_list = rtx_to_sys_list(rtx, fi); | ||||||
|  |  | ||||||
| 	rx = hawk_rtx_valtonum(rtx, hawk_rtx_getarg (rtx, 0), &lv, &fv); | 	rx = val_to_ntime(rtx, hawk_rtx_getarg(rtx, 0), &nt); | ||||||
| 	if (rx == 0) | 	if (rx <= -1) | ||||||
| 	{ | 	{ | ||||||
| #if defined(_WIN32) | 		rx = copy_error_to_sys_list(rtx, sys_list); | ||||||
| 		Sleep ((DWORD)HAWK_SEC_TO_MSEC(lv)); | 		goto done; | ||||||
| 		rx = 0; |  | ||||||
| #elif defined(__OS2__) |  | ||||||
| 		DosSleep ((ULONG)HAWK_SEC_TO_MSEC(lv)); |  | ||||||
| 		rx = 0; |  | ||||||
| #elif defined(__DOS__) |  | ||||||
| 		#if (defined(__WATCOMC__) && (__WATCOMC__ < 1200)) |  | ||||||
| 			sleep (lv); |  | ||||||
| 			rx = 0; |  | ||||||
| 		#else |  | ||||||
| 			rx = sleep (lv); |  | ||||||
| 		#endif |  | ||||||
| #elif defined(HAVE_NANOSLEEP) |  | ||||||
| 		struct timespec req; |  | ||||||
| 		req.tv_sec = lv; |  | ||||||
| 		req.tv_nsec = 0; |  | ||||||
| 		rx = nanosleep(&req, HAWK_NULL); |  | ||||||
| #else |  | ||||||
| 		rx = sleep(lv); |  | ||||||
| #endif |  | ||||||
| 	} | 	} | ||||||
| 	else if (rx >= 1) |  | ||||||
| 	{ |  | ||||||
| #if defined(_WIN32) | #if defined(_WIN32) | ||||||
| 		Sleep ((DWORD)HAWK_SEC_TO_MSEC(fv)); | 	Sleep (HAWK_SECNSEC_TO_MSEC(nt.sec, nt.nsec)); | ||||||
| 		rx = 0; | 	rx = 0; | ||||||
| #elif defined(__OS2__) | #elif defined(__OS2__) | ||||||
| 		DosSleep ((ULONG)HAWK_SEC_TO_MSEC(fv)); | 	DosSleep ((ULONG)HAWK_SECNSEC_TO_MSEC(nt.sec, nt.nsec))); | ||||||
| 		rx = 0; | 	rx = 0; | ||||||
| #elif defined(__DOS__) | #elif defined(__DOS__) | ||||||
| 		/* no high-resolution sleep() is available */ | 	/* no high-resolution sleep() is available */ | ||||||
| 		#if (defined(__WATCOMC__) && (__WATCOMC__ < 1200)) | 	#if (defined(__WATCOMC__) && (__WATCOMC__ < 1200)) | ||||||
| 			sleep ((hawk_int_t)fv); | 	sleep (nt.sec); | ||||||
| 			rx = 0; | 	rx = 0; | ||||||
| 		#else | 	#else | ||||||
| 			rx = sleep((hawk_int_t)fv); | 	rx = sleep(nt.sec); | ||||||
| 		#endif; | 	#endif; | ||||||
| #elif defined(HAVE_NANOSLEEP) | #elif defined(HAVE_NANOSLEEP) | ||||||
| 		struct timespec req; | 	struct timespec req; | ||||||
| 		req.tv_sec = (hawk_int_t)fv; | 	req.tv_sec = nt.sec; | ||||||
| 		req.tv_nsec = HAWK_SEC_TO_NSEC(fv - req.tv_sec); | 	req.tv_nsec = nt.nsec; | ||||||
| 		rx = nanosleep(&req, HAWK_NULL); | 	rx = nanosleep(&req, HAWK_NULL); | ||||||
| #elif defined(HAVE_SELECT) | #elif defined(HAVE_SELECT) | ||||||
| 		struct timeval req; | 	struct timeval req; | ||||||
| 		req.tv_sec = (hawk_int_t)fv; | 	req.tv_sec = nt.sec; | ||||||
| 		req.tv_usec = HAWK_SEC_TO_USEC(fv - req.tv_sec); | 	req.tv_usec = HAWK_NSEC_TO_USEC(nt.nsec); | ||||||
| 		rx = select(0, HAWK_NULL, HAWK_NULL, HAWK_NULL, &req); | 	rx = select(0, HAWK_NULL, HAWK_NULL, HAWK_NULL, &req); | ||||||
| #else | #else | ||||||
| 		/* no high-resolution sleep() is available */ | 	/* no high-resolution sleep() is available */ | ||||||
| 		rx = sleep((hawk_int_t)fv); | 	rx = sleep(nt.sec); | ||||||
| #endif | #endif | ||||||
| 	} |  | ||||||
|  |  | ||||||
|  | done: | ||||||
| 	retv = hawk_rtx_makeintval(rtx, rx); | 	retv = hawk_rtx_makeintval(rtx, rx); | ||||||
| 	if (retv == HAWK_NULL) return -1; | 	if (!retv) return -1; | ||||||
|  |  | ||||||
| 	hawk_rtx_setretval (rtx, retv); | 	hawk_rtx_setretval (rtx, retv); | ||||||
| 	return 0; | 	return 0; | ||||||
| @ -1776,7 +1802,7 @@ static int fnc_gettime (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | |||||||
| 	if (hawk_get_time (&now) <= -1) now.sec = 0; | 	if (hawk_get_time (&now) <= -1) now.sec = 0; | ||||||
|  |  | ||||||
| 	retv = hawk_rtx_makeintval(rtx, now.sec); | 	retv = hawk_rtx_makeintval(rtx, now.sec); | ||||||
| 	if (retv == HAWK_NULL) return -1; | 	if (!retv) return -1; | ||||||
|  |  | ||||||
| 	hawk_rtx_setretval (rtx, retv); | 	hawk_rtx_setretval (rtx, retv); | ||||||
| 	return 0; | 	return 0; | ||||||
| @ -1800,7 +1826,7 @@ static int fnc_settime (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	retv = hawk_rtx_makeintval(rtx, rx); | 	retv = hawk_rtx_makeintval(rtx, rx); | ||||||
| 	if (retv == HAWK_NULL) return -1; | 	if (!retv) return -1; | ||||||
|  |  | ||||||
| 	hawk_rtx_setretval (rtx, retv); | 	hawk_rtx_setretval (rtx, retv); | ||||||
| 	return 0; | 	return 0; | ||||||
| @ -3042,9 +3068,9 @@ static int fnc_waitonmux (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | |||||||
| 	if (sys_node) | 	if (sys_node) | ||||||
| 	{ | 	{ | ||||||
| 		sys_node_data_mux_t* mux_data = &sys_node->ctx.u.mux; | 		sys_node_data_mux_t* mux_data = &sys_node->ctx.u.mux; | ||||||
| 		hawk_int_t tmout; | 		hawk_ntime_t tmout; | ||||||
|  |  | ||||||
| 		if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 1), &tmout) <= -1) tmout = -1; | 		if (val_to_ntime(rtx, hawk_rtx_getarg(rtx, 1), &tmout) <= -1 || tmout.sec <= -1) { tmout.sec = 0; tmout.nsec = HAWK_MSEC_TO_NSEC(-1); } | ||||||
|  |  | ||||||
| 		if (mux_data->x_evt_max < mux_data->x_count) | 		if (mux_data->x_evt_max < mux_data->x_count) | ||||||
| 		{ | 		{ | ||||||
| @ -3060,7 +3086,11 @@ static int fnc_waitonmux (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | |||||||
| 			mux_data->x_evt_max = HAWK_ALIGN(mux_data->x_count, 64); | 			mux_data->x_evt_max = HAWK_ALIGN(mux_data->x_count, 64); | ||||||
| 			mux_data->x_evt = tmp; | 			mux_data->x_evt = tmp; | ||||||
| 		} | 		} | ||||||
| 		if ((rx = epoll_wait(sys_node->ctx.u.mux.fd, mux_data->x_evt, mux_data->x_evt_max, tmout)) <= -1) |  | ||||||
|  | 		/* once this function is called, invalid the exising event data regardless of success or failure */ | ||||||
|  | 		mux_data->x_evt_count = 0;  | ||||||
|  |  | ||||||
|  | 		if ((rx = epoll_wait(sys_node->ctx.u.mux.fd, mux_data->x_evt, mux_data->x_evt_max, HAWK_SECNSEC_TO_MSEC(tmout.sec, tmout.nsec))) <= -1) | ||||||
| 		{ | 		{ | ||||||
| 			rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL); | 			rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL); | ||||||
| 		} | 		} | ||||||
| @ -3094,7 +3124,7 @@ static int fnc_getmuxevt (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | |||||||
| 	{ | 	{ | ||||||
| 		sys_node_data_mux_t* mux_data = &sys_node->ctx.u.mux; | 		sys_node_data_mux_t* mux_data = &sys_node->ctx.u.mux; | ||||||
| 		sys_node_t* file_node; | 		sys_node_t* file_node; | ||||||
| 		hawk_int_t index; | 		hawk_int_t index, id, evts; | ||||||
| 		int x; | 		int x; | ||||||
|  |  | ||||||
| 		if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 1), &index) <= -1) | 		if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 1), &index) <= -1) | ||||||
| @ -3112,6 +3142,12 @@ static int fnc_getmuxevt (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		file_node = mux_data->x_evt[index].data.ptr; | 		file_node = mux_data->x_evt[index].data.ptr; | ||||||
|  | 		if (!file_node) | ||||||
|  | 		{ | ||||||
|  | 			/* has it been closed before it's retrieved with sys::getmuxevt()? */ | ||||||
|  | 			rx = set_error_on_sys_list (rtx, sys_list, HAWK_ENOENT, HAWK_NULL); | ||||||
|  | 			goto done; | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		HAWK_ASSERT (HAWK_IN_QUICKINT_RANGE(file_node->id)); | 		HAWK_ASSERT (HAWK_IN_QUICKINT_RANGE(file_node->id)); | ||||||
| 		x = hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 2), hawk_rtx_makeintval(rtx, file_node->id)); | 		x = hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 2), hawk_rtx_makeintval(rtx, file_node->id)); | ||||||
| @ -3544,6 +3580,77 @@ done: | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static int fnc_setsockopt (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_TYPE_SCK, &rx); | ||||||
|  | 	if (sys_node) | ||||||
|  | 	{ | ||||||
|  | 		hawk_int_t level, optname; | ||||||
|  | 		int iv; | ||||||
|  | 		struct timeval tv; | ||||||
|  | 		void* vptr; | ||||||
|  | 		hawk_oow_t vlen; | ||||||
|  |  | ||||||
|  | 		if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 1), &level) <= -1 || | ||||||
|  | 		    hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 2), &optname) <= -1) | ||||||
|  | 		{ | ||||||
|  | 		fail: | ||||||
|  | 			rx = copy_error_to_sys_list(rtx, sys_list); | ||||||
|  | 			goto done; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		switch (optname) | ||||||
|  | 		{ | ||||||
|  | 		/* TODO: | ||||||
|  | 			case SO_BINDTODEVICE: | ||||||
|  | 		*/ | ||||||
|  | 			case SO_BROADCAST: | ||||||
|  | 			case SO_DONTROUTE: | ||||||
|  | 			case SO_KEEPALIVE: | ||||||
|  | 			case SO_RCVBUF: | ||||||
|  | 			case SO_REUSEADDR: | ||||||
|  | 			case SO_REUSEPORT: | ||||||
|  | 			case SO_SNDBUF: | ||||||
|  | 			{ | ||||||
|  | 				hawk_int_t tmp; | ||||||
|  | 				if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 3), &tmp) <= -1) goto fail; | ||||||
|  | 				iv = tmp; | ||||||
|  | 				vptr = &iv; | ||||||
|  | 				vlen = HAWK_SIZEOF(iv); | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			case SO_RCVTIMEO: | ||||||
|  | 			case SO_SNDTIMEO: | ||||||
|  | 			{ | ||||||
|  | 				hawk_ntime_t tmp; | ||||||
|  | 				if (val_to_ntime(rtx, hawk_rtx_getarg(rtx, 3), &tmp) <= -1) goto fail; | ||||||
|  | 				tv.tv_sec = tmp.sec; | ||||||
|  | 				tv.tv_usec = HAWK_NSEC_TO_MSEC(tmp.nsec); | ||||||
|  | 				vptr = &tv; | ||||||
|  | 				vlen = HAWK_SIZEOF(tv); | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			default: | ||||||
|  | 				rx = set_error_on_sys_list(rtx, sys_list, EINVAL, HAWK_NULL); | ||||||
|  | 				goto done; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		rx = setsockopt(sys_node->ctx.u.file.fd, level, optname, vptr, vlen); | ||||||
|  | 		if (rx <= -1) rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | done: | ||||||
|  | 	hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx)); | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
| /* ------------------------------------------------------------ */ | /* ------------------------------------------------------------ */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @ -3968,6 +4075,7 @@ static fnctab_t fnctab[] = | |||||||
| 	{ HAWK_T("rmdir"),       { { 1, 1, HAWK_NULL     }, fnc_rmdir,       0  } }, | 	{ HAWK_T("rmdir"),       { { 1, 1, HAWK_NULL     }, fnc_rmdir,       0  } }, | ||||||
| 	{ HAWK_T("sendto"),      { { 2, 3, HAWK_NULL     }, fnc_sendto,      0  } }, | 	{ HAWK_T("sendto"),      { { 2, 3, HAWK_NULL     }, fnc_sendto,      0  } }, | ||||||
| 	{ HAWK_T("setenv"),      { { 2, 3, HAWK_NULL     }, fnc_setenv,      0  } }, | 	{ HAWK_T("setenv"),      { { 2, 3, HAWK_NULL     }, fnc_setenv,      0  } }, | ||||||
|  | 	{ HAWK_T("setsockopt"),  { { 4, 4, HAWK_NULL     }, fnc_setsockopt,  0  } }, | ||||||
| 	{ HAWK_T("settime"),     { { 1, 1, HAWK_NULL     }, fnc_settime,     0  } }, | 	{ HAWK_T("settime"),     { { 1, 1, HAWK_NULL     }, fnc_settime,     0  } }, | ||||||
| 	{ HAWK_T("shutdown"),    { { 2, 2, HAWK_NULL     }, fnc_shutdown,    0  } }, | 	{ HAWK_T("shutdown"),    { { 2, 2, HAWK_NULL     }, fnc_shutdown,    0  } }, | ||||||
| 	{ HAWK_T("sleep"),       { { 1, 1, HAWK_NULL     }, fnc_sleep,       0  } }, | 	{ HAWK_T("sleep"),       { { 1, 1, HAWK_NULL     }, fnc_sleep,       0  } }, | ||||||
| @ -4161,6 +4269,18 @@ static inttab_t inttab[] = | |||||||
| 	{ HAWK_T("SOCK_NONBLOCK"), { SOCK_NONBLOCK } }, | 	{ HAWK_T("SOCK_NONBLOCK"), { SOCK_NONBLOCK } }, | ||||||
| 	{ HAWK_T("SOCK_STREAM"),   { SOCK_STREAM } }, | 	{ HAWK_T("SOCK_STREAM"),   { SOCK_STREAM } }, | ||||||
|  |  | ||||||
|  | 	{ HAWK_T("SOL_SOCKET"),    { SOL_SOCKET } }, | ||||||
|  |  | ||||||
|  | 	{ HAWK_T("SO_BROADCAST"),  { SO_BROADCAST } }, | ||||||
|  | 	{ HAWK_T("SO_DONTROUTE"),  { SO_DONTROUTE } }, | ||||||
|  | 	{ HAWK_T("SO_KEEPALIVE"),  { SO_KEEPALIVE } }, | ||||||
|  | 	{ HAWK_T("SO_RCVBUF"),     { SO_RCVBUF } }, | ||||||
|  | 	{ HAWK_T("SO_RCVTIMEO"),   { SO_RCVTIMEO } }, | ||||||
|  | 	{ HAWK_T("SO_REUSEADDR"),  { SO_REUSEADDR } }, | ||||||
|  | 	{ HAWK_T("SO_REUSEPORT"),  { SO_REUSEPORT } }, | ||||||
|  | 	{ HAWK_T("SO_SNDBUF"),     { SO_SNDBUF } }, | ||||||
|  | 	{ HAWK_T("SO_SNDTIMEO"),   { SO_SNDTIMEO } }, | ||||||
|  |  | ||||||
| 	{ HAWK_T("STRFTIME_UTC"),  { STRFTIME_UTC } }, | 	{ HAWK_T("STRFTIME_UTC"),  { STRFTIME_UTC } }, | ||||||
|  |  | ||||||
| 	{ HAWK_T("WNOHANG"),       { WNOHANG } } | 	{ HAWK_T("WNOHANG"),       { WNOHANG } } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user