Skip to content

Instantly share code, notes, and snippets.

@yrro
Last active February 5, 2024 09:39
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save yrro/18dc22513f1001d0ec8d to your computer and use it in GitHub Desktop.
Save yrro/18dc22513f1001d0ec8d to your computer and use it in GitHub Desktop.
The poor Java programmer's alternative to calling sd_notify
/*
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE
FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package systemd;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Paths;
import java.util.function.Supplier;
@lombok.extern.slf4j.Slf4j
public class SdDaemon {
public static void status(String status) {
notify("--status=" + status);
}
public static void ready() {
notify("--ready");
}
public static boolean booted() {
return Files.isDirectory(Paths.get("/run/systemd/system"), LinkOption.NOFOLLOW_LINKS);
}
private static void notify(String arg) {
if (!booted() || System.getenv("NOTIFY_SOCKET") == null)
return;
try {
Process p = new ProcessBuilder("systemd-notify", arg)
.redirectErrorStream(true)
.start();
if (ignoreInterruptedException(p::waitFor) == 0)
return;
log.error("Failed to notify systemd of/that {}; systemd-notify exited with status {}", arg, p.exitValue());
try (BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
r.lines().forEach(l -> log.error("systemd-notify: {}", l));
}
} catch (Exception e) {
log.warn("Failed to notify systemd of service readiness", e);
}
}
private interface ThrowingSupplier<T, E extends Throwable> {
T get() throws E;
}
private static <T> T ignoreInterruptedException(ThrowingSupplier<T, InterruptedException> r) {
Supplier<Object> s;
for (;;) {
try {
return r.get();
} catch (InterruptedException e) {
continue;
}
}
}
}
@nicobrevin
Copy link

Hiya @yrro - are you happy that this code is public domain and so I can copy pasta like a crazy guy?

@yrro
Copy link
Author

yrro commented Feb 5, 2024

I've just put a license statement at the top - enjoy!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment