試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

Vala言語でUNIXドメインソケットを用いてcpufreqdのデーモンと通信するテスト(メモ)

以前cpufreqdのプロファイル手動切り替え/モード切り替えツールcpufreqd-icon(http://kakurasan.ehoh.net/software/cpufreqd-icon/)を作成したとき(関連記事)には事情によりC言語を用いたのだが、元々はVala言語で作成する予定で、cpufreqdのデーモンとのUNIXドメインソケットによる通信を行う関数が言語バインディングから利用できないのが理由でC言語に切り替えていた。
しかし、GLibライブラリに含まれるGIOというライブラリがその後のバージョンでUNIXドメインを含むソケットの処理をサポートするようになり、Vala言語でも(GLibとGIO以外のライブラリを用いずに)UNIXドメインソケットによりcpufreqdとの通信ができるようになったため、ここではC言語の標準ライブラリで作成していたときの処理と比較しながらそのメモを貼り付ける。なお、Vala言語からはC言語のGIOの機能をそのまま用いているだけなので、直接C言語でGIOライブラリを用いて処理を行うことも可能(書き方は変わる)だが、ここでは扱わない。

必要なバージョン

GLib,GIOのバージョン2.22系以上が必要となる。

メモ

ソケットはGLib.Socketオブジェクトで扱う。引数も同様に指定できる。

(C言語/標準ライブラリ)
int sock = socket (PF_UNIX, SOCK_STREAM, 0);

(Vala言語/GIO)
GLib.Socket sock = new GLib.Socket (GLib.SocketFamily.UNIX,
                                    GLib.SocketType.STREAM,
                                    GLib.SocketProtocol.DEFAULT);

C言語の標準ライブラリではsockaddr_un構造体のメンバsun_familyにAF_UNIXを指定し、メンバaddr.sun_path(char配列)にはソケットのパス名を入れた上でconnect()を呼ぶが、Vala言語ではGLib.Socketオブジェクトのメンバ関数connect()にGLib.UnixSocketAddressオブジェクトを指定し、この引数としてソケットのパス名を指定する。

(C言語/標準ライブラリ)
struct sockaddr_un addr;
addr.sun_family = AF_UNIX;
(別途char配列addr.sun_pathにソケットのパス名を入れておく)
connect (sock, (struct sockaddr *) &addr, sizeof(addr))

(Vala言語/GIO)
sock.connect (new GLib.UnixSocketAddress ([ソケットのパス名]), null);

この後はGLib.Socketオブジェクト(例ではsock)のメンバ(プロパティ)fdとしてファイル記述子にアクセスし、IOチャンネル(GLib.IOChannelオブジェクト)*1Posix.read()/Posix.write()でファイル記述子を指定してやりとりを行うことになる。
cpufreqdに対する通信ではcpufreqdのソースのsrc/cpufreqd.hに書かれている内容に従って(「プロファイル一覧の問い合わせ」などの)コマンドを生成してPosix.write()で送信し、返す出力はIOチャンネルで処理することになる。

(「Vala言語でUNIXドメインソケットを用いてcpufreqdのデーモンと通信するテスト(コード例)」に続く)

関連記事:

使用したバージョン:

  • Vala 0.7.9
  • GLib, GIO 2.22.2

関連URL:

*1:GLib.IOChannel.unix_new()のコンストラクタでファイル記述子を引数にして生成