Linuxでは、uinputデバイスが作成されると、そのデバイスに対応する1つ以上のイベントファイルがファイルシステムに作成されます。(たとえば、uinputマウスを作成すると、ファイル/ dev / input / mouseNが作成されます。)しかし、特定のuinputデバイス用に作成されたファイルを特定するにはどうすればよいですか?uinputカーネルモジュールは、その情報を取得するためのioctlを提供していないようです。考えられるアプローチの1つは、uinputデバイスを作成した直後にファイルシステムをポーリングして、どのファイルが表示されるかを確認することですが、実際のデバイスとuinputの両方が同時に接続または作成される他のデバイスと競合するため、このアプローチは機能しません。 。私は何かを見落としていますか、それともこの情報を取得するためにカーネルをハックする必要がありますか?
2 に答える
sysfsを調べると、自分の情報を見つけることができます。uinputデバイスを作成したら、次のようにします。
$ ls /sys/class/input/
event0 event1 ... eventN
input0 input2 ... input19 ... inputN
mouse0 mouse1 ... mouseN
mice
$ ls /sys/devices/virtual/input/
input19 mice
別のパスで仮想デバイスを見つけることができることに注意してください。この場合、input19は私のuinputデバイスです。対応するcharデバイスはどれですか?
$ ls /sys/devices/virtual/input/input19/
event14 name id ...
私のcharデバイスは/dev/input/event14
です。私input19
はuinputデバイスを作成している唯一のユーザーなので、それが私のuinputデバイスであることを知っています。確認したい場合は、そのsysfs属性名を読み取り、それが本当にデバイスであることを確認する必要があります
$ cat /sys/devices/virtual/input/input19/name
foo-keyboard-201303261446
カーネルメッセージを読むことで、新しいuinputデバイスに関する情報を取得できます。
$ dmesg | tail -n 7
input: foo-keyboard-201303261445 as /devices/virtual/input/input14
input: foo-keyboard-201303261445 as /devices/virtual/input/input15
input: foo-keyboard-201303261445 as /devices/virtual/input/input16
input: foo-keyboard-201303261445 as /devices/virtual/input/input17
input: foo-keyboard-201303261446 as /devices/virtual/input/input18
input: foo-keyboard-201303261446 as /devices/virtual/input/input19
input: foo-keyboard-201303261446 as /devices/virtual/input/input20
あなたのプログラムからあなたは/dev/kmsg
あなたのイベントを読んでキャッチすることができます。たぶん、あなたはデバイスを開いて、/dev/kmsg
それをフラッシュして、select()
uinput通知を受け取るまで待つことができます。
別の方法は、libudevを使用してuinputデバイスを取得することです。次のリンクを見てください:libudevチュートリアル
更新:あなたの質問のおかげで、私はgithubで利用可能なlibuinputライブラリを改善しました:Federicoによるlibuinput。htekmsgデバイスを使用するソリューションを実装しました。
更新:2014年にLinuxuinput
ドライバーが改善されました(git SHA1 e3480a61fc)。次のコマンドuinput
を使用して、sysfsパスをドライバーから直接取得できるようになりました。ioctl
/**
* UI_GET_SYSNAME - get the sysfs name of the created uinput device
*
* @return the sysfs name of the created virtual input device.
* The complete sysfs path is then /sys/devices/virtual/input/--NAME--
* Usually, it is in the form "inputN"
*/
#define UI_GET_SYSNAME(len) _IOC(_IOC_READ, UINPUT_IOCTL_BASE, 300, len)
したがって、3.13よりも新しいLinuxカーネルを使用する可能性がある場合は、上記を使用して、ioctl
uinputを使用するコードを改善できます。
これは私がこれまでに見つけた最良の方法であり、ここで与えられた答えと組み合わせると、次のようになります。
char sysfs_device_name[16];
ioctl(uinput_fd_after_create, UI_GET_SYSNAME(sizeof(sysfs_device_name)), sysfs_device_name);
printf("/sys/devices/virtual/input/%s\n", sysfs_device_name);
//Now retrieve all files in that folder and grep for event* then
send_input_to_fd = open("the_event[n]", O_WRONLY | O_NDELAY);
これで、send_input_to_fdがイベントの送信先となる正しいFDになります。