[PATCH 2/2] dhcpcd: Add hooks

Sebastian Huber sebastian.huber at embedded-brains.de
Wed May 2 07:47:16 UTC 2018


---
 dhcpcd/dhcpcd.c                 |  9 +++++++
 dhcpcd/namespace.h              |  1 +
 dhcpcd/script.c                 | 54 +++++++++++++++++++++++++++++++++++++++++
 dhcpcd/script.h                 |  6 +----
 libbsd.py                       |  1 +
 rtemsbsd/include/rtems/dhcpcd.h | 22 +++++++++++++++++
 testsuite/dhcpcd01/test_main.c  | 21 +++++++++++++++-
 7 files changed, 108 insertions(+), 6 deletions(-)

diff --git a/dhcpcd/dhcpcd.c b/dhcpcd/dhcpcd.c
index 7cdd3c066..a37ebf8e8 100644
--- a/dhcpcd/dhcpcd.c
+++ b/dhcpcd/dhcpcd.c
@@ -1581,3 +1581,12 @@ main(int argc, char **argv)
 	eloop_start(&dhcpcd_sigset);
 	exit(EXIT_SUCCESS);
 }
+#ifdef __rtems__
+int
+dhcpcd_script_runreason_do_nothing(const struct interface *ifp,
+    const char *reason)
+{
+	return 0;
+}
+__weak_reference(dhcpcd_script_runreason_do_nothing, script_runreason);
+#endif /* __rtems__ */
diff --git a/dhcpcd/namespace.h b/dhcpcd/namespace.h
index efff909ad..c9f5fb1fa 100644
--- a/dhcpcd/namespace.h
+++ b/dhcpcd/namespace.h
@@ -156,6 +156,7 @@ extern rtems_recursive_mutex dhcpcd_mutex;
 #define print_string dhcpcd_print_string
 #define read_config dhcpcd_read_config
 #define read_lease dhcpcd_read_lease
+#define script_runreason dhcpcd_script_runreason
 #define select_profile dhcpcd_select_profile
 #define set_cloexec dhcpcd_set_cloexec
 #define set_nonblock dhcpcd_set_nonblock
diff --git a/dhcpcd/script.c b/dhcpcd/script.c
index 2de1e6347..1005d1740 100644
--- a/dhcpcd/script.c
+++ b/dhcpcd/script.c
@@ -51,7 +51,30 @@
 #include "ipv6nd.h"
 #include "net.h"
 #include "script.h"
+#ifdef __rtems__
+#include <rtems/dhcpcd.h>
 
+static SLIST_HEAD(, rtems_dhcpcd_hook) dhcpcd_hooks =
+  SLIST_HEAD_INITIALIZER(dhcpcd_hooks);
+
+void
+rtems_dhcpcd_add_hook(rtems_dhcpcd_hook *hook)
+{
+	rtems_recursive_mutex_lock(&dhcpcd_mutex);
+	SLIST_INSERT_HEAD(&dhcpcd_hooks, hook, node);
+	rtems_recursive_mutex_unlock(&dhcpcd_mutex);
+}
+
+void
+rtems_dhcpcd_remove_hook(rtems_dhcpcd_hook *hook)
+{
+	rtems_recursive_mutex_lock(&dhcpcd_mutex);
+	SLIST_REMOVE(&dhcpcd_hooks, hook, rtems_dhcpcd_hook, node);
+	rtems_recursive_mutex_unlock(&dhcpcd_mutex);
+}
+#endif /* __rtems__ */
+
+#ifndef __rtems__
 #define DEFAULT_PATH	"PATH=/usr/bin:/usr/sbin:/bin:/sbin"
 
 static const char * const if_params[] = {
@@ -75,10 +98,12 @@ if_printoptions(void)
 	for (p = if_params; *p; p++)
 		printf(" -  %s\n", *p);
 }
+#endif /* __rtems__ */
 
 static int
 exec_script(char *const *argv, char *const *env)
 {
+#ifndef __rtems__
 	pid_t pid;
 	posix_spawnattr_t attr;
 	short flags;
@@ -103,6 +128,20 @@ exec_script(char *const *argv, char *const *env)
 		return -1;
 	}
 	return pid;
+#else /* __rtems__ */
+	rtems_dhcpcd_hook *hook;
+	rtems_dhcpcd_hook *hook2;
+
+	rtems_recursive_mutex_lock(&dhcpcd_mutex);
+
+	SLIST_FOREACH_SAFE(hook, &dhcpcd_hooks, node, hook2) {
+		(*hook->handler)(env);
+	}
+
+	rtems_recursive_mutex_unlock(&dhcpcd_mutex);
+
+	return 0;
+#endif /* __rtems__ */
 }
 
 #ifdef INET
@@ -168,6 +207,7 @@ append_config(char ***env, ssize_t *len,
 }
 #endif
 
+#ifndef __rtems__
 static size_t
 arraytostr(const char *const *argv, char **s)
 {
@@ -191,6 +231,7 @@ arraytostr(const char *const *argv, char **s)
 	}
 	return len;
 }
+#endif /* __rtems__ */
 
 static ssize_t
 make_env(const struct interface *ifp, const char *reason, char ***argv)
@@ -435,6 +476,7 @@ eexit:
 	return -1;
 }
 
+#ifndef __rtems__
 static int
 send_interface1(int fd, const struct interface *iface, const char *reason)
 {
@@ -507,18 +549,23 @@ send_interface(int fd, const struct interface *iface)
 	}
 	return retval;
 }
+#endif /* __rtems__ */
 
 int
 script_runreason(const struct interface *ifp, const char *reason)
 {
 	char *const argv[2] = { UNCONST(ifp->options->script), NULL };
 	char **env = NULL, **ep;
+#ifndef __rtems__
 	char *path, *bigenv;
+#endif /* __rtems__ */
 	ssize_t e, elen = 0;
 	pid_t pid;
 	int status = 0;
+#ifndef __rtems__
 	const struct fd_list *fd;
 	struct iovec iov[2];
+#endif /* __rtems__ */
 
 	if (ifp->options->script == NULL ||
 	    ifp->options->script[0] == '\0' ||
@@ -530,6 +577,7 @@ script_runreason(const struct interface *ifp, const char *reason)
 
 	/* Make our env */
 	elen = make_env(ifp, reason, &env);
+#ifndef __rtems__
 	ep = realloc(env, sizeof(char *) * (elen + 2));
 	if (ep == NULL) {
 		elen = -1;
@@ -554,8 +602,10 @@ script_runreason(const struct interface *ifp, const char *reason)
 		}
 	}
 	env[++elen] = NULL;
+#endif /* __rtems__ */
 
 	pid = exec_script(argv, env);
+#ifndef __rtems__
 	if (pid == -1)
 		syslog(LOG_ERR, "%s: %s: %m", __func__, argv[0]);
 	else if (pid != 0) {
@@ -596,6 +646,10 @@ script_runreason(const struct interface *ifp, const char *reason)
 	free(bigenv);
 
 out:
+#else /* __rtems__ */
+	(void)e;
+	(void)pid;
+#endif /* __rtems__ */
 	/* Cleanup */
 	ep = env;
 	while (*ep)
diff --git a/dhcpcd/script.h b/dhcpcd/script.h
index dfd4a1726..9c5fd4d4e 100644
--- a/dhcpcd/script.h
+++ b/dhcpcd/script.h
@@ -33,16 +33,12 @@
 void if_printoptions(void);
 #ifndef __rtems__
 int send_interface(int, const struct interface *);
-int script_runreason(const struct interface *, const char *);
 #else /* __rtems__ */
 static inline int send_interface(int fd, const struct interface *iface)
 {
 	return 0;
 }
-static inline int script_runreason(const struct interface *ifp, const char *reason)
-{
-	return 0;
-}
 #endif /* __rtems__ */
+int script_runreason(const struct interface *, const char *);
 
 #endif
diff --git a/libbsd.py b/libbsd.py
index 586703fdd..41bc42a76 100644
--- a/libbsd.py
+++ b/libbsd.py
@@ -4555,6 +4555,7 @@ class dhcpcd(builder.Module):
                 'dhcpcd/ipv6nd.c',
                 'dhcpcd/net.c',
                 'dhcpcd/platform-bsd.c',
+                'dhcpcd/script.c',
                 'dhcpcd/compat/pselect.c',
                 'dhcpcd/crypt/hmac_md5.c',
             ],
diff --git a/rtemsbsd/include/rtems/dhcpcd.h b/rtemsbsd/include/rtems/dhcpcd.h
index 6bc5e023d..7ab4638a2 100644
--- a/rtemsbsd/include/rtems/dhcpcd.h
+++ b/rtemsbsd/include/rtems/dhcpcd.h
@@ -40,6 +40,9 @@
 #ifndef _RTEMS_DHCPCD_H_
 #define _RTEMS_DHCPCD_H_
 
+#include <sys/cdefs.h>
+#include <sys/queue.h>
+
 #include <rtems.h>
 
 #ifdef __cplusplus
@@ -57,6 +60,25 @@ extern "C" {
  */
 rtems_status_code rtems_dhcpcd_start(rtems_task_priority priority);
 
+typedef struct rtems_dhcpcd_hook {
+	void (*handler)(char *const *env);
+	SLIST_ENTRY(rtems_dhcpcd_hook) node;
+} rtems_dhcpcd_hook;
+
+/**
+ * @brief Adds a DHCP client hook.
+ *
+ * The hook handler is invoked with an environment list (NULL terminated) of
+ * strings ('\0' terminated).  Each string of the environment list has usually
+ * the format "key=value", e.g. "interface=eth0", "reason=BOUND".
+ */
+void rtems_dhcpcd_add_hook(rtems_dhcpcd_hook *hook);
+
+/**
+ * @brief Removes a DHCP client hook.
+ */
+void rtems_dhcpcd_remove_hook(rtems_dhcpcd_hook *hook);
+
 /** @} */
 
 #ifdef __cplusplus
diff --git a/testsuite/dhcpcd01/test_main.c b/testsuite/dhcpcd01/test_main.c
index 181f92ae1..5d8facc28 100644
--- a/testsuite/dhcpcd01/test_main.c
+++ b/testsuite/dhcpcd01/test_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2013, 2018 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -30,14 +30,33 @@
  */
 
 #include <assert.h>
+#include <stdio.h>
 
 #include <rtems.h>
+#include <rtems/dhcpcd.h>
 
 #define TEST_NAME "LIBBSD DHCPCD 1"
 
 static void
+dhcpcd_hook_handler(char *const *env)
+{
+
+	while (*env != NULL) {
+		printf("%s\n", *env);
+		++env;
+	}
+}
+
+static rtems_dhcpcd_hook dhcpcd_hook = {
+	.handler = dhcpcd_hook_handler
+};
+
+static void
 test_main(void)
 {
+
+	rtems_dhcpcd_add_hook(&dhcpcd_hook);
+
 	rtems_task_delete(RTEMS_SELF);
 	assert(0);
 }
-- 
2.12.3




More information about the devel mailing list