diff --git a/src/error.c b/src/error.c index cd45cd5..d05db90 100644 --- a/src/error.c +++ b/src/error.c @@ -119,3 +119,23 @@ void err_set_win_error(DWORD error) { SetLastError(error); errno = err_map_win_error_to_errno(error); } + +int _check_handle(HANDLE handle) { + DWORD flags; + + /* GetHandleInformation() succeeds when passed INVALID_HANDLE_VALUE, so check + * for this condition explicitly. */ + if (handle == INVALID_HANDLE_VALUE) + return_error(-1, ERROR_INVALID_HANDLE); + + if (!GetHandleInformation(handle, &flags)) + return_error(-1); + + return 0; +} + +void err_validate_handle_and_set_win_error(HANDLE handle, DWORD error) { + if (_check_handle(handle) < 0) + return; + err_set_win_error(error); +} diff --git a/src/error.h b/src/error.h index 04ae9cb..9a4b3f0 100644 --- a/src/error.h +++ b/src/error.h @@ -11,10 +11,19 @@ err_set_win_error(error); \ return (value); \ } while (0) - #define return_error(value, ...) _return_error_helper(__VA_ARGS__ + 0, value) +#define _return_handle_error_helper(error, value, handle) \ + do { \ + err_validate_handle_and_set_win_error((HANDLE) handle, error); \ + return (value); \ + } while (0) +#define return_handle_error(value, handle, ...) \ + _return_handle_error_helper(__VA_ARGS__ + 0, value, handle) + WEPOLL_INTERNAL errno_t err_map_win_error_to_errno(DWORD error); WEPOLL_INTERNAL void err_set_win_error(DWORD error); +WEPOLL_INTERNAL void err_validate_handle_and_set_win_error(HANDLE handle, + DWORD error); #endif /* WEPOLL_ERROR_H_ */