[Babel-users] [PATCH 1/3] add error helper functions

Christof Schulze christof.schulze at gmx.net
Wed Dec 5 23:11:13 GMT 2018


So I have introduced a task queue that allows us to easily abstract and 
schedule tasks independently from the data structure where they are 
held. This is meant to simplify the code and build clearer modules to 
hopefully increase maintainability. This is a series of three patches:
* the first introducing some exit functions (mainly because the 
   taskqueue implementation I had lying around uses these)
* the second introduces the taskqueue itself
* the third adjusts the implementation of scheduling interfaces to use 
   the taskqueue. With the outlook of moving other checks onto the same 
   mechanism it may even make sense to implement post_or_reschedule_task() 
   I also think we should be able to get rid of periodic interface checks 
   altogether but that is another story.
   
So what are your thoughts?

Exiting with error is a common pattern. This introduces exit_error(), exit_bug() that
help exiting in a standardized and terse way
---
  babeld.c | 35 ++++++++++++-----------------------
  babeld.h |  2 +-
  error.h  | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3 files changed, 76 insertions(+), 24 deletions(-)
  create mode 100644 error.h

diff --git a/babeld.c b/babeld.c
index 37f9a76..08923f5 100644
--- a/babeld.c
+++ b/babeld.c
@@ -54,6 +54,7 @@ THE SOFTWARE.
  #include "local.h"
  #include "rule.h"
  #include "version.h"
+#include "error.h"
  
  struct timeval now;
  
@@ -291,17 +292,14 @@ main(int argc, char **argv)
              config_files = realloc(config_files,
                                     (num_config_files + 1) * sizeof(char*));
              if(config_files == NULL) {
-                fprintf(stderr, "Couldn't allocate config file.\n");
-                exit(1);
+                exit_error("Couldn't allocate config file.");
              }
              config_files[num_config_files++] = optarg;
              break;
          case 'C':
              rc = parse_config_from_string(optarg, strlen(optarg), NULL);
              if(rc != CONFIG_ACTION_DONE) {
-                fprintf(stderr,
-                        "Couldn't parse configuration from command line.\n");
-                exit(1);
+                exit_error("Couldn't parse configuration from command line.");
              }
              break;
          case 'D':
@@ -326,8 +324,7 @@ main(int argc, char **argv)
          if(access("/etc/babeld.conf", F_OK) >= 0) {
              config_files = malloc(sizeof(char*));
              if(config_files == NULL) {
-                fprintf(stderr, "Couldn't allocate config file.\n");
-                exit(1);
+                exit_error("Couldn't allocate config file.");
              }
              config_files[num_config_files++] = "/etc/babeld.conf";
          }
@@ -337,11 +334,9 @@ main(int argc, char **argv)
          int line;
          rc = parse_config_from_file(config_files[i], &line);
          if(rc < 0) {
-            fprintf(stderr,
-                    "Couldn't parse configuration from file %s "
-                    "(error at line %d).\n",
+            exit_error("Couldn't parse configuration from file %s "
+                    "(error at line %d).",
                      config_files[i], line);
-            exit(1);
          }
      }
  
@@ -367,20 +362,17 @@ main(int argc, char **argv)
  
      rc = reopen_logfile();
      if(rc < 0) {
-        perror("reopen_logfile()");
-        exit(1);
+        exit_error("reopen_logfile()");
      }
  
      fd = open("/dev/null", O_RDONLY);
      if(fd < 0) {
-        perror("open(null)");
-        exit(1);
+        exit_error("open(null)");
      }
  
      rc = dup2(fd, 0);
      if(rc < 0) {
-        perror("dup2(null, 0)");
-        exit(1);
+        exit_error("dup2(null, 0)");
      }
  
      close(fd);
@@ -388,8 +380,7 @@ main(int argc, char **argv)
      if(do_daemonise) {
          rc = daemonise();
          if(rc < 0) {
-            perror("daemonise");
-            exit(1);
+            exit_error("daemonise");
          }
      }
  
@@ -399,8 +390,7 @@ main(int argc, char **argv)
  
          len = snprintf(buf, 100, "%lu", (unsigned long)getpid());
          if(len < 0 || len >= 100) {
-            perror("snprintf(getpid)");
-            exit(1);
+            exit_error("snprintf(getpid)");
          }
  
          pfd = open(pidfile, O_WRONLY | O_CREAT | O_EXCL, 0644);
@@ -408,8 +398,7 @@ main(int argc, char **argv)
              char buf[40];
              snprintf(buf, 40, "creat(%s)", pidfile);
              buf[39] = '\0';
-            perror(buf);
-            exit(1);
+            exit_error(buf);
          }
  
          rc = write(pfd, buf, len);
diff --git a/babeld.h b/babeld.h
index e46dd79..53ae464 100644
--- a/babeld.h
+++ b/babeld.h
@@ -19,7 +19,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.
  */
-
+#pragma once
  #define INFINITY ((unsigned short)(~0))
  
  #ifndef RTPROT_BABEL
diff --git a/error.h b/error.h
new file mode 100644
index 0000000..490e8d0
--- /dev/null
+++ b/error.h
@@ -0,0 +1,63 @@
+/*
+  Copyright (c) 2015, Matthias Schiffer <mschiffer at universe-factory.net>
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice,
+       this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice,
+       this list of conditions and the following disclaimer in the documentation
+       and/or other materials provided with the distribution.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#pragma once
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define exit_errno(message) _exit_error(1, errno, "%s", message)
+
+static inline void _exit_error(int status, int errnum, const char *format,
+			       ...) {
+	va_list ap;
+	va_start(ap, format);
+	vfprintf(stderr, format, ap);
+	va_end(ap);
+
+	if (errnum)
+		fprintf(stderr, ": %s\n", strerror(errnum));
+	else
+		fprintf(stderr, "\n");
+	if (status == -1)
+		abort();
+	exit(status);
+}
+
+static inline void exit_error(const char *format, ...) {
+	va_list ap;
+	va_start(ap, format);
+	_exit_error(1, 0, format, ap);
+	va_end(ap);
+}
+
+static inline void exit_bug(const char *format, ...) {
+	va_list ap;
+	va_start(ap, format);
+	_exit_error(-1, 0, format, ap);
+	va_end(ap);
+}
-- 
2.11.0




More information about the Babel-users mailing list