From af0216251b94e751baa47146ac9609db70793b8e Mon Sep 17 00:00:00 2001 From: Jay Satiro Date: Mon, 19 Jun 2017 00:52:38 -0400 Subject: [PATCH] curl_setup_once: Remove ERRNO/SET_ERRNO macros Prior to this change (SET_)ERRNO mapped to GetLastError/SetLastError for Win32 and regular errno otherwise. I reviewed the code and found no justifiable reason for conflating errno on WIN32 with GetLastError/SetLastError. All Win32 CRTs support errno, and any Win32 multithreaded CRT supports thread-local errno. Fixes https://github.com/curl/curl/issues/895 Closes https://github.com/curl/curl/pull/1589 --- lib/asyn-thread.c | 7 ++----- lib/connect.c | 20 ++++++++------------ lib/curl_ntlm_wb.c | 19 ++++++------------- lib/curl_setup_once.h | 14 -------------- lib/curl_threads.c | 19 +++++++++++++------ lib/inet_ntop.c | 12 ++++++------ lib/inet_pton.c | 6 +++--- lib/non-ascii.c | 21 ++++++--------------- lib/parsedate.c | 10 +++++----- lib/strerror.c | 24 ++++++++++++++++++------ lib/strtoofft.c | 2 +- lib/telnet.c | 13 +++++++------ src/tool_dirhie.c | 2 +- src/tool_paramhlp.c | 4 ++-- 14 files changed, 78 insertions(+), 95 deletions(-) diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c index 4250e276a..8936b6033 100644 --- a/lib/asyn-thread.c +++ b/lib/asyn-thread.c @@ -407,9 +407,7 @@ static bool init_resolve_thread(struct connectdata *conn, #endif if(!td->thread_hnd) { -#ifndef _WIN32_WCE err = errno; -#endif goto err_exit; } @@ -418,8 +416,7 @@ static bool init_resolve_thread(struct connectdata *conn, err_exit: destroy_async_data(&conn->async); - SET_ERRNO(err); - + errno = err; return FALSE; } @@ -655,7 +652,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, /* fall-back to blocking version */ infof(conn->data, "init_resolve_thread() failed for %s; %s\n", - hostname, Curl_strerror(conn, ERRNO)); + hostname, Curl_strerror(conn, errno)); error = Curl_getaddrinfo_ex(hostname, sbuf, &hints, &res); if(error) { diff --git a/lib/connect.c b/lib/connect.c index e959c1e9b..8063cf005 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -607,7 +607,8 @@ void Curl_persistconninfo(struct connectdata *conn) conn->data->info.conn_local_port = conn->local_port; } -/* retrieves ip address and port from a sockaddr structure */ +/* retrieves ip address and port from a sockaddr structure. + note it calls Curl_inet_ntop which sets errno on fail, not SOCKERRNO. */ static bool getaddressinfo(struct sockaddr *sa, char *addr, long *port) { @@ -654,7 +655,7 @@ static bool getaddressinfo(struct sockaddr *sa, char *addr, addr[0] = '\0'; *port = 0; - + errno = EAFNOSUPPORT; return FALSE; } @@ -672,11 +673,9 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) return; if(!conn->bits.reuse && !conn->bits.tcp_fastopen) { - int error; - len = sizeof(struct Curl_sockaddr_storage); if(getpeername(sockfd, (struct sockaddr*) &ssrem, &len)) { - error = SOCKERRNO; + int error = SOCKERRNO; failf(data, "getpeername() failed with errno %d: %s", error, Curl_strerror(conn, error)); return; @@ -685,7 +684,7 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) len = sizeof(struct Curl_sockaddr_storage); memset(&ssloc, 0, sizeof(ssloc)); if(getsockname(sockfd, (struct sockaddr*) &ssloc, &len)) { - error = SOCKERRNO; + int error = SOCKERRNO; failf(data, "getsockname() failed with errno %d: %s", error, Curl_strerror(conn, error)); return; @@ -693,18 +692,16 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) if(!getaddressinfo((struct sockaddr*)&ssrem, conn->primary_ip, &conn->primary_port)) { - error = ERRNO; failf(data, "ssrem inet_ntop() failed with errno %d: %s", - error, Curl_strerror(conn, error)); + errno, Curl_strerror(conn, errno)); return; } memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN); if(!getaddressinfo((struct sockaddr*)&ssloc, conn->local_ip, &conn->local_port)) { - error = ERRNO; failf(data, "ssloc inet_ntop() failed with errno %d: %s", - error, Curl_strerror(conn, error)); + errno, Curl_strerror(conn, errno)); return; } @@ -995,9 +992,8 @@ static CURLcode singleipconnect(struct connectdata *conn, if(!getaddressinfo((struct sockaddr*)&addr.sa_addr, ipaddress, &port)) { /* malformed address or bug in inet_ntop, try next address */ - error = ERRNO; failf(data, "sa_addr inet_ntop() failed with errno %d: %s", - error, Curl_strerror(conn, error)); + errno, Curl_strerror(conn, errno)); Curl_closesocket(conn, sockfd); return CURLE_OK; } diff --git a/lib/curl_ntlm_wb.c b/lib/curl_ntlm_wb.c index 9f5b87bc3..9e9586cc3 100644 --- a/lib/curl_ntlm_wb.c +++ b/lib/curl_ntlm_wb.c @@ -123,7 +123,6 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp) struct passwd pw, *pw_res; char pwbuf[1024]; #endif - int error; /* Return if communication with ntlm_auth already set up */ if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD || @@ -178,26 +177,23 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp) ntlm_auth = NTLM_WB_FILE; if(access(ntlm_auth, X_OK) != 0) { - error = ERRNO; failf(conn->data, "Could not access ntlm_auth: %s errno %d: %s", - ntlm_auth, error, Curl_strerror(conn, error)); + ntlm_auth, errno, Curl_strerror(conn, errno)); goto done; } if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) { - error = ERRNO; failf(conn->data, "Could not open socket pair. errno %d: %s", - error, Curl_strerror(conn, error)); + errno, Curl_strerror(conn, errno)); goto done; } child_pid = fork(); if(child_pid == -1) { - error = ERRNO; sclose(sockfds[0]); sclose(sockfds[1]); failf(conn->data, "Could not fork. errno %d: %s", - error, Curl_strerror(conn, error)); + errno, Curl_strerror(conn, errno)); goto done; } else if(!child_pid) { @@ -208,16 +204,14 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp) /* Don't use sclose in the child since it fools the socket leak detector */ sclose_nolog(sockfds[0]); if(dup2(sockfds[1], STDIN_FILENO) == -1) { - error = ERRNO; failf(conn->data, "Could not redirect child stdin. errno %d: %s", - error, Curl_strerror(conn, error)); + errno, Curl_strerror(conn, errno)); exit(1); } if(dup2(sockfds[1], STDOUT_FILENO) == -1) { - error = ERRNO; failf(conn->data, "Could not redirect child stdout. errno %d: %s", - error, Curl_strerror(conn, error)); + errno, Curl_strerror(conn, errno)); exit(1); } @@ -235,10 +229,9 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp) "--username", username, NULL); - error = ERRNO; sclose_nolog(sockfds[1]); failf(conn->data, "Could not execl(). errno %d: %s", - error, Curl_strerror(conn, error)); + errno, Curl_strerror(conn, errno)); exit(1); } diff --git a/lib/curl_setup_once.h b/lib/curl_setup_once.h index 684187cae..a5b542c6e 100644 --- a/lib/curl_setup_once.h +++ b/lib/curl_setup_once.h @@ -435,20 +435,6 @@ typedef int sig_atomic_t; #endif -/* - * Macro ERRNO / SET_ERRNO() returns / sets the NOT *socket-related* errno - * (or equivalent) on this platform to hide platform details to code using it. - */ - -#if defined(WIN32) && !defined(USE_LWIPSOCK) -#define ERRNO ((int)GetLastError()) -#define SET_ERRNO(x) (SetLastError((DWORD)(x))) -#else -#define ERRNO (errno) -#define SET_ERRNO(x) (errno = (x)) -#endif - - /* * Portable error number symbolic names defined to Winsock error codes. */ diff --git a/lib/curl_threads.c b/lib/curl_threads.c index a78eff5c2..19897107a 100644 --- a/lib/curl_threads.c +++ b/lib/curl_threads.c @@ -104,15 +104,22 @@ int Curl_thread_join(curl_thread_t *hnd) curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void *), void *arg) { -#ifdef _WIN32_WCE - return CreateThread(NULL, 0, func, arg, 0, NULL); -#else curl_thread_t t; +#ifdef _WIN32_WCE + t = CreateThread(NULL, 0, func, arg, 0, NULL); +#else t = (curl_thread_t)_beginthreadex(NULL, 0, func, arg, 0, NULL); - if((t == 0) || (t == (curl_thread_t)-1L)) - return curl_thread_t_null; - return t; #endif + if((t == 0) || (t == (curl_thread_t)-1L)) { +#ifdef _WIN32_WCE + DWORD gle = GetLastError(); + errno = ((gle == ERROR_ACCESS_DENIED || + gle == ERROR_NOT_ENOUGH_MEMORY) ? + EACCES : EINVAL); +#endif + return curl_thread_t_null; + } + return t; } void Curl_thread_destroy(curl_thread_t hnd) diff --git a/lib/inet_ntop.c b/lib/inet_ntop.c index 9afbdbb32..22f08e84d 100644 --- a/lib/inet_ntop.c +++ b/lib/inet_ntop.c @@ -63,7 +63,7 @@ static char *inet_ntop4 (const unsigned char *src, char *dst, size_t size) len = strlen(tmp); if(len == 0 || len >= size) { - SET_ERRNO(ENOSPC); + errno = ENOSPC; return (NULL); } strcpy(dst, tmp); @@ -142,7 +142,7 @@ 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))) { - SET_ERRNO(ENOSPC); + errno = ENOSPC; return (NULL); } tp += strlen(tp); @@ -160,7 +160,7 @@ static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size) /* Check for overflow, copy, and we're done. */ if((size_t)(tp - tmp) > size) { - SET_ERRNO(ENOSPC); + errno = ENOSPC; return (NULL); } strcpy(dst, tmp); @@ -177,8 +177,8 @@ static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size) * * On Windows we store the error in the thread errno, not * in the winsock error code. This is to avoid losing the - * actual last winsock error. So use macro ERRNO to fetch the - * errno this function sets when returning NULL, not SOCKERRNO. + * actual last winsock error. So when this function returns + * NULL, check errno not SOCKERRNO. */ char *Curl_inet_ntop(int af, const void *src, char *buf, size_t size) { @@ -190,7 +190,7 @@ char *Curl_inet_ntop(int af, const void *src, char *buf, size_t size) return inet_ntop6((const unsigned char *)src, buf, size); #endif default: - SET_ERRNO(EAFNOSUPPORT); + errno = EAFNOSUPPORT; return NULL; } } diff --git a/lib/inet_pton.c b/lib/inet_pton.c index 475f44abc..fef9610d1 100644 --- a/lib/inet_pton.c +++ b/lib/inet_pton.c @@ -57,8 +57,8 @@ static int inet_pton6(const char *src, unsigned char *dst); * notice: * On Windows we store the error in the thread errno, not * in the winsock error code. This is to avoid losing the - * actual last winsock error. So use macro ERRNO to fetch the - * errno this function sets when returning (-1), not SOCKERRNO. + * actual last winsock error. So when this function returns + * -1, check errno not SOCKERRNO. * author: * Paul Vixie, 1996. */ @@ -73,7 +73,7 @@ Curl_inet_pton(int af, const char *src, void *dst) return (inet_pton6(src, (unsigned char *)dst)); #endif default: - SET_ERRNO(EAFNOSUPPORT); + errno = EAFNOSUPPORT; return (-1); } /* NOTREACHED */ diff --git a/lib/non-ascii.c b/lib/non-ascii.c index 2f5de4c68..ae0097036 100644 --- a/lib/non-ascii.c +++ b/lib/non-ascii.c @@ -98,19 +98,17 @@ CURLcode Curl_convert_to_network(struct Curl_easy *data, /* do the translation ourselves */ char *input_ptr, *output_ptr; size_t in_bytes, out_bytes, rc; - int error; /* open an iconv conversion descriptor if necessary */ if(data->outbound_cd == (iconv_t)-1) { data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK, CURL_ICONV_CODESET_OF_HOST); if(data->outbound_cd == (iconv_t)-1) { - error = ERRNO; failf(data, "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s", CURL_ICONV_CODESET_OF_NETWORK, CURL_ICONV_CODESET_OF_HOST, - error, strerror(error)); + errno, strerror(errno)); return CURLE_CONV_FAILED; } } @@ -120,10 +118,9 @@ CURLcode Curl_convert_to_network(struct Curl_easy *data, rc = iconv(data->outbound_cd, (const char **)&input_ptr, &in_bytes, &output_ptr, &out_bytes); if((rc == ICONV_ERROR) || (in_bytes != 0)) { - error = ERRNO; failf(data, "The Curl_convert_to_network iconv call failed with errno %i: %s", - error, strerror(error)); + errno, strerror(errno)); return CURLE_CONV_FAILED; } #else @@ -158,19 +155,17 @@ CURLcode Curl_convert_from_network(struct Curl_easy *data, /* do the translation ourselves */ char *input_ptr, *output_ptr; size_t in_bytes, out_bytes, rc; - int error; /* open an iconv conversion descriptor if necessary */ if(data->inbound_cd == (iconv_t)-1) { data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST, CURL_ICONV_CODESET_OF_NETWORK); if(data->inbound_cd == (iconv_t)-1) { - error = ERRNO; failf(data, "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s", CURL_ICONV_CODESET_OF_HOST, CURL_ICONV_CODESET_OF_NETWORK, - error, strerror(error)); + errno, strerror(errno)); return CURLE_CONV_FAILED; } } @@ -180,10 +175,9 @@ CURLcode Curl_convert_from_network(struct Curl_easy *data, rc = iconv(data->inbound_cd, (const char **)&input_ptr, &in_bytes, &output_ptr, &out_bytes); if((rc == ICONV_ERROR) || (in_bytes != 0)) { - error = ERRNO; failf(data, "Curl_convert_from_network iconv call failed with errno %i: %s", - error, strerror(error)); + errno, strerror(errno)); return CURLE_CONV_FAILED; } #else @@ -219,19 +213,17 @@ CURLcode Curl_convert_from_utf8(struct Curl_easy *data, const char *input_ptr; char *output_ptr; size_t in_bytes, out_bytes, rc; - int error; /* open an iconv conversion descriptor if necessary */ if(data->utf8_cd == (iconv_t)-1) { data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST, CURL_ICONV_CODESET_FOR_UTF8); if(data->utf8_cd == (iconv_t)-1) { - error = ERRNO; failf(data, "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s", CURL_ICONV_CODESET_OF_HOST, CURL_ICONV_CODESET_FOR_UTF8, - error, strerror(error)); + errno, strerror(errno)); return CURLE_CONV_FAILED; } } @@ -241,10 +233,9 @@ CURLcode Curl_convert_from_utf8(struct Curl_easy *data, rc = iconv(data->utf8_cd, &input_ptr, &in_bytes, &output_ptr, &out_bytes); if((rc == ICONV_ERROR) || (in_bytes != 0)) { - error = ERRNO; failf(data, "The Curl_convert_from_utf8 iconv call failed with errno %i: %s", - error, strerror(error)); + errno, strerror(errno)); return CURLE_CONV_FAILED; } if(output_ptr < input_ptr) { diff --git a/lib/parsedate.c b/lib/parsedate.c index 3c783be48..609fd5363 100644 --- a/lib/parsedate.c +++ b/lib/parsedate.c @@ -404,12 +404,12 @@ static int parsedate(const char *date, time_t *output) int error; int old_errno; - old_errno = ERRNO; - SET_ERRNO(0); + old_errno = errno; + errno = 0; lval = strtol(date, &end, 10); - error = ERRNO; - if(error != old_errno) - SET_ERRNO(old_errno); + error = errno; + if(errno != old_errno) + errno = old_errno; if(error) return PARSEDATE_FAIL; diff --git a/lib/strerror.c b/lib/strerror.c index 7e5cde47b..35dc0a421 100644 --- a/lib/strerror.c +++ b/lib/strerror.c @@ -630,11 +630,15 @@ const char *Curl_strerror(struct connectdata *conn, int err) { char *buf, *p; size_t max; - int old_errno = ERRNO; + int old_errno; + DWORD old_win_err; DEBUGASSERT(conn); DEBUGASSERT(err >= 0); + old_errno = errno; + old_win_err = GetLastError(); + buf = conn->syserr_buf; max = sizeof(conn->syserr_buf)-1; *buf = '\0'; @@ -722,8 +726,11 @@ const char *Curl_strerror(struct connectdata *conn, int err) if(p && (p - buf) >= 1) *p = '\0'; - if(old_errno != ERRNO) - SET_ERRNO(old_errno); + if(old_win_err != GetLastError()) + SetLastError(old_win_err); + + if(errno != old_errno) + errno = old_errno; return buf; } @@ -737,6 +744,7 @@ const char *Curl_sspi_strerror (struct connectdata *conn, int err) char *p, *str, *msg = NULL; bool msg_formatted = FALSE; int old_errno; + DWORD old_win_err; #endif const char *txt; char *outbuf; @@ -750,7 +758,8 @@ const char *Curl_sspi_strerror (struct connectdata *conn, int err) #ifndef CURL_DISABLE_VERBOSE_STRINGS - old_errno = ERRNO; + old_errno = errno; + old_win_err = GetLastError(); switch(err) { case SEC_E_OK: @@ -1051,8 +1060,11 @@ const char *Curl_sspi_strerror (struct connectdata *conn, int err) strncpy(outbuf, str, outmax); } - if(old_errno != ERRNO) - SET_ERRNO(old_errno); + if(old_win_err != GetLastError()) + SetLastError(old_win_err); + + if(errno != old_errno) + errno = old_errno; #else diff --git a/lib/strtoofft.c b/lib/strtoofft.c index b854bf4de..bd3432ab8 100644 --- a/lib/strtoofft.c +++ b/lib/strtoofft.c @@ -132,7 +132,7 @@ curlx_strtoll(const char *nptr, char **endptr, int base) else value = CURL_OFF_T_MAX; - SET_ERRNO(ERANGE); + errno = ERANGE; } if(endptr) diff --git a/lib/telnet.c b/lib/telnet.c index 122100523..269b193d0 100644 --- a/lib/telnet.c +++ b/lib/telnet.c @@ -1357,14 +1357,14 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) /* load ws2_32.dll and get the function pointers we need. */ wsock2 = Curl_load_library(TEXT("WS2_32.DLL")); if(wsock2 == NULL) { - failf(data, "failed to load WS2_32.DLL (%d)", ERRNO); + failf(data, "failed to load WS2_32.DLL (%u)", GetLastError()); return CURLE_FAILED_INIT; } /* Grab a pointer to WSACreateEvent */ create_event_func = GetProcAddress(wsock2, "WSACreateEvent"); if(create_event_func == NULL) { - failf(data, "failed to find WSACreateEvent function (%d)", ERRNO); + failf(data, "failed to find WSACreateEvent function (%u)", GetLastError()); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } @@ -1372,7 +1372,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) /* And WSACloseEvent */ close_event_func = GetProcAddress(wsock2, "WSACloseEvent"); if(close_event_func == NULL) { - failf(data, "failed to find WSACloseEvent function (%d)", ERRNO); + failf(data, "failed to find WSACloseEvent function (%u)", GetLastError()); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } @@ -1380,7 +1380,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) /* And WSAEventSelect */ event_select_func = GetProcAddress(wsock2, "WSAEventSelect"); if(event_select_func == NULL) { - failf(data, "failed to find WSAEventSelect function (%d)", ERRNO); + failf(data, "failed to find WSAEventSelect function (%u)", GetLastError()); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } @@ -1388,7 +1388,8 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) /* And WSAEnumNetworkEvents */ enum_netevents_func = GetProcAddress(wsock2, "WSAEnumNetworkEvents"); if(enum_netevents_func == NULL) { - failf(data, "failed to find WSAEnumNetworkEvents function (%d)", ERRNO); + failf(data, "failed to find WSAEnumNetworkEvents function (%u)", + GetLastError()); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } @@ -1581,7 +1582,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) /* We called LoadLibrary, so call FreeLibrary */ if(!FreeLibrary(wsock2)) - infof(data, "FreeLibrary(wsock2) failed (%d)", ERRNO); + infof(data, "FreeLibrary(wsock2) failed (%u)", GetLastError()); #else pfd[0].fd = sockfd; pfd[0].events = POLLIN; diff --git a/src/tool_dirhie.c b/src/tool_dirhie.c index 23bb2cb42..1d7359205 100644 --- a/src/tool_dirhie.c +++ b/src/tool_dirhie.c @@ -50,7 +50,7 @@ static void show_dir_errno(FILE *errors, const char *name) { - switch(ERRNO) { + switch(errno) { #ifdef EACCES case EACCES: fprintf(errors, "You don't have permission to create %s.\n", name); diff --git a/src/tool_paramhlp.c b/src/tool_paramhlp.c index 6b534ce5d..ee37931b8 100644 --- a/src/tool_paramhlp.c +++ b/src/tool_paramhlp.c @@ -383,11 +383,11 @@ ParameterError str2offset(curl_off_t *val, const char *str) #if(CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG) *val = curlx_strtoofft(str, &endptr, 0); - if((*val == CURL_OFF_T_MAX || *val == CURL_OFF_T_MIN) && (ERRNO == ERANGE)) + if((*val == CURL_OFF_T_MAX || *val == CURL_OFF_T_MIN) && (errno == ERANGE)) return PARAM_BAD_NUMERIC; #else *val = strtol(str, &endptr, 0); - if((*val == LONG_MIN || *val == LONG_MAX) && ERRNO == ERANGE) + if((*val == LONG_MIN || *val == LONG_MAX) && errno == ERANGE) return PARAM_BAD_NUMERIC; #endif if((endptr != str) && (endptr == str + strlen(str)))