aboutsummaryrefslogtreecommitdiffhomepage
path: root/wutil.cpp
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2013-01-09 17:06:20 -0800
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2013-01-09 17:06:20 -0800
commitc70e92e98d34e14b1e1310a10677b7c0f6e2b54c (patch)
treeb5f2d4e2bfd8ff9a3e9b5ca8a21b81f48302d7d9 /wutil.cpp
parentbf10d6c03b1751bf7ae702508df02e238a1429c7 (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.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/wutil.cpp b/wutil.cpp
index 75fbac55..7d2d200d 100644
--- a/wutil.cpp
+++ b/wutil.cpp
@@ -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)