diff options
author | ridiculousfish <corydoras@ridiculousfish.com> | 2013-01-09 17:06:20 -0800 |
---|---|---|
committer | ridiculousfish <corydoras@ridiculousfish.com> | 2013-01-09 17:06:20 -0800 |
commit | c70e92e98d34e14b1e1310a10677b7c0f6e2b54c (patch) | |
tree | b5f2d4e2bfd8ff9a3e9b5ca8a21b81f48302d7d9 /wutil.cpp | |
parent | bf10d6c03b1751bf7ae702508df02e238a1429c7 (diff) |
Don't call strerror or perror after fork, it's unsafe. Added safe_strerror and safe_perror replacements.
Diffstat (limited to 'wutil.cpp')
-rw-r--r-- | wutil.cpp | 49 |
1 files changed, 49 insertions, 0 deletions
@@ -292,6 +292,55 @@ void wperror(const wcstring &s) fwprintf(stderr, L"%s\n", strerror(e)); } +static inline void safe_append(char *buffer, const char *s, size_t buffsize) +{ + strncat(buffer, s, buffsize - strlen(buffer) - 1); +} + +const char *safe_strerror(int err) +{ + if (err >= 0 && err < sys_nerr && sys_errlist[err] != NULL) + { + return sys_errlist[err]; + } + else + { + int saved_err = errno; + + /* Use a shared buffer for this case */ + static char buff[384]; + char errnum_buff[64]; + format_long_safe(errnum_buff, err); + + buff[0] = '\0'; + safe_append(buff, "unknown error (errno was ", sizeof buff); + safe_append(buff, errnum_buff, sizeof buff); + safe_append(buff, ")", sizeof buff); + + errno = saved_err; + return buff; + } +} + +void safe_perror(const char *message) +{ + // Note we cannot use strerror, because on Linux it uses gettext, which is not safe + int err = errno; + + char buff[384]; + buff[0] = '\0'; + + if (message) { + safe_append(buff, message, sizeof buff); + safe_append(buff, ": ", sizeof buff); + } + safe_append(buff, safe_strerror(err), sizeof buff); + safe_append(buff, "\n", sizeof buff); + + write(STDERR_FILENO, buff, strlen(buff)); + errno = err; +} + #ifdef HAVE_REALPATH_NULL wchar_t *wrealpath(const wcstring &pathname, wchar_t *resolved_path) |