]> git.ozlabs.org Git - ccan/commitdiff
err: actually implement replacement versions!
authorRusty Russell <rusty@rustcorp.com.au>
Fri, 8 Jun 2012 11:19:32 +0000 (20:49 +0930)
committerRusty Russell <rusty@rustcorp.com.au>
Fri, 8 Jun 2012 11:19:32 +0000 (20:49 +0930)
This is where you see the genius of the originals: you can't implement them
without horrible hacks to get the program name :(

ccan/err/_info
ccan/err/err.c [new file with mode: 0644]
ccan/err/err.h
ccan/err/test/run.c

index 5a5752bb0b297418486200661ec69db71d84dbdf..97bc0f9ed4ff03437804b2928326aa040d3e5665 100644 (file)
@@ -8,11 +8,15 @@
  * A few platforms don't provide err.h; for those, this provides replacements.
  * For most, it simple includes the system err.h.
  *
+ * Unfortunately, you have to call err_set_progname() to tell the replacements
+ * your program name, otherwise it prints "unknown program".
+ *
  * Example:
  *     #include <ccan/err/err.h>
  *
  *     int main(int argc, char *argv[])
  *     {
+ *             err_set_progname(argv[0]);
  *             if (argc != 1)
  *                     errx(1, "Expect no arguments");
  *             exit(0);
diff --git a/ccan/err/err.c b/ccan/err/err.c
new file mode 100644 (file)
index 0000000..9e0e20c
--- /dev/null
@@ -0,0 +1,64 @@
+#include "err.h"
+
+#if !HAVE_ERR_H
+#include <stdarg.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+static const char *progname = "unknown program";
+
+void err_set_progname(const char *name)
+{
+       progname = name;
+}
+
+void NORETURN err(int eval, const char *fmt, ...)
+{
+       int err_errno = errno;
+       va_list ap;
+
+       fprintf(stderr, "%s: ", progname);
+       va_start(ap, fmt);
+       vfprintf(stderr, fmt, ap);
+       va_end(ap);
+       fprintf(stderr, ": %s\n", strerror(err_errno));
+       exit(eval);
+}
+
+void NORETURN errx(int eval, const char *fmt, ...)
+{
+       va_list ap;
+
+       fprintf(stderr, "%s: ", progname);
+       va_start(ap, fmt);
+       vfprintf(stderr, fmt, ap);
+       va_end(ap);
+       fprintf(stderr, "\n");
+       exit(eval);
+}
+
+void warn(const char *fmt, ...)
+{
+       int err_errno = errno;
+       va_list ap;
+
+       fprintf(stderr, "%s: ", progname);
+       va_start(ap, fmt);
+       vfprintf(stderr, fmt, ap);
+       va_end(ap);
+       fprintf(stderr, ": %s\n", strerror(err_errno));
+}
+
+void warnx(const char *fmt, ...)
+{
+       va_list ap;
+
+       fprintf(stderr, "%s: ", progname);
+       va_start(ap, fmt);
+       vfprintf(stderr, fmt, ap);
+       va_end(ap);
+       fprintf(stderr, "\n");
+}
+#endif
index da9ea0c5bd165a97183f78bbebf965c813184df6..58ad91c728a65a36487bd4eda87d31dbf8c19957 100644 (file)
@@ -4,9 +4,27 @@
 
 #if HAVE_ERR_H
 #include <err.h>
+
+/* This is unnecessary with a real err.h.  See below */
+#define err_set_progname(name) ((void)name)
+
 #else
 #include <ccan/compiler/compiler.h>
 
+/**
+ * err_set_progname - set the program name
+ * @name: the name to use for err, errx, warn and warnx
+ *
+ * The BSD err.h calls know the program name, unfortunately there's no
+ * portable way for the CCAN replacements to do that on other systems.
+ *
+ * If you don't call this with argv[0], it will be "unknown program".
+ *
+ * Example:
+ *     err_set_progname(argv[0]);
+ */
+void err_set_progname(const char *name);
+
 /**
  * err - exit(eval) with message based on format and errno.
  * @eval: the exit code
index c0407a9322b1c3e8fe60a454a497d6dbe4deee41..242e93f8061c246e344a26079f0b0fd2808bb813 100644 (file)
@@ -1,4 +1,4 @@
-#include <ccan/err/err.h>
+#include <ccan/err/err.c>
 #include <ccan/tap/tap.h>
 #include <unistd.h>
 #include <string.h>
 
 #define BUFFER_MAX 1024
 
-int main(void)
+int main(int argc, char *argv[])
 {
        int pfd[2];
+       const char *base;
 
-       plan_tests(20);
-       fflush(stdout);
+       plan_tests(24);
+
+       err_set_progname(argv[0]);
+
+       /* In case it only prints out the basename of argv[0]. */
+       base = strrchr(argv[0], '/');
+       if (base)
+               base++;
+       else
+               base = argv[0];
 
        /* Test err() in child */
        pipe(pfd);
+       fflush(stdout);
        if (fork()) {
                char buffer[BUFFER_MAX+1];
                unsigned int i;
@@ -31,6 +41,7 @@ int main(void)
                                buffer[i] = '\0';
                                ok1(strstr(buffer, "running err:"));
                                ok1(strstr(buffer, strerror(ENOENT)));
+                               ok1(strstr(buffer, base));
                                ok1(buffer[i-1] == '\n');
                                break;
                        }
@@ -61,6 +72,7 @@ int main(void)
                        if (read(pfd[0], buffer + i, 1) == 0) {
                                buffer[i] = '\0';
                                ok1(strstr(buffer, "running errx\n"));
+                               ok1(strstr(buffer, base));
                                break;
                        }
                }
@@ -91,6 +103,7 @@ int main(void)
                                buffer[i] = '\0';
                                ok1(strstr(buffer, "running warn:"));
                                ok1(strstr(buffer, strerror(ENOENT)));
+                               ok1(strstr(buffer, base));
                                ok1(buffer[i-1] == '\n');
                                break;
                        }
@@ -121,6 +134,7 @@ int main(void)
                        if (read(pfd[0], buffer + i, 1) == 0) {
                                buffer[i] = '\0';
                                ok1(strstr(buffer, "running warnx\n"));
+                               ok1(strstr(buffer, base));
                                break;
                        }
                }