From ab47993a00e8854d64ae90de0cdd4b9272653473 Mon Sep 17 00:00:00 2001 From: Tom Jones Date: Wed, 24 Apr 2024 10:30:20 +0000 Subject: vppinfra: Add method for getting current executable name Add a unix method for getting the current executable name. This is implemented to match the readlink api for existing calls. Type: improvement Change-Id: Id06a55892d09d0b305a56b55a424f53ffb685a72 Signed-off-by: Tom Jones Signed-off-by: Damjan Marion --- src/plugins/fateshare/fateshare.c | 25 ++++++++++++++++--------- src/vlib/unix/main.c | 22 ++++++++++++---------- src/vpp/vnet/main.c | 26 ++++++++++++++++---------- src/vppinfra/unix-misc.c | 24 ++++++++++++++++++++++++ src/vppinfra/unix.h | 4 ++++ 5 files changed, 72 insertions(+), 29 deletions(-) diff --git a/src/plugins/fateshare/fateshare.c b/src/plugins/fateshare/fateshare.c index 33ee167bce3..37cd0300ab7 100644 --- a/src/plugins/fateshare/fateshare.c +++ b/src/plugins/fateshare/fateshare.c @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -197,24 +198,30 @@ fateshare_config (vlib_main_t *vm, unformat_input_t *input) if (fmp->monitor_cmd == 0) { - char *p, path[PATH_MAX]; - int rv; + char *p; + u8 *path; /* find executable path */ - if ((rv = readlink ("/proc/self/exe", path, PATH_MAX - 1)) == -1) + path = os_get_exec_path (); + + if (path == 0) return clib_error_return ( - 0, "could not stat /proc/self/exe - set monitor manually"); + 0, "could not get exec path - set monitor manually"); - /* readlink doesn't provide null termination */ - path[rv] = 0; + /* add null termination */ + vec_add1 (path, 0); /* strip filename */ - if ((p = strrchr (path, '/')) == 0) - return clib_error_return ( - 0, "could not determine vpp directory - set monitor manually"); + if ((p = strrchr ((char *) path, '/')) == 0) + { + vec_free (path); + return clib_error_return ( + 0, "could not determine vpp directory - set monitor manually"); + } *p = 0; fmp->monitor_cmd = format (0, "%s/vpp_fateshare_monitor\0", path); + vec_free (path); } if (fmp->monitor_logfile == 0) { diff --git a/src/vlib/unix/main.c b/src/vlib/unix/main.c index 38eef4125a9..ee28ca8f1aa 100644 --- a/src/vlib/unix/main.c +++ b/src/vlib/unix/main.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -612,22 +613,23 @@ vlib_unix_main (int argc, char *argv[]) vlib_main_t *vm = vlib_get_first_main (); /* one and only time for this! */ unformat_input_t input; clib_error_t *e; - char buffer[PATH_MAX]; int i; vec_validate_aligned (vgm->vlib_mains, 0, CLIB_CACHE_LINE_BYTES); - if ((i = readlink ("/proc/self/exe", buffer, sizeof (buffer) - 1)) > 0) + vgm->exec_path = (char *) os_get_exec_path (); + + if (vgm->exec_path) { - int j; - buffer[i] = 0; - vgm->exec_path = vec_new (char, i + 1); - clib_memcpy_fast (vgm->exec_path, buffer, i + 1); - for (j = i - 1; j > 0; j--) - if (buffer[j - 1] == '/') + for (i = vec_len (vgm->exec_path) - 1; i > 0; i--) + if (vgm->exec_path[i - 1] == '/') break; - vgm->name = vec_new (char, i - j + 1); - clib_memcpy_fast (vgm->name, buffer + j, i - j + 1); + + vgm->name = 0; + + vec_add (vgm->name, vgm->exec_path + i, vec_len (vgm->exec_path) - i); + vec_add1 (vgm->exec_path, 0); + vec_add1 (vgm->name, 0); } else vgm->exec_path = vgm->name = argv[0]; diff --git a/src/vpp/vnet/main.c b/src/vpp/vnet/main.c index 71434a9c065..c57efd59a62 100644 --- a/src/vpp/vnet/main.c +++ b/src/vpp/vnet/main.c @@ -22,6 +22,8 @@ #include #include +#include +#include #include #include #include @@ -43,25 +45,26 @@ static void vpp_find_plugin_path () { extern char *vat_plugin_path; - char *p, path[PATH_MAX]; - int rv; - u8 *s; + char *p; + u8 *s, *path; /* find executable path */ - if ((rv = readlink ("/proc/self/exe", path, PATH_MAX - 1)) == -1) + path = os_get_exec_path (); + + if (!path) return; - /* readlink doesn't provide null termination */ - path[rv] = 0; + /* add null termination */ + vec_add1 (path, 0); /* strip filename */ - if ((p = strrchr (path, '/')) == 0) - return; + if ((p = strrchr ((char *) path, '/')) == 0) + goto done; *p = 0; /* strip bin/ */ - if ((p = strrchr (path, '/')) == 0) - return; + if ((p = strrchr ((char *) path, '/')) == 0) + goto done; *p = 0; s = format (0, "%s/" CLIB_LIB_DIR "/vpp_plugins", path, path); @@ -71,6 +74,9 @@ vpp_find_plugin_path () s = format (0, "%s/" CLIB_LIB_DIR "/vpp_api_test_plugins", path, path); vec_add1 (s, 0); vat_plugin_path = (char *) s; + +done: + vec_free (path); } static void diff --git a/src/vppinfra/unix-misc.c b/src/vppinfra/unix-misc.c index 4dbc5ce98ce..29cbe0a557d 100644 --- a/src/vppinfra/unix-misc.c +++ b/src/vppinfra/unix-misc.c @@ -42,6 +42,8 @@ #include #ifdef __linux__ #include +#else +#include #endif #include @@ -358,6 +360,28 @@ os_get_cpu_phys_core_id (int cpu_id) #endif } +__clib_export u8 * +os_get_exec_path () +{ + u8 *rv = 0; +#ifdef __linux__ + char tmp[PATH_MAX]; + ssize_t sz = readlink ("/proc/self/exe", tmp, sizeof (tmp)); + + if (sz <= 0) + return 0; +#else + char tmp[MAXPATHLEN]; + int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; + size_t sz = MAXPATHLEN; + + if (sysctl (mib, 4, tmp, &sz, NULL, 0) == -1) + return 0; +#endif + vec_add (rv, tmp, sz); + return rv; +} + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vppinfra/unix.h b/src/vppinfra/unix.h index 3ad57b05e72..abda21879f9 100644 --- a/src/vppinfra/unix.h +++ b/src/vppinfra/unix.h @@ -71,6 +71,10 @@ clib_bitmap_t *os_get_cpu_on_node_bitmap (int node); /* Retrieve physical core id of specific cpu, -1 if not available */ int os_get_cpu_phys_core_id (int cpu); +/* Retrieve the path of the current executable as a vector (not + * null-terminated). */ +u8 *os_get_exec_path (); + #endif /* included_clib_unix_h */ /* -- cgit 1.2.3-korg