From: Viktor Szakats Date: Sat, 8 Mar 2025 01:18:35 +0000 (+0100) Subject: core: stop redefining `E*` macros on Windows, map `EACCES`, related fixes X-Git-Tag: curl-8_13_0~155 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=51d8213579c6e92f16912742a25d9567d4a52903;p=thirdparty%2Fcurl.git core: stop redefining `E*` macros on Windows, map `EACCES`, related fixes Before this patch, standard `E*` errno codes were redefined on Windows, onto matching winsock2 `WSA*` error codes, which have different values. This broke uses where using the `E*` value in non-socket context, or other places expecting a POSIX `errno`, e.g. file I/O, threads, IDN or interfacing with dependencies. Fix it by introducing a curl-specific `SOCKE*` set of macros that map to `WSA*` on Windows and standard POSIX codes on other platforms. Then verify and update the code to use `SOCKE*` or `E*` macro depending on context. - Add `SOCKE*` macros that map to either winsock2 or POSIX error codes. And use them with `SOCKERRNO` or in contexts requiring platform-dependent socket error codes. This fixes `E*` uses which were supposed be POSIX values, not `WSA*` socket errors, on Windows: - lib/curl_multibyte.c - lib/curl_threads.c - lib/idn.c - lib/vtls/gtls.c - lib/vtls/rustls.c - src/tool_cb_wrt.c - src/tool_dirhie.c - Ban `E*` codes having a `SOCKE*` mapping, via checksrc. Authored-by: Daniel Stenberg - Add exceptions for `E*` codes used in file I/O, or other contexts requiring POSIX error codes. Also: - ftp: fix missing `SOCKEACCES` mapping for Windows. - add `SOCKENOMEM` for `Curl_getaddrinfo()` via `asyn-thread.c`. - tests/server/sockfilt: fix to set `SOCKERRNO` in local `select()` override on Windows. - lib/inet_ntop: fix to return `WSAEINVAL` on Windows, where `ENOSPC` is used on other platforms. To simulate Windows' built-in `inet_ntop()`, as tested on a Win10 machine. Note: - WINE returns `STATUS_INVALID_PARAMETER` = `0xC000000D`. - Microsoft documentation says it returns `WSA_INVALID_PARAMETER` (= `ERROR_INVALID_PARAMETER`) 87: https://learn.microsoft.com/windows/win32/api/ws2tcpip/nf-ws2tcpip-inet_ntop#return-value - lib/inet_ntop: drop redundant `CURL_SETERRNO(ENOSPC)`. `inet_ntop4()` already sets it before returning `NULL`. - replace stray `WSAEWOULDBLOCK` with `USE_WINSOCK` macro to detect winsock2. - move existing `SOCKE*` mappings from `tests/server` to `curl_setup_once.h`. - add missing `EINTR`, `EINVAL` constants for WinCE. Follow-up to abf80aae384319ef9b19ffbd0d69a1fbe7421f1f #16612 Follow-up to d69425ed7d0918aceddd96048b146a9df85638ec #16615 Bug: https://github.com/curl/curl/pull/16553#issuecomment-2704679377 Closes #16621 --- diff --git a/CMake/CurlTests.c b/CMake/CurlTests.c index 69a996a047..de2313080d 100644 --- a/CMake/CurlTests.c +++ b/CMake/CurlTests.c @@ -278,6 +278,7 @@ int main(void) { char buffer[1024]; /* This will not compile if strerror_r does not return a char* */ + /* !checksrc! disable ERRNOVAR 1 */ check(strerror_r(EACCES, buffer, sizeof(buffer))[0]); return 0; } @@ -294,6 +295,7 @@ int main(void) { char buffer[1024]; /* This will not compile if strerror_r does not return an int */ + /* !checksrc! disable ERRNOVAR 1 */ check(strerror_r(EACCES, buffer, sizeof(buffer))); return 0; } diff --git a/docs/examples/.checksrc b/docs/examples/.checksrc index 37f7909524..cfcd695bd0 100644 --- a/docs/examples/.checksrc +++ b/docs/examples/.checksrc @@ -1,2 +1,3 @@ -disable TYPEDEFSTRUCT disable BANNEDFUNC +disable ERRNOVAR +disable TYPEDEFSTRUCT diff --git a/lib/amigaos.c b/lib/amigaos.c index c4872f248d..ac6d6b4193 100644 --- a/lib/amigaos.c +++ b/lib/amigaos.c @@ -184,7 +184,7 @@ int Curl_amiga_select(int nfds, fd_set *readfds, fd_set *writefds, { int r = WaitSelect(nfds, readfds, writefds, errorfds, timeout, 0); /* Ensure Ctrl-C signal is actioned */ - if((r == -1) && (SOCKERRNO == EINTR)) + if((r == -1) && (SOCKERRNO == SOCKEINTR)) raise(SIGINT); return r; } diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c index bf7f144ad5..c057ee8eb8 100644 --- a/lib/asyn-thread.c +++ b/lib/asyn-thread.c @@ -49,9 +49,9 @@ #endif #ifdef HAVE_GETADDRINFO -# define RESOLVER_ENOMEM EAI_MEMORY +# define RESOLVER_ENOMEM EAI_MEMORY /* = WSA_NOT_ENOUGH_MEMORY on Windows */ #else -# define RESOLVER_ENOMEM ENOMEM +# define RESOLVER_ENOMEM SOCKENOMEM #endif #include "urldata.h" @@ -433,6 +433,7 @@ static bool init_resolve_thread(struct Curl_easy *data, const struct addrinfo *hints) { struct thread_data *td = &data->state.async.thdata; + /* !checksrc! disable ERRNOVAR 1 */ int err = ENOMEM; struct Curl_async *async = &data->state.async; diff --git a/lib/cf-socket.c b/lib/cf-socket.c index 260b52333d..e02b035127 100644 --- a/lib/cf-socket.c +++ b/lib/cf-socket.c @@ -868,7 +868,7 @@ static bool verifyconnect(curl_socket_t sockfd, int *error) err = 0; } #endif - if((0 == err) || (EISCONN == err)) + if((0 == err) || (SOCKEISCONN == err)) /* we are connected, awesome! */ rc = TRUE; else @@ -891,10 +891,10 @@ static CURLcode socket_connect_result(struct Curl_easy *data, const char *ipaddress, int error) { switch(error) { - case EINPROGRESS: - case EWOULDBLOCK: + case SOCKEINPROGRESS: + case SOCKEWOULDBLOCK: #if defined(EAGAIN) -#if (EAGAIN) != (EWOULDBLOCK) +#if (EAGAIN) != (SOCKEWOULDBLOCK) /* On some platforms EAGAIN and EWOULDBLOCK are the * same value, and on others they are different, hence * the odd #if @@ -1515,15 +1515,16 @@ static ssize_t cf_socket_send(struct Curl_cfilter *cf, struct Curl_easy *data, int sockerr = SOCKERRNO; if( -#ifdef WSAEWOULDBLOCK +#ifdef USE_WINSOCK /* This is how Windows does it */ - (WSAEWOULDBLOCK == sockerr) + (SOCKEWOULDBLOCK == sockerr) #else /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned due to its inability to send off data without blocking. We therefore treat both error codes the same here */ - (EWOULDBLOCK == sockerr) || (EAGAIN == sockerr) || (EINTR == sockerr) || - (EINPROGRESS == sockerr) + (SOCKEWOULDBLOCK == sockerr) || + (EAGAIN == sockerr) || (SOCKEINTR == sockerr) || + (SOCKEINPROGRESS == sockerr) #endif ) { /* this is just a case of EWOULDBLOCK */ @@ -1583,14 +1584,15 @@ static ssize_t cf_socket_recv(struct Curl_cfilter *cf, struct Curl_easy *data, int sockerr = SOCKERRNO; if( -#ifdef WSAEWOULDBLOCK +#ifdef USE_WINSOCK /* This is how Windows does it */ - (WSAEWOULDBLOCK == sockerr) + (SOCKEWOULDBLOCK == sockerr) #else /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned due to its inability to send off data without blocking. We therefore treat both error codes the same here */ - (EWOULDBLOCK == sockerr) || (EAGAIN == sockerr) || (EINTR == sockerr) + (SOCKEWOULDBLOCK == sockerr) || + (EAGAIN == sockerr) || (SOCKEINTR == sockerr) #endif ) { /* this is just a case of EWOULDBLOCK */ diff --git a/lib/connect.c b/lib/connect.c index 327a6c36d8..18a592a7a7 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -306,7 +306,7 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, addr[0] = '\0'; *port = 0; - CURL_SETERRNO(EAFNOSUPPORT); + CURL_SETERRNO(SOCKEAFNOSUPPORT); return FALSE; } @@ -608,8 +608,8 @@ static CURLcode baller_connect(struct Curl_cfilter *cf, else if(Curl_timediff(*now, baller->started) >= baller->timeoutms) { infof(data, "%s connect timeout after %" FMT_TIMEDIFF_T "ms, move on!", baller->name, baller->timeoutms); -#if defined(ETIMEDOUT) - baller->error = ETIMEDOUT; +#ifdef SOCKETIMEDOUT + baller->error = SOCKETIMEDOUT; #endif baller->result = CURLE_OPERATION_TIMEDOUT; } @@ -770,11 +770,8 @@ evaluate: Curl_timediff(now, data->progress.t_startsingle), curl_easy_strerror(result)); -#ifdef WSAETIMEDOUT - if(WSAETIMEDOUT == data->state.os_errno) - result = CURLE_OPERATION_TIMEDOUT; -#elif defined(ETIMEDOUT) - if(ETIMEDOUT == data->state.os_errno) +#ifdef SOCKETIMEDOUT + if(SOCKETIMEDOUT == data->state.os_errno) result = CURLE_OPERATION_TIMEDOUT; #endif diff --git a/lib/curl_multibyte.c b/lib/curl_multibyte.c index 9c9fae6653..3c8077d9de 100644 --- a/lib/curl_multibyte.c +++ b/lib/curl_multibyte.c @@ -269,6 +269,7 @@ int curlx_win32_open(const char *filename, int oflag, ...) curlx_unicodefree(filename_w); } else + /* !checksrc! disable ERRNOVAR 1 */ CURL_SETERRNO(EINVAL); #else if(fix_excessive_path(filename, &fixed)) @@ -299,6 +300,7 @@ FILE *curlx_win32_fopen(const char *filename, const char *mode) result = _wfopen(target, mode_w); } else + /* !checksrc! disable ERRNOVAR 1 */ CURL_SETERRNO(EINVAL); curlx_unicodefree(filename_w); curlx_unicodefree(mode_w); @@ -335,6 +337,7 @@ int curlx_win32_stat(const char *path, struct_stat *buffer) curlx_unicodefree(path_w); } else + /* !checksrc! disable ERRNOVAR 1 */ CURL_SETERRNO(EINVAL); #else if(fix_excessive_path(path, &fixed)) diff --git a/lib/curl_setup.h b/lib/curl_setup.h index 86c8cb07b6..c8605fd200 100644 --- a/lib/curl_setup.h +++ b/lib/curl_setup.h @@ -853,11 +853,13 @@ /* Terrible workarounds to make Windows CE compile */ #define errno 0 #define CURL_SETERRNO(x) ((void)(x)) +#define EINTR 4 #define EAGAIN 11 #define ENOMEM 12 #define EACCES 13 #define EEXIST 17 #define EISDIR 21 +#define EINVAL 22 #define ENOSPC 28 #define strerror(x) "?" #else diff --git a/lib/curl_setup_once.h b/lib/curl_setup_once.h index 9f13dc4189..c1051e0fae 100644 --- a/lib/curl_setup_once.h +++ b/lib/curl_setup_once.h @@ -321,32 +321,39 @@ typedef unsigned int bit; */ #ifdef USE_WINSOCK -#undef EBADF /* override definition in errno.h */ -#define EBADF WSAEBADF -#undef EINTR /* override definition in errno.h */ -#define EINTR WSAEINTR -#undef EINVAL /* override definition in errno.h */ -#define EINVAL WSAEINVAL -#undef EWOULDBLOCK /* override definition in errno.h */ -#define EWOULDBLOCK WSAEWOULDBLOCK -#undef EINPROGRESS /* override definition in errno.h */ -#define EINPROGRESS WSAEINPROGRESS -#undef EMSGSIZE /* override definition in errno.h */ -#define EMSGSIZE WSAEMSGSIZE -#undef EAFNOSUPPORT /* override definition in errno.h */ -#define EAFNOSUPPORT WSAEAFNOSUPPORT -#undef EADDRINUSE /* override definition in errno.h */ -#define EADDRINUSE WSAEADDRINUSE -#undef EADDRNOTAVAIL /* override definition in errno.h */ -#define EADDRNOTAVAIL WSAEADDRNOTAVAIL -#undef ECONNRESET /* override definition in errno.h */ -#define ECONNRESET WSAECONNRESET -#undef EISCONN /* override definition in errno.h */ -#define EISCONN WSAEISCONN -#undef ETIMEDOUT /* override definition in errno.h */ -#define ETIMEDOUT WSAETIMEDOUT -#undef ECONNREFUSED /* override definition in errno.h */ -#define ECONNREFUSED WSAECONNREFUSED +#define SOCKEACCES WSAEACCES +#define SOCKEADDRINUSE WSAEADDRINUSE +#define SOCKEADDRNOTAVAIL WSAEADDRNOTAVAIL +#define SOCKEAFNOSUPPORT WSAEAFNOSUPPORT +#define SOCKEBADF WSAEBADF +#define SOCKECONNREFUSED WSAECONNREFUSED +#define SOCKECONNRESET WSAECONNRESET +#define SOCKEINPROGRESS WSAEINPROGRESS +#define SOCKEINTR WSAEINTR +#define SOCKEINVAL WSAEINVAL +#define SOCKEISCONN WSAEISCONN +#define SOCKEMSGSIZE WSAEMSGSIZE +#define SOCKENOMEM WSA_NOT_ENOUGH_MEMORY +#define SOCKETIMEDOUT WSAETIMEDOUT +#define SOCKEWOULDBLOCK WSAEWOULDBLOCK +#else +#define SOCKEACCES EACCES +#define SOCKEADDRINUSE EADDRINUSE +#define SOCKEADDRNOTAVAIL EADDRNOTAVAIL +#define SOCKEAFNOSUPPORT EAFNOSUPPORT +#define SOCKEBADF EBADF +#define SOCKECONNREFUSED ECONNREFUSED +#define SOCKECONNRESET ECONNRESET +#define SOCKEINPROGRESS EINPROGRESS +#define SOCKEINTR EINTR +#define SOCKEINVAL EINVAL +#define SOCKEISCONN EISCONN +#define SOCKEMSGSIZE EMSGSIZE +#define SOCKENOMEM ENOMEM +#ifdef ETIMEDOUT +#define SOCKETIMEDOUT ETIMEDOUT +#endif +#define SOCKEWOULDBLOCK EWOULDBLOCK #endif /* diff --git a/lib/curl_threads.c b/lib/curl_threads.c index 6f90bfed15..54f0dcee49 100644 --- a/lib/curl_threads.c +++ b/lib/curl_threads.c @@ -127,6 +127,7 @@ curl_thread_t Curl_thread_create( if((t == 0) || (t == LongToHandle(-1L))) { #ifdef UNDER_CE DWORD gle = GetLastError(); + /* !checksrc! disable ERRNOVAR 1 */ int err = (gle == ERROR_ACCESS_DENIED || gle == ERROR_NOT_ENOUGH_MEMORY) ? EACCES : EINVAL; diff --git a/lib/ftp.c b/lib/ftp.c index 849254f451..50e3e52738 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -1063,7 +1063,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data, if(bind(portsock, sa, sslen) ) { /* It failed. */ error = SOCKERRNO; - if(possibly_non_local && (error == EADDRNOTAVAIL)) { + if(possibly_non_local && (error == SOCKEADDRNOTAVAIL)) { /* The requested bind address is not local. Use the address used for * the control connection instead and restart the port loop */ @@ -1080,7 +1080,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data, possibly_non_local = FALSE; /* do not try this again */ continue; } - if(error != EADDRINUSE && error != EACCES) { + if(error != SOCKEADDRINUSE && error != SOCKEACCES) { failf(data, "bind(port=%hu) failed: %s", port, Curl_strerror(error, buffer, sizeof(buffer))); goto out; diff --git a/lib/idn.c b/lib/idn.c index 401aa9aa48..6a96527aee 100644 --- a/lib/idn.c +++ b/lib/idn.c @@ -71,6 +71,7 @@ static CURLcode iconv_to_utf8(const char *in, size_t inlen, *outlen -= iconv_outlen; iconv_close(cd); if(iconv_result == (size_t)-1) { + /* !checksrc! disable ERRNOVAR 1 */ if(errno == ENOMEM) return CURLE_OUT_OF_MEMORY; else @@ -80,6 +81,7 @@ static CURLcode iconv_to_utf8(const char *in, size_t inlen, return CURLE_OK; } else { + /* !checksrc! disable ERRNOVAR 1 */ if(errno == ENOMEM) return CURLE_OUT_OF_MEMORY; else diff --git a/lib/inet_ntop.c b/lib/inet_ntop.c index 51126ce9c4..26d84a907b 100644 --- a/lib/inet_ntop.c +++ b/lib/inet_ntop.c @@ -74,7 +74,11 @@ static char *inet_ntop4(const unsigned char *src, char *dst, size_t size) len = strlen(tmp); if(len == 0 || len >= size) { +#ifdef USE_WINSOCK + CURL_SETERRNO(WSAEINVAL); +#else CURL_SETERRNO(ENOSPC); +#endif return NULL; } strcpy(dst, tmp); @@ -153,7 +157,6 @@ static char *inet_ntop6(const unsigned char *src, char *dst, size_t size) if(i == 6 && best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { if(!inet_ntop4(src + 12, tp, sizeof(tmp) - (tp - tmp))) { - CURL_SETERRNO(ENOSPC); return NULL; } tp += strlen(tp); @@ -171,7 +174,11 @@ static char *inet_ntop6(const unsigned char *src, char *dst, size_t size) /* Check for overflow, copy, and we are done. */ if((size_t)(tp - tmp) > size) { +#ifdef USE_WINSOCK + CURL_SETERRNO(WSAEINVAL); +#else CURL_SETERRNO(ENOSPC); +#endif return NULL; } strcpy(dst, tmp); @@ -197,7 +204,7 @@ char *curlx_inet_ntop(int af, const void *src, char *buf, size_t size) case AF_INET6: return inet_ntop6((const unsigned char *)src, buf, size); default: - CURL_SETERRNO(EAFNOSUPPORT); + CURL_SETERRNO(SOCKEAFNOSUPPORT); return NULL; } } diff --git a/lib/inet_pton.c b/lib/inet_pton.c index 7531f719c7..5a871a3099 100644 --- a/lib/inet_pton.c +++ b/lib/inet_pton.c @@ -80,7 +80,7 @@ curlx_inet_pton(int af, const char *src, void *dst) case AF_INET6: return inet_pton6(src, (unsigned char *)dst); default: - CURL_SETERRNO(EAFNOSUPPORT); + CURL_SETERRNO(SOCKEAFNOSUPPORT); return -1; } /* NOTREACHED */ diff --git a/lib/memdebug.c b/lib/memdebug.c index d72d557013..05b625cfce 100644 --- a/lib/memdebug.c +++ b/lib/memdebug.c @@ -117,13 +117,12 @@ static bool countcheck(const char *func, int line, const char *source) fprintf(stderr, "LIMIT %s:%d %s reached memlimit\n", source, line, func); fflush(curl_dbg_logfile); /* because it might crash now */ + /* !checksrc! disable ERRNOVAR 1 */ CURL_SETERRNO(ENOMEM); return TRUE; /* RETURN ERROR! */ } else memsize--; /* countdown */ - - } return FALSE; /* allow this */ diff --git a/lib/multi.c b/lib/multi.c index ee3cad724a..7b54850a63 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -1328,7 +1328,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi, when there is no more data, breaking the loop. */ nread = wakeup_read(multi->wakeup_pair[0], buf, sizeof(buf)); if(nread <= 0) { - if(nread < 0 && EINTR == SOCKERRNO) + if(nread < 0 && SOCKEINTR == SOCKERRNO) continue; break; } @@ -1429,11 +1429,11 @@ CURLMcode curl_multi_wakeup(CURLM *m) int err = SOCKERRNO; int return_success; #ifdef USE_WINSOCK - return_success = WSAEWOULDBLOCK == err; + return_success = SOCKEWOULDBLOCK == err; #else - if(EINTR == err) + if(SOCKEINTR == err) continue; - return_success = EWOULDBLOCK == err || EAGAIN == err; + return_success = SOCKEWOULDBLOCK == err || EAGAIN == err; #endif if(!return_success) return CURLM_WAKEUP_FAILURE; diff --git a/lib/openldap.c b/lib/openldap.c index 8b5cebd601..dd07499e11 100644 --- a/lib/openldap.c +++ b/lib/openldap.c @@ -1170,7 +1170,7 @@ ldapsb_tls_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) ret = (li->recv)(data, FIRSTSOCKET, buf, len, &err); if(ret < 0 && err == CURLE_AGAIN) { - SET_SOCKERRNO(EWOULDBLOCK); + SET_SOCKERRNO(SOCKEWOULDBLOCK); } } } @@ -1189,7 +1189,7 @@ ldapsb_tls_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) CURLcode err = CURLE_SEND_ERROR; ret = (li->send)(data, FIRSTSOCKET, buf, len, FALSE, &err); if(ret < 0 && err == CURLE_AGAIN) { - SET_SOCKERRNO(EWOULDBLOCK); + SET_SOCKERRNO(SOCKEWOULDBLOCK); } } } diff --git a/lib/select.c b/lib/select.c index a7e9ce53ac..23280c6d98 100644 --- a/lib/select.c +++ b/lib/select.c @@ -74,7 +74,7 @@ int Curl_wait_ms(timediff_t timeout_ms) if(!timeout_ms) return 0; if(timeout_ms < 0) { - SET_SOCKERRNO(EINVAL); + SET_SOCKERRNO(SOCKEINVAL); return -1; } #if defined(MSDOS) @@ -96,7 +96,7 @@ int Curl_wait_ms(timediff_t timeout_ms) } #endif /* _WIN32 */ if(r) { - if((r == -1) && (SOCKERRNO == EINTR)) + if((r == -1) && (SOCKERRNO == SOCKEINTR)) /* make EINTR from select or poll not a "lethal" error */ r = 0; else @@ -312,7 +312,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms) pending_ms = 0; r = poll(ufds, nfds, pending_ms); if(r <= 0) { - if((r == -1) && (SOCKERRNO == EINTR)) + if((r == -1) && (SOCKERRNO == SOCKEINTR)) /* make EINTR from select or poll not a "lethal" error */ r = 0; return r; @@ -360,7 +360,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms) */ r = our_select(maxfd, &fds_read, &fds_write, &fds_err, timeout_ms); if(r <= 0) { - if((r == -1) && (SOCKERRNO == EINTR)) + if((r == -1) && (SOCKERRNO == SOCKEINTR)) /* make EINTR from select or poll not a "lethal" error */ r = 0; return r; diff --git a/lib/select.h b/lib/select.h index 60e166b001..10968fab7f 100644 --- a/lib/select.h +++ b/lib/select.h @@ -93,7 +93,7 @@ int Curl_wait_ms(timediff_t timeout_ms); #define FDSET_SOCK(x) 1 #define VERIFY_SOCK(x) do { \ if(!VALID_SOCK(x)) { \ - SET_SOCKERRNO(WSAEINVAL); \ + SET_SOCKERRNO(SOCKEINVAL); \ return -1; \ } \ } while(0) @@ -105,7 +105,7 @@ int Curl_wait_ms(timediff_t timeout_ms); #define VERIFY_SOCK(x) do { \ if(!VALID_SOCK(x) || !FDSET_SOCK(x)) { \ - SET_SOCKERRNO(EINVAL); \ + SET_SOCKERRNO(SOCKEINVAL); \ return -1; \ } \ } while(0) diff --git a/lib/socketpair.c b/lib/socketpair.c index 0bb70419db..85fb7a826c 100644 --- a/lib/socketpair.c +++ b/lib/socketpair.c @@ -223,15 +223,15 @@ int Curl_socketpair(int domain, int type, int protocol, if(Curl_timediff(Curl_now(), start) > (60 * 1000)) goto error; if( -#ifdef WSAEWOULDBLOCK +#ifdef USE_WINSOCK /* This is how Windows does it */ - (WSAEWOULDBLOCK == sockerr) + (SOCKEWOULDBLOCK == sockerr) #else /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned due to its inability to send off data without blocking. We therefore treat both error codes the same here */ - (EWOULDBLOCK == sockerr) || (EAGAIN == sockerr) || - (EINTR == sockerr) || (EINPROGRESS == sockerr) + (SOCKEWOULDBLOCK == sockerr) || (EAGAIN == sockerr) || + (SOCKEINTR == sockerr) || (SOCKEINPROGRESS == sockerr) #endif ) { continue; diff --git a/lib/telnet.c b/lib/telnet.c index ee4d73b243..f35298ab7c 100644 --- a/lib/telnet.c +++ b/lib/telnet.c @@ -1449,7 +1449,7 @@ static CURLcode telnet_do(struct Curl_easy *data, bool *done) events.lNetworkEvents = 0; if(WSAEnumNetworkEvents(sockfd, event_handle, &events) == SOCKET_ERROR) { err = SOCKERRNO; - if(err != EINPROGRESS) { + if(err != SOCKEINPROGRESS) { infof(data, "WSAEnumNetworkEvents failed (%d)", err); keepon = FALSE; result = CURLE_READ_ERROR; @@ -1554,7 +1554,7 @@ static CURLcode telnet_do(struct Curl_easy *data, bool *done) /* In test 1452, macOS sees a ECONNRESET sometimes? Is this the * telnet test server not shutting down the socket in a clean way? * Seems to be timing related, happens more on slow debug build */ - if(data->state.os_errno == ECONNRESET) { + if(data->state.os_errno == SOCKECONNRESET) { DEBUGF(infof(data, "telnet_do, unexpected ECONNRESET on recv")); } break; diff --git a/lib/vquic/vquic.c b/lib/vquic/vquic.c index a36d424702..1e7a258b61 100644 --- a/lib/vquic/vquic.c +++ b/lib/vquic/vquic.c @@ -148,17 +148,18 @@ static CURLcode do_sendmsg(struct Curl_cfilter *cf, #endif - while((sent = sendmsg(qctx->sockfd, &msg, 0)) == -1 && SOCKERRNO == EINTR) + while((sent = sendmsg(qctx->sockfd, &msg, 0)) == -1 && + SOCKERRNO == SOCKEINTR) ; if(sent == -1) { switch(SOCKERRNO) { case EAGAIN: -#if EAGAIN != EWOULDBLOCK - case EWOULDBLOCK: +#if EAGAIN != SOCKEWOULDBLOCK + case SOCKEWOULDBLOCK: #endif return CURLE_AGAIN; - case EMSGSIZE: + case SOCKEMSGSIZE: /* UDP datagram is too large; caused by PMTUD. Just let it be lost. */ break; case EIO: @@ -186,16 +187,16 @@ static CURLcode do_sendmsg(struct Curl_cfilter *cf, while((sent = send(qctx->sockfd, (const char *)pkt, (SEND_TYPE_ARG3)pktlen, 0)) == -1 && - SOCKERRNO == EINTR) + SOCKERRNO == SOCKEINTR) ; if(sent == -1) { - if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) { + if(SOCKERRNO == EAGAIN || SOCKERRNO == SOCKEWOULDBLOCK) { return CURLE_AGAIN; } else { failf(data, "send() returned %zd (errno %d)", sent, SOCKERRNO); - if(SOCKERRNO != EMSGSIZE) { + if(SOCKERRNO != SOCKEMSGSIZE) { return CURLE_SEND_ERROR; } /* UDP datagram is too large; caused by PMTUD. Just let it be @@ -392,14 +393,14 @@ static CURLcode recvmmsg_packets(struct Curl_cfilter *cf, } while((mcount = recvmmsg(qctx->sockfd, mmsg, n, 0, NULL)) == -1 && - SOCKERRNO == EINTR) + SOCKERRNO == SOCKEINTR) ; if(mcount == -1) { - if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) { + if(SOCKERRNO == EAGAIN || SOCKERRNO == SOCKEWOULDBLOCK) { CURL_TRC_CF(data, cf, "ingress, recvmmsg -> EAGAIN"); goto out; } - if(!cf->connected && SOCKERRNO == ECONNREFUSED) { + if(!cf->connected && SOCKERRNO == SOCKECONNREFUSED) { struct ip_quadruple ip; Curl_cf_socket_peek(cf->next, data, NULL, NULL, &ip); failf(data, "QUIC: connection to %s port %u refused", @@ -484,13 +485,13 @@ static CURLcode recvmsg_packets(struct Curl_cfilter *cf, msg.msg_namelen = sizeof(remote_addr); msg.msg_controllen = sizeof(msg_ctrl); while((nread = recvmsg(qctx->sockfd, &msg, 0)) == -1 && - SOCKERRNO == EINTR) + SOCKERRNO == SOCKEINTR) ; if(nread == -1) { - if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) { + if(SOCKERRNO == EAGAIN || SOCKERRNO == SOCKEWOULDBLOCK) { goto out; } - if(!cf->connected && SOCKERRNO == ECONNREFUSED) { + if(!cf->connected && SOCKERRNO == SOCKECONNREFUSED) { struct ip_quadruple ip; Curl_cf_socket_peek(cf->next, data, NULL, NULL, &ip); failf(data, "QUIC: connection to %s port %u refused", @@ -558,14 +559,14 @@ static CURLcode recvfrom_packets(struct Curl_cfilter *cf, while((nread = recvfrom(qctx->sockfd, (char *)buf, bufsize, 0, (struct sockaddr *)&remote_addr, &remote_addrlen)) == -1 && - SOCKERRNO == EINTR) + SOCKERRNO == SOCKEINTR) ; if(nread == -1) { - if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) { + if(SOCKERRNO == EAGAIN || SOCKERRNO == SOCKEWOULDBLOCK) { CURL_TRC_CF(data, cf, "ingress, recvfrom -> EAGAIN"); goto out; } - if(!cf->connected && SOCKERRNO == ECONNREFUSED) { + if(!cf->connected && SOCKERRNO == SOCKECONNREFUSED) { struct ip_quadruple ip; Curl_cf_socket_peek(cf->next, data, NULL, NULL, &ip); failf(data, "QUIC: connection to %s port %u refused", diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c index 6924140299..7db06e759a 100644 --- a/lib/vtls/gtls.c +++ b/lib/vtls/gtls.c @@ -100,6 +100,7 @@ static ssize_t gtls_push(void *s, const void *buf, size_t blen) blen, nwritten, result); backend->gtls.io_result = result; if(nwritten < 0) { + /* !checksrc! disable ERRNOVAR 1 */ gnutls_transport_set_errno(backend->gtls.session, (CURLE_AGAIN == result) ? EAGAIN : EINVAL); nwritten = -1; @@ -121,6 +122,7 @@ static ssize_t gtls_pull(void *s, void *buf, size_t blen) if(!backend->gtls.shared_creds->trust_setup) { result = Curl_gtls_client_trust_setup(cf, data, &backend->gtls); if(result) { + /* !checksrc! disable ERRNOVAR 1 */ gnutls_transport_set_errno(backend->gtls.session, EINVAL); backend->gtls.io_result = result; return -1; @@ -132,6 +134,7 @@ static ssize_t gtls_pull(void *s, void *buf, size_t blen) blen, nread, result); backend->gtls.io_result = result; if(nread < 0) { + /* !checksrc! disable ERRNOVAR 1 */ gnutls_transport_set_errno(backend->gtls.session, (CURLE_AGAIN == result) ? EAGAIN : EINVAL); nread = -1; diff --git a/lib/vtls/rustls.c b/lib/vtls/rustls.c index 529d6b9c1c..61c7bdf87e 100644 --- a/lib/vtls/rustls.c +++ b/lib/vtls/rustls.c @@ -98,6 +98,7 @@ read_cb(void *userdata, uint8_t *buf, uintptr_t len, uintptr_t *out_n) (char *)buf, len, &result); if(nread < 0) { nread = 0; + /* !checksrc! disable ERRNOVAR 4 */ if(CURLE_AGAIN == result) ret = EAGAIN; else diff --git a/packages/OS400/ccsidcurl.c b/packages/OS400/ccsidcurl.c index 48f7f6d4ae..ccd397f0e6 100644 --- a/packages/OS400/ccsidcurl.c +++ b/packages/OS400/ccsidcurl.c @@ -290,6 +290,7 @@ curl_easy_escape_ccsid(CURL *handle, const char *string, int length, char *d; if(!string) { + /* !checksrc! disable ERRNOVAR 1 */ errno = EINVAL; return (char *) NULL; } @@ -320,6 +321,7 @@ curl_easy_unescape_ccsid(CURL *handle, const char *string, int length, char *d; if(!string) { + /* !checksrc! disable ERRNOVAR 1 */ errno = EINVAL; return (char *) NULL; } diff --git a/packages/OS400/os400sys.c b/packages/OS400/os400sys.c index 07be5dcc51..7be7208549 100644 --- a/packages/OS400/os400sys.c +++ b/packages/OS400/os400sys.c @@ -357,6 +357,7 @@ Curl_gss_convert_in_place(OM_uint32 *minor_status, gss_buffer_t buf) gss_release_buffer(minor_status, buf); if(minor_status) + /* !checksrc! disable ERRNOVAR 1 */ *minor_status = ENOMEM; return -1; @@ -388,6 +389,7 @@ Curl_gss_import_name_a(OM_uint32 *minor_status, gss_buffer_t in_name, in.value = malloc(i + 1); if(!in.value) { if(minor_status) + /* !checksrc! disable ERRNOVAR 1 */ *minor_status = ENOMEM; return GSS_S_FAILURE; @@ -451,6 +453,7 @@ Curl_gss_init_sec_context_a(OM_uint32 *minor_status, in.value = malloc(i + 1); if(!in.value) { if(minor_status) + /* !checksrc! disable ERRNOVAR 1 */ *minor_status = ENOMEM; return GSS_S_FAILURE; @@ -801,6 +804,7 @@ sockaddr2ebcdic(struct sockaddr_storage *dstaddr, if(!srcaddr || srclen < offsetof(struct sockaddr, sa_family) + sizeof(srcaddr->sa_family) || srclen > sizeof(*dstaddr)) { + /* !checksrc! disable ERRNOVAR 1 */ errno = EINVAL; return -1; } @@ -838,6 +842,7 @@ sockaddr2ascii(struct sockaddr *dstaddr, int dstlen, if(srclen > dstlen) srclen = dstlen; if(!srcaddr || srclen < 0) { + /* !checksrc! disable ERRNOVAR 1 */ errno = EINVAL; return -1; } diff --git a/scripts/checksrc.pl b/scripts/checksrc.pl index 8289c14c5c..2ebb8650f6 100755 --- a/scripts/checksrc.pl +++ b/scripts/checksrc.pl @@ -97,6 +97,7 @@ my %warnings = ( 'EMPTYLINEBRACE' => 'Empty line before the open brace', 'EQUALSNOSPACE' => 'equals sign without following space', 'EQUALSNULL' => 'if/while comparison with == NULL', + 'ERRNOVAR' => 'use of bare errno define', 'EXCLAMATIONSPACE' => 'Whitespace after exclamation mark in expression', 'FOPENMODE' => 'fopen needs a macro for the mode string', 'INCLUDEDUP', => 'same file is included again', @@ -1022,6 +1023,12 @@ sub scanfile { "space after exclamation mark"); } + if($nostr =~ /(.*)\b(EACCES|EADDRINUSE|EADDRNOTAVAIL|EAFNOSUPPORT|EBADF|ECONNREFUSED|ECONNRESET|EINPROGRESS|EINTR|EINVAL|EISCONN|EMSGSIZE|ENOMEM|ETIMEDOUT|EWOULDBLOCK)\b/) { + checkwarn("ERRNOVAR", + $line, length($1), $file, $ol, + "use of bare errno define $2, use SOCK$2"); + } + # check for more than one consecutive space before open brace or # question mark. Skip lines containing strings since they make it hard # due to artificially getting multiple spaces diff --git a/src/tool_cb_wrt.c b/src/tool_cb_wrt.c index f33f338d65..7a575c98f6 100644 --- a/src/tool_cb_wrt.c +++ b/src/tool_cb_wrt.c @@ -68,6 +68,7 @@ bool tool_create_output_file(struct OutStruct *outs, do { fd = open(fname, O_CREAT | O_WRONLY | O_EXCL | CURL_O_BINARY, OPENMODE); /* Keep retrying in the hope that it is not interrupted sometime */ + /* !checksrc! disable ERRNOVAR 1 */ } while(fd == -1 && errno == EINTR); if(config->file_clobber_mode == CLOBBER_NEVER && fd == -1) { int next_num = 1; @@ -86,6 +87,7 @@ bool tool_create_output_file(struct OutStruct *outs, } memcpy(newname, fname, len); newname[len] = '.'; + /* !checksrc! disable ERRNOVAR 1 */ while(fd == -1 && /* have not successfully opened a file */ (errno == EEXIST || errno == EISDIR) && /* because we keep having files that already exist */ diff --git a/src/tool_dirhie.c b/src/tool_dirhie.c index 1360ddd6bb..ac9b969a8d 100644 --- a/src/tool_dirhie.c +++ b/src/tool_dirhie.c @@ -48,6 +48,7 @@ static void show_dir_errno(struct GlobalConfig *global, const char *name) { switch(errno) { #ifdef EACCES + /* !checksrc! disable ERRNOVAR 1 */ case EACCES: errorf(global, "You do not have permission to create %s", name); break; @@ -129,6 +130,7 @@ CURLcode create_dir_hierarchy(const char *outfile, struct GlobalConfig *global) return result; /* Create directory. Ignore access denied error to allow traversal. */ + /* !checksrc! disable ERRNOVAR 1 */ if(!skip && (-1 == mkdir(curlx_dyn_ptr(&dirbuf), (mode_t)0000750)) && (errno != EACCES) && (errno != EEXIST)) { show_dir_errno(global, curlx_dyn_ptr(&dirbuf)); diff --git a/src/tool_operate.c b/src/tool_operate.c index 3a8d932973..24e62d3fbb 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -547,7 +547,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, (CURLE_COULDNT_CONNECT == result)) { long oserrno = 0; curl_easy_getinfo(curl, CURLINFO_OS_ERRNO, &oserrno); - if(ECONNREFUSED == oserrno) + if(SOCKECONNREFUSED == oserrno) retry = RETRY_CONNREFUSED; } else if((CURLE_OK == result) || diff --git a/tests/libtest/first.c b/tests/libtest/first.c index a70fd54e5f..3192b8a942 100644 --- a/tests/libtest/first.c +++ b/tests/libtest/first.c @@ -41,7 +41,7 @@ int select_wrapper(int nfds, fd_set *rd, fd_set *wr, fd_set *exc, struct timeval *tv) { if(nfds < 0) { - SET_SOCKERRNO(EINVAL); + SET_SOCKERRNO(SOCKEINVAL); return -1; } #ifdef USE_WINSOCK diff --git a/tests/server/rtspd.c b/tests/server/rtspd.c index 81ecf04119..9d6a58b9a3 100644 --- a/tests/server/rtspd.c +++ b/tests/server/rtspd.c @@ -573,6 +573,7 @@ static void rtspd_storerequest(char *reqbuf, size_t totalsize) do { dump = fopen(dumpfile, "ab"); + /* !checksrc! disable ERRNOVAR 1 */ } while(!dump && ((error = errno) == EINTR)); if(!dump) { logmsg("Error opening file %s error (%d) %s", @@ -589,6 +590,7 @@ static void rtspd_storerequest(char *reqbuf, size_t totalsize) goto storerequest_cleanup; if(written > 0) writeleft -= written; + /* !checksrc! disable ERRNOVAR 1 */ } while((writeleft > 0) && ((error = errno) == EINTR)); if(writeleft == 0) diff --git a/tests/server/sockfilt.c b/tests/server/sockfilt.c index 6dfd52b82b..3fad138ab0 100644 --- a/tests/server/sockfilt.c +++ b/tests/server/sockfilt.c @@ -228,6 +228,7 @@ static ssize_t fullread(int filedes, void *buffer, size_t nbytes) if(rc < 0) { error = errno; + /* !checksrc! disable ERRNOVAR 1 */ if((error == EINTR) || (error == EAGAIN)) continue; if(error == CURL_WIN32_EPIPE) { @@ -279,6 +280,7 @@ static ssize_t fullwrite(int filedes, const void *buffer, size_t nbytes) if(wc < 0) { error = errno; + /* !checksrc! disable ERRNOVAR 1 */ if((error == EINTR) || (error == EAGAIN)) continue; logmsg("writing to file descriptor: %d,", filedes); @@ -624,7 +626,7 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds, /* check if the input value is valid */ if(nfds < 0) { - CURL_SETERRNO(EINVAL); + SET_SOCKERRNO(SOCKEINVAL); return -1; } @@ -645,7 +647,7 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds, /* create internal event to abort waiting threads */ abort = CreateEvent(NULL, TRUE, FALSE, NULL); if(!abort) { - CURL_SETERRNO(ENOMEM); + SET_SOCKERRNO(SOCKENOMEM); return -1; } @@ -653,7 +655,7 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds, data = calloc(nfds, sizeof(struct select_ws_data)); if(!data) { CloseHandle(abort); - CURL_SETERRNO(ENOMEM); + SET_SOCKERRNO(SOCKENOMEM); return -1; } @@ -662,7 +664,7 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds, if(!handles) { CloseHandle(abort); free(data); - CURL_SETERRNO(ENOMEM); + SET_SOCKERRNO(SOCKENOMEM); return -1; } diff --git a/tests/server/sws.c b/tests/server/sws.c index 19a287f0ae..ef3d126a64 100644 --- a/tests/server/sws.c +++ b/tests/server/sws.c @@ -761,6 +761,7 @@ static void sws_storerequest(const char *reqbuf, size_t totalsize) do { dump = fopen(dumpfile, "ab"); + /* !checksrc! disable ERRNOVAR 1 */ } while(!dump && ((error = errno) == EINTR)); if(!dump) { logmsg("[2] Error opening file %s error (%d) %s", @@ -777,6 +778,7 @@ static void sws_storerequest(const char *reqbuf, size_t totalsize) goto storerequest_cleanup; if(written > 0) writeleft -= written; + /* !checksrc! disable ERRNOVAR 1 */ } while((writeleft > 0) && ((error = errno) == EINTR)); if(writeleft == 0) diff --git a/tests/server/util.c b/tests/server/util.c index 79b64c39af..06395f096d 100644 --- a/tests/server/util.c +++ b/tests/server/util.c @@ -128,6 +128,7 @@ void logmsg(const char *msg, ...) do { logfp = fopen(serverlogfile, "ab"); + /* !checksrc! disable ERRNOVAR 1 */ } while(!logfp && (errno == EINTR)); if(logfp) { fprintf(logfp, "%s %s\n", timebuf, buffer); @@ -353,6 +354,7 @@ void set_advisor_read_lock(const char *filename) do { lockfile = fopen(filename, "wb"); + /* !checksrc! disable ERRNOVAR 1 */ } while(!lockfile && ((error = errno) == EINTR)); if(!lockfile) { logmsg("Error creating lock file %s error (%d) %s", @@ -379,6 +381,7 @@ void clear_advisor_read_lock(const char *filename) do { res = unlink(filename); + /* !checksrc! disable ERRNOVAR 1 */ } while(res && ((error = errno) == EINTR)); if(res) logmsg("Error removing lock file %s error (%d) %s", diff --git a/tests/server/util.h b/tests/server/util.h index dd9c13039f..09008f1042 100644 --- a/tests/server/util.h +++ b/tests/server/util.h @@ -25,24 +25,6 @@ ***************************************************************************/ #include "server_setup.h" -#ifdef USE_WINSOCK -#define SOCKEADDRINUSE WSAEADDRINUSE -#define SOCKECONNREFUSED WSAECONNREFUSED -#define SOCKEINPROGRESS WSAEINPROGRESS -#define SOCKEINTR WSAEINTR -#define SOCKEINVAL WSAEINVAL -#define SOCKEISCONN WSAEISCONN -#define SOCKEWOULDBLOCK WSAEWOULDBLOCK -#else -#define SOCKEADDRINUSE EADDRINUSE -#define SOCKECONNREFUSED ECONNREFUSED -#define SOCKEINPROGRESS EINPROGRESS -#define SOCKEINTR EINTR -#define SOCKEINVAL EINVAL -#define SOCKEISCONN EISCONN -#define SOCKEWOULDBLOCK EWOULDBLOCK -#endif - enum { DOCNUMBER_NOTHING = -7, DOCNUMBER_QUIT = -6,