util: New ovs_retval_to_string() function.
authorAndrew Evans <aevans@nicira.com>
Sun, 30 Jan 2011 19:29:14 +0000 (11:29 -0800)
committerAndrew Evans <aevans@nicira.com>
Mon, 31 Jan 2011 01:54:59 +0000 (17:54 -0800)
Many OVS functions return 0, EOF, or errno. There are several places in the
codebase where a return value is converted to a string. All must decide whether
the return value is set, and if it is, whether it is an errno value, EOF, or
otherwise invalid. This commit consolidates that code.

Reviewed by Ben Pfaff.

lib/jsonrpc.c
lib/ovsdb-error.c
lib/pcap.c
lib/util.c
lib/util.h
ofproto/ofproto.c

index 7c761ea0dcf5a736e59cb60ce0a4e436bc8e1be6..fb20bc585663b16e0496eb8693ec27843c555701 100644 (file)
@@ -142,6 +142,12 @@ jsonrpc_wait(struct jsonrpc *rpc)
     }
 }
 
+/*
+ * Possible status values:
+ * - 0: no error yet
+ * - >0: errno value
+ * - EOF: end of file (remote end closed connection; not necessarily an error)
+ */
 int
 jsonrpc_get_status(const struct jsonrpc *rpc)
 {
index db8019f385225e8df95bdd11a314b9bb6c80ede5..d6b4576ea27b8b1a9685b766184af809a3fe8ec7 100644 (file)
@@ -237,4 +237,3 @@ ovsdb_error_assert(struct ovsdb_error *error)
         ovsdb_error_destroy(error);
     }
 }
-
index 8c52f48347faab06f7d447c4c072fd8f081ffec4..afd41fa814c08d4f6752563e7decd8db8b7c3b65 100644 (file)
@@ -76,8 +76,7 @@ pcap_read_header(FILE *file)
     struct pcap_hdr ph;
     if (fread(&ph, sizeof ph, 1, file) != 1) {
         int error = ferror(file) ? errno : EOF;
-        VLOG_WARN("failed to read pcap header: %s",
-                  error > 0 ? strerror(error) : "end of file");
+        VLOG_WARN("failed to read pcap header: %s", ovs_retval_to_string(error));
         return error;
     }
     if (ph.magic_number != 0xa1b2c3d4 && ph.magic_number != 0xd4c3b2a1) {
@@ -118,7 +117,7 @@ pcap_read(FILE *file, struct ofpbuf **bufp)
     if (fread(&prh, sizeof prh, 1, file) != 1) {
         int error = ferror(file) ? errno : EOF;
         VLOG_WARN("failed to read pcap record header: %s",
-                  error > 0 ? strerror(error) : "end of file");
+                  ovs_retval_to_string(error));
         return error;
     }
 
@@ -144,7 +143,7 @@ pcap_read(FILE *file, struct ofpbuf **bufp)
     if (fread(data, len, 1, file) != 1) {
         int error = ferror(file) ? errno : EOF;
         VLOG_WARN("failed to read pcap packet: %s",
-                  error > 0 ? strerror(error) : "end of file");
+                  ovs_retval_to_string(error));
         ofpbuf_delete(buf);
         return error;
     }
index d6e470c92f55f5f041db20bf9ffd84ff46d1e275..193efb9237c26fee14f85ee20ba0f08af3e6ef31 100644 (file)
@@ -158,8 +158,7 @@ ovs_fatal(int err_no, const char *format, ...)
     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);
@@ -176,14 +175,40 @@ ovs_error(int err_no, const char *format, ...)
     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)
index 49790490614b3d773d014d36abac69fc0da68bbe..f3bf80c6eaeddc760344b743bb30785d2258b985 100644 (file)
@@ -137,6 +137,7 @@ void ovs_strlcpy(char *dst, const char *src, size_t size);
 void ovs_fatal(int err_no, const char *format, ...)
     PRINTF_FORMAT(2, 3) NO_RETURN;
 void ovs_error(int err_no, const char *format, ...) PRINTF_FORMAT(2, 3);
+const char *ovs_retval_to_string(int);
 void ovs_hex_dump(FILE *, const void *, size_t, uintptr_t offset, bool ascii);
 
 bool str_to_int(const char *, int base, int *);
index 67ce714d08509daf15d43bc2173050a9f6f43a39..c980f693124213dd12ae7f1cf16e4ecdbfa4d6e5 100644 (file)
@@ -1363,13 +1363,10 @@ ofproto_get_ofproto_controller_info(const struct ofproto * ofproto,
 
         cinfo->pairs.n = 0;
 
-        if (last_error == EOF) {
-            cinfo->pairs.keys[cinfo->pairs.n] = "last_error";
-            cinfo->pairs.values[cinfo->pairs.n++] = xstrdup("End of file");
-        } else if (last_error > 0) {
+        if (last_error) {
             cinfo->pairs.keys[cinfo->pairs.n] = "last_error";
             cinfo->pairs.values[cinfo->pairs.n++] =
-                xstrdup(strerror(last_error));
+                xstrdup(ovs_retval_to_string(last_error));
         }
 
         cinfo->pairs.keys[cinfo->pairs.n] = "state";