diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2024-04-05 13:40:11 +0200 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2024-04-05 13:56:17 +0200 |
commit | 362dcfc5db0271cd6b3a564c528cabf0ac0e7993 (patch) | |
tree | f5fef0448085ee7ed0a18463bca28240e606be5a | |
parent | man: update fedora example to F40 (diff) | |
download | systemd-362dcfc5db0271cd6b3a564c528cabf0ac0e7993.tar.xz systemd-362dcfc5db0271cd6b3a564c528cabf0ac0e7993.zip |
sd-notify: fix unsetting of environment variable on error
The man page says that the variable will be unset even if the call fails.
But we weren't consistent: for some errors we would return early. This
is not good, because based on the man page, the caller may use just print
a warning, or even use '(void) sd_notify(…)' for the call.
-rw-r--r-- | src/libsystemd/sd-daemon/sd-daemon.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c index 0eb0797e08..2ff9537a6d 100644 --- a/src/libsystemd/sd-daemon/sd-daemon.c +++ b/src/libsystemd/sd-daemon/sd-daemon.c @@ -650,7 +650,7 @@ _public_ int sd_notify(int unset_environment, const char *state) { _public_ int sd_pid_notifyf(pid_t pid, int unset_environment, const char *format, ...) { _cleanup_free_ char *p = NULL; - int r; + int r = 0, k; if (format) { va_list ap; @@ -659,16 +659,20 @@ _public_ int sd_pid_notifyf(pid_t pid, int unset_environment, const char *format r = vasprintf(&p, format, ap); va_end(ap); - if (r < 0 || !p) - return -ENOMEM; + if (r < 0 || !p) { + r = -ENOMEM; + p = mfree(p); /* If vasprintf failed, do not use the string, + * even if something was returned. */ + } } - return sd_pid_notify(pid, unset_environment, p); + k = sd_pid_notify(pid, unset_environment, p); + return r < 0 ? r : k; } _public_ int sd_notifyf(int unset_environment, const char *format, ...) { _cleanup_free_ char *p = NULL; - int r; + int r = 0, k; if (format) { va_list ap; @@ -677,11 +681,15 @@ _public_ int sd_notifyf(int unset_environment, const char *format, ...) { r = vasprintf(&p, format, ap); va_end(ap); - if (r < 0 || !p) - return -ENOMEM; + if (r < 0 || !p) { + r = -ENOMEM; + p = mfree(p); /* If vasprintf failed, do not use the string, + * even if something was returned. */ + } } - return sd_pid_notify(0, unset_environment, p); + k = sd_pid_notify(0, unset_environment, p); + return r < 0 ? r : k; } _public_ int sd_pid_notifyf_with_fds( @@ -691,27 +699,31 @@ _public_ int sd_pid_notifyf_with_fds( const char *format, ...) { _cleanup_free_ char *p = NULL; - int r; + int r = 0, k; /* Paranoia check: we traditionally used 'unsigned' as array size, but we nowadays more correctly use * 'size_t'. sd_pid_notifyf_with_fds() and sd_pid_notify_with_fds() are from different eras, hence * differ in this. Let's catch resulting incompatibilites early, even though they are pretty much * theoretic only */ if (n_fds > UINT_MAX) - return -E2BIG; + r = -E2BIG; - if (format) { + else if (format) { va_list ap; va_start(ap, format); r = vasprintf(&p, format, ap); va_end(ap); - if (r < 0 || !p) - return -ENOMEM; + if (r < 0 || !p) { + r = -ENOMEM; + p = mfree(p); /* If vasprintf failed, do not use the string, + * even if something was returned. */ + } } - return sd_pid_notify_with_fds(pid, unset_environment, p, fds, n_fds); + k = sd_pid_notify_with_fds(pid, unset_environment, p, fds, n_fds); + return r < 0 ? r : k; } _public_ int sd_booted(void) { |