]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: init: allow the redefinition of argv[] parsing function
authorFrederic Lecaille <flecaille@haproxy.com>
Wed, 11 Feb 2026 10:16:39 +0000 (11:16 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 19 Feb 2026 13:46:49 +0000 (14:46 +0100)
This patches allows the argv[] parsing function to be redefined from
others C modules. This is done extracting the function which really
parse the argv[] array to implement haproxy_init_args(). This function
is declared as a weak symbol which may be overloaded by others C module.

Same thing for copy_argv() which checks/cleanup/modifies the argv array.
One may want this function to be redefined. This is the case when other
C modules do not handle the same command line option. Copying such
argv[] would lead to conflicts with the original haproxy argv[] during
the copy.

src/haproxy.c

index c7e89ae1ead959db29fe7790b820b0363d7201b7..177df7bcbadbccbad4eef3c47c350cf340ab875b 100644 (file)
@@ -152,6 +152,8 @@ int daemon_fd[2] = {-1, -1};        /* pipe to communicate with parent process */
 int devnullfd = -1;
 int fileless_mode;
 struct cfgfile fileless_cfg;
+extern __attribute__((weak)) void haproxy_init_args(int argc, char **argv);
+extern __attribute__((weak)) char **copy_argv(int argc, char **argv);
 
 static int stopped_tgroups;
 static int stop_detected;
@@ -1174,7 +1176,7 @@ err:
  * Return an allocated copy of argv
  */
 
-static char **copy_argv(int argc, char **argv)
+char **copy_argv(int argc, char **argv)
 {
        char **newargv, **retargv;
 
@@ -1502,53 +1504,10 @@ static void init_early(int argc, char **argv)
        }
 }
 
-/* handles program arguments. Very minimal parsing is performed, variables are
- * fed with some values, and lists are completed with other ones. In case of
- * error, it will exit.
- */
-static void init_args(int argc, char **argv)
+void haproxy_init_args(int argc, char **argv)
 {
        char *err_msg = NULL;
 
-       /* pre-fill in the global tuning options before we let the cmdline
-        * change them.
-        */
-       global.tune.options |= GTUNE_USE_SELECT;  /* select() is always available */
-#if defined(USE_POLL)
-       global.tune.options |= GTUNE_USE_POLL;
-#endif
-#if defined(USE_EPOLL)
-       global.tune.options |= GTUNE_USE_EPOLL;
-#endif
-#if defined(USE_KQUEUE)
-       global.tune.options |= GTUNE_USE_KQUEUE;
-#endif
-#if defined(USE_EVPORTS)
-       global.tune.options |= GTUNE_USE_EVPORTS;
-#endif
-#if defined(USE_LINUX_SPLICE)
-       global.tune.options |= GTUNE_USE_SPLICE;
-#endif
-#if defined(USE_GETADDRINFO)
-       global.tune.options |= GTUNE_USE_GAI;
-#endif
-#ifdef USE_THREAD
-       global.tune.options |= GTUNE_IDLE_POOL_SHARED;
-#endif
-       global.tune.options |= GTUNE_STRICT_LIMITS;
-
-       global.tune.options |= GTUNE_USE_FAST_FWD; /* Use fast-forward by default */
-
-       /* Use zero-copy forwarding by default */
-       global.tune.no_zero_copy_fwd = 0;
-
-       /* keep a copy of original arguments for the master process */
-       old_argv = copy_argv(argc, argv);
-       if (!old_argv) {
-               ha_alert("failed to copy argv.\n");
-               exit(EXIT_FAILURE);
-       }
-
        /* skip program name and start */
        argc--; argv++;
        while (argc > 0) {
@@ -1852,6 +1811,54 @@ static void init_args(int argc, char **argv)
        free(err_msg);
 }
 
+/* handles program arguments. Very minimal parsing is performed, variables are
+ * fed with some values, and lists are completed with other ones. In case of
+ * error, it will exit.
+ */
+static void init_args(int argc, char **argv)
+{
+       /* pre-fill in the global tuning options before we let the cmdline
+        * change them.
+        */
+       global.tune.options |= GTUNE_USE_SELECT;  /* select() is always available */
+#if defined(USE_POLL)
+       global.tune.options |= GTUNE_USE_POLL;
+#endif
+#if defined(USE_EPOLL)
+       global.tune.options |= GTUNE_USE_EPOLL;
+#endif
+#if defined(USE_KQUEUE)
+       global.tune.options |= GTUNE_USE_KQUEUE;
+#endif
+#if defined(USE_EVPORTS)
+       global.tune.options |= GTUNE_USE_EVPORTS;
+#endif
+#if defined(USE_LINUX_SPLICE)
+       global.tune.options |= GTUNE_USE_SPLICE;
+#endif
+#if defined(USE_GETADDRINFO)
+       global.tune.options |= GTUNE_USE_GAI;
+#endif
+#ifdef USE_THREAD
+       global.tune.options |= GTUNE_IDLE_POOL_SHARED;
+#endif
+       global.tune.options |= GTUNE_STRICT_LIMITS;
+
+       global.tune.options |= GTUNE_USE_FAST_FWD; /* Use fast-forward by default */
+
+       /* Use zero-copy forwarding by default */
+       global.tune.no_zero_copy_fwd = 0;
+
+       /* keep a copy of original arguments for the master process */
+       old_argv = copy_argv(argc, argv);
+       if (!old_argv) {
+               ha_alert("failed to copy argv.\n");
+               exit(EXIT_FAILURE);
+       }
+
+       haproxy_init_args(argc, argv);
+}
+
 /* call the various keyword dump functions based on the comma-delimited list of
  * classes in kwd_dump.
  */