VLOG_DEFINE_THIS_MODULE(util);
+COVERAGE_DEFINE(util_xalloc);
+
const char *program_name;
void
return s;
}
+/* Similar to strlcpy() from OpenBSD, but it never reads more than 'size - 1'
+ * bytes from 'src' and doesn't return anything. */
void
ovs_strlcpy(char *dst, const char *src, size_t size)
{
if (size > 0) {
- size_t n = strlen(src);
- size_t n_copy = MIN(n, size - 1);
- memcpy(dst, src, n_copy);
- dst[n_copy] = '\0';
+ size_t len = strnlen(src, size - 1);
+ memcpy(dst, src, len);
+ dst[len] = '\0';
}
}
vfprintf(stderr, format, args);
va_end(args);
if (err_no != 0)
- fprintf(stderr, " (%s)",
- err_no == EOF ? "end of file" : strerror(err_no));
+ fprintf(stderr, " (%s)", ovs_retval_to_string(err_no));
putc('\n', stderr);
exit(EXIT_FAILURE);
vfprintf(stderr, format, args);
va_end(args);
if (err_no != 0) {
- fprintf(stderr, " (%s)",
- err_no == EOF ? "end of file" : strerror(err_no));
+ fprintf(stderr, " (%s)", ovs_retval_to_string(err_no));
}
putc('\n', stderr);
errno = save_errno;
}
+/* Many OVS functions return an int which is one of:
+ * - 0: no error yet
+ * - >0: errno value
+ * - EOF: end of file (not necessarily an error; depends on the function called)
+ *
+ * Returns the appropriate human-readable string. The caller must copy the
+ * string if it wants to hold onto it, as the storage may be overwritten on
+ * subsequent function calls.
+ */
+const char *
+ovs_retval_to_string(int retval)
+{
+ static char unknown[48];
+
+ if (!retval) {
+ return "";
+ }
+ if (retval > 0) {
+ return strerror(retval);
+ }
+ if (retval == EOF) {
+ return "End of file";
+ }
+ snprintf(unknown, sizeof unknown, "***unknown return value: %d***", retval);
+ return unknown;
+}
+
/* Sets program_name based on 'argv0'. Should be called at the beginning of
* main(), as "set_program_name(argv[0]);". */
void set_program_name(const char *argv0)