size_t msglen;
char *p;
size_t errbuflen_remaining;
-#if defined(HAVE_STRERROR_S)
- errno_t err;
-#elif defined(HAVE_STRERROR_R)
- int err;
-#endif
va_start(ap, fmt);
- pcap_vsnprintf(errbuf, errbuflen, fmt, ap);
+ vsnprintf(errbuf, errbuflen, fmt, ap);
va_end(ap);
msglen = strlen(errbuf);
* Now append the string for the error code.
*/
#if defined(HAVE_STRERROR_S)
- err = strerror_s(p, errbuflen_remaining, errnum);
+ /*
+ * We have a Windows-style strerror_s().
+ */
+ errno_t err = strerror_s(p, errbuflen_remaining, errnum);
if (err != 0) {
/*
* It doesn't appear to be documented anywhere obvious
* what the error returns from strerror_s().
*/
- pcap_snprintf(p, errbuflen_remaining, "Error %d", errnum);
+ snprintf(p, errbuflen_remaining, "Error %d", errnum);
}
-#elif defined(HAVE_STRERROR_R)
- err = strerror_r(errnum, p, errbuflen_remaining);
+#elif defined(HAVE_GNU_STRERROR_R)
+ /*
+ * We have a GNU-style strerror_r(), which is *not* guaranteed to
+ * do anything to the buffer handed to it, and which returns a
+ * pointer to the error string, which may or may not be in
+ * the buffer.
+ *
+ * It is, however, guaranteed to succeed.
+ */
+ char strerror_buf[PCAP_ERRBUF_SIZE];
+ char *errstring = strerror_r(errnum, strerror_buf, PCAP_ERRBUF_SIZE);
+ snprintf(p, errbuflen_remaining, "%s", errstring);
+#elif defined(HAVE_POSIX_STRERROR_R)
+ /*
+ * We have a POSIX-style strerror_r(), which is guaranteed to fill
+ * in the buffer, but is not guaranteed to succeed.
+ */
+ int err = strerror_r(errnum, p, errbuflen_remaining);
if (err == EINVAL) {
/*
* UNIX 03 says this isn't guaranteed to produce a
* fallback error message.
*/
- pcap_snprintf(p, errbuflen_remaining, "Unknown error: %d",
+ snprintf(p, errbuflen_remaining, "Unknown error: %d",
errnum);
} else if (err == ERANGE) {
/*
* UNIX 03 says this isn't guaranteed to produce a
* fallback error message.
*/
- pcap_snprintf(p, errbuflen_remaining,
+ snprintf(p, errbuflen_remaining,
"Message for error %d is too long", errnum);
}
#else
* We have neither strerror_s() nor strerror_r(), so we're
* stuck with using pcap_strerror().
*/
- pcap_snprintf(p, errbuflen_remaining, "%s", pcap_strerror(errnum));
+ snprintf(p, errbuflen_remaining, "%s", pcap_strerror(errnum));
#endif
}
#ifdef _WIN32
/*
- * Generate a string for a Win32-specific error (i.e. an error generated when
- * calling a Win32 API).
- * For errors occurred during standard C calls, we still use pcap_strerror().
+ * Generate an error message based on a format, arguments, and a
+ * Win32 error, with a message for the Win32 error after the formatted output.
*/
void
-pcap_win32_err_to_str(DWORD error, char *errbuf)
+pcap_fmt_errmsg_for_win32_err(char *errbuf, size_t errbuflen, DWORD errnum,
+ const char *fmt, ...)
{
- DWORD retval;
- size_t errlen;
+ va_list ap;
+ size_t msglen;
char *p;
+ size_t errbuflen_remaining;
+ DWORD retval;
+ char win32_errbuf[PCAP_ERRBUF_SIZE+1];
+
+ va_start(ap, fmt);
+ vsnprintf(errbuf, errbuflen, fmt, ap);
+ va_end(ap);
+ msglen = strlen(errbuf);
/*
+ * Do we have enough space to append ": "?
+ * Including the terminating '\0', that's 3 bytes.
+ */
+ if (msglen + 3 > errbuflen) {
+ /* No - just give them what we've produced. */
+ return;
+ }
+ p = errbuf + msglen;
+ errbuflen_remaining = errbuflen - msglen;
+ *p++ = ':';
+ *p++ = ' ';
+ *p = '\0';
+ msglen += 2;
+ errbuflen_remaining -= 2;
+
+ /*
+ * Now append the string for the error code.
+ *
* XXX - what language ID to use?
*
* For UN*Xes, pcap_strerror() may or may not return localized
* happen to understand.
*/
retval = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_MAX_WIDTH_MASK,
- NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- errbuf, PCAP_ERRBUF_SIZE, NULL);
+ NULL, errnum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ win32_errbuf, PCAP_ERRBUF_SIZE, NULL);
if (retval == 0) {
/*
* Failed.
*/
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "Couldn't get error message for error (%lu)", error);
+ snprintf(p, errbuflen_remaining,
+ "Couldn't get error message for error (%lu)", errnum);
return;
}
- /*
- * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
- * message. Get rid of it.
- *
- * XXX - still true with FORMAT_MESSAGE_MAX_WIDTH_MASK?
- */
- errlen = strlen(errbuf);
- if (errlen >= 2 &&
- errbuf[errlen - 2] == '\r' && errbuf[errlen - 1] == '\n') {
- errbuf[errlen - 2] = '\0';
- errbuf[errlen - 1] = '\0';
- }
- p = strchr(errbuf, '\0');
- pcap_snprintf(p, PCAP_ERRBUF_SIZE+1-(p-errbuf), " (%lu)", error);
+ snprintf(p, errbuflen_remaining, "%s (%lu)", win32_errbuf, errnum);
}
#endif