systemdのsd-loginでGUIセッション情報を取得する
loginctl
で色々とセッション情報が取得できるのはわかったけど、じゃあプログラムから参照する方法はなんだと調べて行ったらsystemdのsd-loginに行き着いた。
ライセンスはLGPL v2.1。GitHubの表示がGPL 2.0になっているけどよくよく見ると初期のころ(?)にLGPLに変更されている。公式ページの方で確認できる。
環境
準備とビルド
開発用パッケージが必要なのでインストールする。
$ sudo yum install systemd-devel
ビルドするときはsystemdをリンクする。
$ g++ -Wall main.cpp -lsystemd
セッションのアクティブ状態を取得する
セッションIDが必要だけどgetsid
の値とは別物。sd-loginのAPIを使って、(ここでは)pidから取得している。
sd_session_is_active
の値をファイルに書き出しつつ、ユーザーを変更すると、得られる値が変化することが観察できる。
#include <systemd/sd-login.h> #include <sys/types.h> #include <unistd.h> #include <cstdlib> #include <iostream> int main() { const pid_t pid = getpid(); char *session = 0; const int err = sd_pid_get_session(pid, &session); if (err >= 0 && session) { std::cout << "session: " << session << ", is_active: " << sd_session_is_active(session) << std::endl; free(session); } }
ユーザーIDからセッションのStateを取得する
もう一つ。こちらはユーザーIDからStateの値を取得する。ログイン中でアクティブならactive、ログインしたままユーザーを変更するとonlineが返る。
こちらもStateの値をファイルに書き出しつつ、ユーザーを変更することで値の変化を観察できる。
#include <systemd/sd-login.h> #include <sys/types.h> #include <unistd.h> #include <cstdlib> #include <iostream> int main() { const uid_t uid = getuid(); char *state = 0; const int err = sd_uid_get_state(uid, &state); if (err >= 0 && state) { // forgraound user's state is "active" // background user's state is "online" std::cout << "uid: " << uid << ", state: " << state << std::endl; free(state); } }