kkAyatakaのメモ帳。

誰かの役に立つかもしれない備忘録。

systemdのsd-loginでGUIセッション情報を取得する

loginctlで色々とセッション情報が取得できるのはわかったけど、じゃあプログラムから参照する方法はなんだと調べて行ったらsystemdのsd-loginに行き着いた。

  • systemd/sd-login.hAPIloginctlから得られる情報をAPI経由で取得できる
  • systemd-develのインストールとlibsystemdへのリンクが必要

ライセンスはLGPL v2.1。GitHubの表示がGPL 2.0になっているけどよくよく見ると初期のころ(?)にLGPLに変更されている。公式ページの方で確認できる。

loginctlのコマンドを触ってみた話はこちら。

環境

  • CentOS 7.6.1810
  • systemd 219 (loginctl —version)
  • gcc 4.8.5

準備とビルド

開発用パッケージが必要なのでインストールする。

$ 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);
    }
}

参考