]> diplodocus.org Git - nmh/blobdiff - sbr/error.c
Escape literal leading full stop in man/new.man.
[nmh] / sbr / error.c
index c9fc9d8788f25fcc3e53f30614512af0a9ca9678..b33eae54415ed2ee6e68754305f2f49f11cb9fbc 100644 (file)
@@ -29,9 +29,9 @@ advise (const char *what, const char *fmt, ...)
 /* adios calls advertise() with no tail to print fmt, and perhaps what,
  * to stderr, and "ends" the program with an error exit status.  The
  * route to exit is via the done function pointer and may not be
- * straightforward.
- * FIXME: Document if this function can ever return.  If not, perhaps an
- * abort(3) at the end of the routine would make that more clear. */
+ * straightforward, e.g. longjmp(3), but it must not return to adios().
+ * If it does then it's a bug and adios() will abort(3) as callers do
+ * not expect execution to continue. */
 void
 adios (const char *what, const char *fmt, ...)
 {
@@ -41,6 +41,7 @@ adios (const char *what, const char *fmt, ...)
     advertise (what, NULL, fmt, ap);
     va_end(ap);
     done (1);
+    abort();
 }
 
 
@@ -69,50 +70,56 @@ void
 advertise (const char *what, char *tail, const char *fmt, va_list ap)
 {
     int        eindex = errno;
-    char buffer[BUFSIZ], err[BUFSIZ];
-    struct iovec iob[20], *iov;
+    char buffer[NMH_BUFSIZ], errbuf[NMH_BUFSIZ], *err;
+    struct iovec iob[10], *iov;
+    size_t niov;
 
-    fflush (stdout);
-
-    fflush (stderr);
     iov = iob;
 
+#define APPEND_IOV(p, len) \
+    iov->iov_base = (p); \
+    iov->iov_len = (len); \
+    iov++
+
+#define ADD_LITERAL(s) APPEND_IOV((s), LEN(s))
+#define ADD_VAR(s) APPEND_IOV((s), strlen(s))
+
     if (invo_name && *invo_name) {
-       iov->iov_len = strlen (iov->iov_base = invo_name);
-       iov++;
-       iov->iov_len = strlen (iov->iov_base = ": ");
-       iov++;
+        ADD_VAR(invo_name);
+       ADD_LITERAL(": ");
     }
     
     vsnprintf (buffer, sizeof(buffer), fmt, ap);
-    iov->iov_len = strlen (iov->iov_base = buffer);
-    iov++;
+    ADD_VAR(buffer);
     if (what) {
        if (*what) {
-           iov->iov_len = strlen (iov->iov_base = " ");
-           iov++;
-           iov->iov_len = strlen (iov->iov_base = (void*)what);
-           iov++;
-           iov->iov_len = strlen (iov->iov_base = ": ");
-           iov++;
+            ADD_LITERAL(" ");
+            ADD_VAR((void *)what);
+            ADD_LITERAL(": ");
        }
-        if (!(iov->iov_base = strerror (eindex))) {
+        err = strerror(eindex);
+        if (!err) {
            /* this shouldn't happen, but we'll test for it just in case */
-           snprintf (err, sizeof(err), "Error %d", eindex);
-           iov->iov_base = err;
+           snprintf(errbuf, sizeof(errbuf), "Error %d", eindex);
+            err = errbuf;
        }
-       iov->iov_len = strlen (iov->iov_base);
-       iov++;
+        ADD_VAR(err);
     }
     if (tail && *tail) {
-       iov->iov_len = strlen (iov->iov_base = ", ");
-       iov++;
-       iov->iov_len = strlen (iov->iov_base = tail);
-       iov++;
+        ADD_LITERAL(", ");
+        ADD_VAR(tail);
     }
-    iov->iov_len = strlen (iov->iov_base = "\n");
-    iov++;
-    if (writev (fileno (stderr), iob, iov - iob) < 0) {
+    ADD_LITERAL("\n");
+
+#undef ADD_LITERAL
+#undef ADD_VAR
+
+    niov = iov - iob;
+    assert(niov <= DIM(iob));
+
+    fflush (stdout);
+    fflush (stderr);
+    if (writev(fileno(stderr), iob, niov) == -1) {
         snprintf(buffer, sizeof buffer, "%s: write stderr failed: %d\n",
             invo_name && *invo_name ? invo_name : "nmh", errno);
         if (write(2, buffer, strlen(buffer)) == -1) {