diff --git a/main/network.c b/main/network.c index 70dc5055828..47c0dba1d27 100644 --- a/main/network.c +++ b/main/network.c @@ -1036,6 +1036,28 @@ PHPAPI socklen_t php_sockaddr_size(php_sockaddr_storage *addr) } /* }}} */ +#ifdef PHP_WIN32 +char *php_socket_strerror_s(long err, char *buf, size_t bufsize) +{ + if (buf == NULL) { + char ebuf[1024]; + errno_t res = strerror_s(ebuf, sizeof(ebuf), err); + if (res == 0) { + buf = estrdup(ebuf); + } else { + buf = estrdup("Unknown error"); + } + } else { + errno_t res = strerror_s(buf, bufsize, err); + if (res != 0) { + strncpy(buf, "Unknown error", bufsize); + buf[bufsize?(bufsize-1):0] = 0; + } + } + return buf; +} +#endif + /* Given a socket error code, if buf == NULL: * emallocs storage for the error message and returns * else @@ -1045,16 +1067,40 @@ PHPAPI socklen_t php_sockaddr_size(php_sockaddr_storage *addr) PHPAPI char *php_socket_strerror(long err, char *buf, size_t bufsize) { #ifndef PHP_WIN32 - char *errstr; - - errstr = strerror(err); +# ifdef HAVE_STRERROR_R + if (buf == NULL) { + char ebuf[1024]; +# ifdef STRERROR_R_CHAR_P + char *errstr = strerror_r(err, ebuf, sizeof(ebuf)); + buf = estrdup(errstr); +# else + errno_t res = strerror_r(err, ebuf, sizeof(ebuf)); + if (res == 0) { + buf = estrdup(ebuf); + } else { + buf = estrdup("Unknown error"); + } +# endif + } else { +# ifdef STRERROR_R_CHAR_P + buf = strerror_r(err, buf, bufsize); +# else + errno_t res = strerror_r(err, buf, bufsize); + if (res != 0) { + strncpy(buf, "Unknown error", bufsize); + buf[bufsize?(bufsize-1):0] = 0; + } +# endif + } +# else + char *errstr = strerror(err); if (buf == NULL) { buf = estrdup(errstr); } else { strncpy(buf, errstr, bufsize); buf[bufsize?(bufsize-1):0] = 0; } - return buf; +# endif #else char *sysbuf = php_win32_error_to_msg(err); if (!sysbuf[0]) { @@ -1069,9 +1115,8 @@ PHPAPI char *php_socket_strerror(long err, char *buf, size_t bufsize) } php_win32_error_msg_free(sysbuf); - - return buf; #endif + return buf; } /* }}} */ @@ -1079,9 +1124,22 @@ PHPAPI char *php_socket_strerror(long err, char *buf, size_t bufsize) PHPAPI zend_string *php_socket_error_str(long err) { #ifndef PHP_WIN32 - char *errstr; - - errstr = strerror(err); +# ifdef HAVE_STRERROR_R + char ebuf[1024]; +# ifdef STRERROR_R_CHAR_P + char *errstr = strerror_r(err, ebuf, sizeof(ebuf)); +# else + const char *errstr; + errno_t res = strerror_r(err, ebuf, sizeof(ebuf)); + if (res == 0) { + errstr = ebuf; + } else { + errstr = "Unknown error"; + } +# endif +# else + char *errstr = strerror(err); +# endif return zend_string_init(errstr, strlen(errstr), 0); #else zend_string *ret; diff --git a/main/php_network.h b/main/php_network.h index 1d941265bd9..6df73cf7af0 100644 --- a/main/php_network.h +++ b/main/php_network.h @@ -64,6 +64,11 @@ * unless buf is not NULL. * Also works sensibly for win32 */ BEGIN_EXTERN_C() +#ifdef PHP_WIN32 +char *php_socket_strerror_s(long err, char *buf, size_t bufsize); +#else +#define php_socket_strerror_s php_socket_strerror +#endif PHPAPI char *php_socket_strerror(long err, char *buf, size_t bufsize); PHPAPI zend_string *php_socket_error_str(long err); END_EXTERN_C() diff --git a/main/rfc1867.c b/main/rfc1867.c index 84b8788bbf7..f6ffb6fabc7 100644 --- a/main/rfc1867.c +++ b/main/rfc1867.c @@ -1048,7 +1048,8 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) if (wlen == (size_t)-1) { /* write failed */ #if DEBUG_FILE_UPLOAD - sapi_module.sapi_error(E_NOTICE, "write() failed - %s", strerror(errno)); + char errstr[256]; + sapi_module.sapi_error(E_NOTICE, "write() failed - %s", php_socket_strerror_s(errno, errstr, sizeof(errstr))); #endif cancel_upload = PHP_UPLOAD_ERROR_F; } else if (wlen < blen) { diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index a8fd70b8d6a..829c8d74dc8 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -368,7 +368,9 @@ static ssize_t php_stdiop_write(php_stream *stream, const char *buf, size_t coun return bytes_written; } if (!(stream->flags & PHP_STREAM_FLAG_SUPPRESS_ERRORS)) { - php_error_docref(NULL, E_NOTICE, "Write of %zu bytes failed with errno=%d %s", count, errno, strerror(errno)); + char errstr[256]; + php_error_docref(NULL, E_NOTICE, "Write of %zu bytes failed with errno=%d %s", + count, errno, php_socket_strerror_s(errno, errstr, sizeof(errstr))); } } } else { @@ -444,7 +446,9 @@ static ssize_t php_stdiop_read(php_stream *stream, char *buf, size_t count) /* TODO: Should this be treated as a proper error or not? */ } else { if (!(stream->flags & PHP_STREAM_FLAG_SUPPRESS_ERRORS)) { - php_error_docref(NULL, E_NOTICE, "Read of %zu bytes failed with errno=%d %s", count, errno, strerror(errno)); + char errstr[256]; + php_error_docref(NULL, E_NOTICE, "Read of %zu bytes failed with errno=%d %s", + count, errno, php_socket_strerror_s(errno, errstr, sizeof(errstr))); } /* TODO: Remove this special-case? */ @@ -1281,7 +1285,9 @@ static int php_plain_files_unlink(php_stream_wrapper *wrapper, const char *url, ret = VCWD_UNLINK(url); if (ret == -1) { if (options & REPORT_ERRORS) { - php_error_docref1(NULL, url, E_WARNING, "%s", strerror(errno)); + char errstr[256]; + php_error_docref1(NULL, url, E_WARNING, "%s", + php_socket_strerror_s(errno, errstr, sizeof(errstr))); } return 0; } @@ -1327,6 +1333,7 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f if (ret == -1) { #ifndef PHP_WIN32 + char errstr[256]; # ifdef EXDEV if (errno == EXDEV) { zend_stat_t sb; @@ -1347,7 +1354,8 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f * access to the file in the meantime. */ if (VCWD_CHOWN(url_to, sb.st_uid, sb.st_gid)) { - php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); + php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", + php_socket_strerror_s(errno, errstr, sizeof(errstr))); if (errno != EPERM) { success = 0; } @@ -1355,7 +1363,8 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f if (success) { if (VCWD_CHMOD(url_to, sb.st_mode)) { - php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); + php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", + php_socket_strerror_s(errno, errstr, sizeof(errstr))); if (errno != EPERM) { success = 0; } @@ -1366,10 +1375,12 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f VCWD_UNLINK(url_from); } } else { - php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); + php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", + php_socket_strerror_s(errno, errstr, sizeof(errstr))); } } else { - php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); + php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", + php_socket_strerror_s(errno, errstr, sizeof(errstr))); } # if !defined(ZTS) && !defined(TSRM_WIN32) umask(oldmask); @@ -1382,7 +1393,8 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f #ifdef PHP_WIN32 php_win32_docref2_from_error(GetLastError(), url_from, url_to); #else - php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); + php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", + php_socket_strerror_s(errno, errstr, sizeof(errstr))); #endif return 0; } @@ -1462,11 +1474,12 @@ static int php_plain_files_mkdir(php_stream_wrapper *wrapper, const char *dir, i if (!p) { p = buf; } + char errstr[256]; while (true) { int ret = VCWD_MKDIR(buf, (mode_t) mode); if (ret < 0 && errno != EEXIST) { if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "%s", strerror(errno)); + php_error_docref(NULL, E_WARNING, "%s", php_socket_strerror_s(errno, errstr, sizeof(errstr))); } return 0; } @@ -1486,7 +1499,7 @@ static int php_plain_files_mkdir(php_stream_wrapper *wrapper, const char *dir, i /* issue a warning to client when the last directory was created failed */ if (ret < 0) { if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "%s", strerror(errno)); + php_error_docref(NULL, E_WARNING, "%s", php_socket_strerror_s(errno, errstr, sizeof(errstr))); } return 0; } @@ -1505,15 +1518,16 @@ static int php_plain_files_rmdir(php_stream_wrapper *wrapper, const char *url, i return 0; } + char errstr[256]; #ifdef PHP_WIN32 if (!php_win32_check_trailing_space(url, strlen(url))) { - php_error_docref1(NULL, url, E_WARNING, "%s", strerror(ENOENT)); + php_error_docref1(NULL, url, E_WARNING, "%s", php_socket_strerror_s(ENOENT, errstr, sizeof(errstr))); return 0; } #endif if (VCWD_RMDIR(url) < 0) { - php_error_docref1(NULL, url, E_WARNING, "%s", strerror(errno)); + php_error_docref1(NULL, url, E_WARNING, "%s", php_socket_strerror_s(errno, errstr, sizeof(errstr))); return 0; } @@ -1532,10 +1546,11 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url #endif mode_t mode; int ret = 0; + char errstr[256]; #ifdef PHP_WIN32 if (!php_win32_check_trailing_space(url, strlen(url))) { - php_error_docref1(NULL, url, E_WARNING, "%s", strerror(ENOENT)); + php_error_docref1(NULL, url, E_WARNING, "%s", php_socket_strerror_s(ENOENT, errstr, sizeof(errstr))); return 0; } #endif @@ -1554,7 +1569,8 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url if (VCWD_ACCESS(url, F_OK) != 0) { FILE *file = VCWD_FOPEN(url, "w"); if (file == NULL) { - php_error_docref1(NULL, url, E_WARNING, "Unable to create file %s because %s", url, strerror(errno)); + php_error_docref1(NULL, url, E_WARNING, "Unable to create file %s because %s", url, + php_socket_strerror_s(errno, errstr, sizeof(errstr))); return 0; } fclose(file); @@ -1597,7 +1613,8 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url return 0; } if (ret == -1) { - php_error_docref1(NULL, url, E_WARNING, "Operation failed: %s", strerror(errno)); + php_error_docref1(NULL, url, E_WARNING, "Operation failed: %s", + php_socket_strerror_s(errno, errstr, sizeof(errstr))); return 0; } php_clear_stat_cache(0, NULL, 0); diff --git a/main/streams/streams.c b/main/streams/streams.c index dde84a9990f..7f6765ba062 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -204,7 +204,8 @@ static void php_stream_display_wrapper_errors(php_stream_wrapper *wrapper, const free_msg = 1; } else { if (wrapper == &php_plain_files_wrapper) { - msg = strerror(errno); /* TODO: not ts on linux */ + char errstr[256]; + msg = php_socket_strerror_s(errno, errstr, sizeof(errstr)); } else { msg = "operation failed"; } diff --git a/main/streams/xp_socket.c b/main/streams/xp_socket.c index ae8cf24c392..ca6bf0b580b 100644 --- a/main/streams/xp_socket.c +++ b/main/streams/xp_socket.c @@ -678,9 +678,10 @@ static inline int php_tcp_sockop_bind(php_stream *stream, php_netstream_data_t * if (sock->socket == SOCK_ERR) { if (xparam->want_errortext) { + char errstr[256]; xparam->outputs.error_text = strpprintf(0, "Failed to create unix%s socket %s", stream->ops == &php_stream_unix_socket_ops ? "" : "datagram", - strerror(errno)); + php_socket_strerror_s(errno, errstr, sizeof(errstr))); } return -1; }