From a0ee703ee27b476c2bf4e02d6392c1f4d9c51764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B3th=20J=C3=A1nos?= Date: Wed, 13 Nov 2024 11:04:18 +0100 Subject: [PATCH] Implement `-U` for FreeBSD. Tested on FreeBSD 14.1. Takes part of #2072. --- doc/man.md.j2 | 2 +- src/conky.cc | 8 ++++---- src/freebsd.cc | 36 ++++++++++++++++++++++++++++++++++++ src/freebsd.h | 2 ++ src/main.cc | 12 ++++++------ 5 files changed, 49 insertions(+), 11 deletions(-) diff --git a/doc/man.md.j2 b/doc/man.md.j2 index d564e89b8..85d1eda48 100644 --- a/doc/man.md.j2 +++ b/doc/man.md.j2 @@ -163,7 +163,7 @@ file. **-U \| \--unique** : Conky won't start if another Conky process is already running. Implemented - only for Linux. + only for Linux and FreeBSD. **-v \| -V \| \--version** diff --git a/src/conky.cc b/src/conky.cc index 44399cc54..8e2f4c0d0 100644 --- a/src/conky.cc +++ b/src/conky.cc @@ -2107,9 +2107,9 @@ void set_current_config() { /* : means that character before that takes an argument */ const char *getopt_string = "vVqdDSs:t:u:i:hc:p:" -#if defined(__linux__) +#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) "U" -#endif +#endif /* Linux || FreeBSD */ #ifdef BUILD_X11 "x:y:w:a:X:m:f:" #ifdef OWN_WINDOW @@ -2140,9 +2140,9 @@ const struct option longopts[] = { #endif /* BUILD_X11 */ {"text", 1, nullptr, 't'}, {"interval", 1, nullptr, 'u'}, {"pause", 1, nullptr, 'p'}, -#if defined(__linux__) +#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) {"unique", 0, nullptr, 'U'}, -#endif /* Linux */ +#endif /* Linux || FreeBSD */ {nullptr, 0, nullptr, 0} }; diff --git a/src/freebsd.cc b/src/freebsd.cc index 0243c4624..f5913c55c 100644 --- a/src/freebsd.cc +++ b/src/freebsd.cc @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -778,3 +779,38 @@ void print_sysctlbyname(struct text_object *obj, char *p, snprintf(p, p_max_size, "%lu", (unsigned long)val[0]); } } + +/****************************************** + * Check if more than one conky process * + * is running * + ******************************************/ + +bool is_conky_already_running(void) { + kvm_t *kd; + struct kinfo_proc *kp; + char errbuf[_POSIX2_LINE_MAX]; + int entries = -1; + int instances = 0; + + kd = kvm_openfiles(NULL, _PATH_DEVNULL, NULL, O_RDONLY, errbuf); + if (kd == NULL) { + NORM_ERR("%s\n", errbuf); + return false; + } + + kp = kvm_getprocs(kd, KERN_PROC_ALL, 0, &entries); + if ((kp == NULL && errno != ESRCH) || (kp != NULL && entries < 0)) { + NORM_ERR("%s\n", kvm_geterr(kd)); + goto cleanup; + } + + for (int i = 0; i < entries && instances < 2; ++i) { + if (!strcmp("conky", kp[i].ki_comm)) { + ++instances; + } + } + +cleanup: + kvm_close(kd); + return instances > 1; +} diff --git a/src/freebsd.h b/src/freebsd.h index f2baf9785..d64cf569c 100644 --- a/src/freebsd.h +++ b/src/freebsd.h @@ -47,4 +47,6 @@ int get_entropy_avail(unsigned int *); int get_entropy_poolsize(unsigned int *); void print_sysctlbyname(struct text_object *, char *, unsigned int); +bool is_conky_already_running(void); + #endif /*FREEBSD_H_*/ diff --git a/src/main.cc b/src/main.cc index 327ef59fd..909d12cfc 100644 --- a/src/main.cc +++ b/src/main.cc @@ -273,9 +273,9 @@ static void print_help(const char *prog_name) { " (and quit)\n" " -p, --pause=SECS pause for SECS seconds at startup " "before doing anything\n" -#if defined(__linux__) +#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) " -U, --unique only one conky process can be created\n" -#endif /* Linux */ +#endif /* Linux || FreeBSD */ , prog_name); } @@ -358,22 +358,22 @@ int main(int argc, char **argv) { window.window = strtol(optarg, nullptr, 0); break; #endif /* BUILD_X11 */ -#if defined(__linux__) +#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) case 'U': unique_process = true; break; -#endif /* Linux */ +#endif /* Linux || FreeBSD */ case '?': return EXIT_FAILURE; } } -#if defined(__linux__) +#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) if (unique_process && is_conky_already_running()) { NORM_ERR("already running"); return 0; } -#endif /* Linux */ +#endif /* Linux || FreeBSD */ try { set_current_config();