1

私の知る限り、ioctl 番号はドライバーによって適切に定義され、カーネルに登録されています。

ジョイスティックの状態を照会するために、Python でいくつかのコードをいじっていました。ジョイスティック api に関するこのドキュメント、ioctl 番号に関するこのドキュメント、および python fcntl モジュールからのこのドキュメント読みました。

値をテストおよびクエリするための C プログラムを作成しました。Python は、 C マクロを実装するためにここから取得したコードを使用してテストします。_IOR()

カーネル ドライバーの定義:

monolith@monolith ~/temp $ grep JSIOCGAXES /usr/include/* -r
/usr/include/linux/joystick.h:#define JSIOCGAXES        _IOR('j', 0x11, __u8)

Cプログラム

#include <stdio.h>
#include <linux/joystick.h>
#include <fcntl.h>

int main() {  
  int fd = open("/dev/input/js0", O_RDONLY);
  printf("Ioctl Number: (int)%d  (hex)%x\n", JSIOCGAXES, JSIOCGAXES);
  char number;
  ioctl(fd, JSIOCGAXES, &number);
  printf("Number of axes: %d\n", number);
  close(fd);
  return 0;
}

C プログラムの出力:

monolith@monolith ~/temp $ ./test 
Ioctl Number: (int)-2147390959  (hex)80016a11
Number of axes: 6

Python 出力

# check if _IOR results in the used ioctl number in C
>>> _IOR(ord('j'), 0x11, 'c')
-2147390959
>>> file = open("/dev/input/js0")
# use that integer
>>> fcntl.ioctl(file, -2147390959)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 14] Bad address
# ask what hex value is
>>> "%x" % -2147390959
'-7ffe95ef'
# WHY THIS HEX CONVERSION DIFFERS?
>>> fcntl.ioctl(file, -0x7ffe95ef)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 14] Bad address
# Use the hex value from the C program output
>>> fcntl.ioctl(file, 0x80016a11)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 14] Bad address

その ioctl 番号でファイル記述子を照会できない理由はありますか? ioctl()関数は、メソッドが実装されfcntl()たファイル記述子またはオブジェクトを取るためfileno()、オブジェクトからエラーを破棄しfileます。

数値変換と型に問題があるのか​​もしれませんが、わかりません...手がかりはありますか?

4

2 に答える 2

2

これはすべて、16進数の変換が異なることになります。16進数のCをプラグインすると、Pythonに異なる数値が表示されます。

>>> 0x80016a11
2147576337

PythonとCが異なる16進数を与える理由はわかりませんが、少なくとも部分的に符号に関連している可能性があり'%x'ます-Pythonは符号付き16進数値1を与え、printfsは符号なし2を与えます。

Pythonの16進値(-7ffe95ef)を使用すると、状況が改善される可能性があります。または、Cで行うように変数を使用して、変換エラーを回避することもできます。

op = _IOR(ord('j'), 0x11, 'c')
...
fcntl.ioctl(file, op)
于 2012-07-14T09:43:16.127 に答える
2

私は自分の質問に答えるつもりです。

何らかの理由で、ioctl()Pythonからを使用して値を取得する唯一の方法は、次のコードを発行することでした。

>>> buf = array.array('h', [0])
>>> fcntl.ioctl(file.fileno(), 0x80016a11, buf)
0
>>> buf[0]
6

つまり、バッファを使用して結果を取得します。ドキュメントを読み直して、なぜ機能しfcntl.ioctl(file.fileno(), 0x80016a11)なかったのかを理解する必要があります。

于 2012-07-14T10:52:38.527 に答える