Golang での IOCTL 実装
ユーザー空間コードを C から Golang に移植する場合、IOCTL の処理が課題となることがあります。この記事では、次の C コードを変換しようとしたときに発生した特定の問題について説明します:
#define MAJOR_NUM 100 #define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) static int mbox_property(int file_desc, void *buf) { return ioctl(file_desc, IOCTL_MBOX_PROPERTY, buf); }
Golang の同等コード:
func mBoxProperty(f *os.File, buf [256]int64) { err := Ioctl(f.Fd(), IOWR(100, 0, 8), uintptr(unsafe.Pointer(&buf[0]))) } func Ioctl(fd, op, arg uintptr) error { _, _, ep := syscall.Syscall(syscall.SYS_IOCTL, fd, op, arg) if ep != 0 { return syscall.Errno(ep) } return nil } func IOWR(t, nr, size uintptr) uintptr { return IOC(IocRead|IocWrite, t, nr, size) } func IOC(dir, t, nr, size uintptr) uintptr { return (dir << IocDirshift) | (t << IocTypeshift) | (nr << IocNrshift) | (size << IocSizeshift) }
このコードを実行すると、「無効な引数」エラーが発生します。問題は、IOCTL() の呼び出し方法にあります。
ラッパー ソリューション
「golang.org/x/sys/unix」パッケージは、ioctl(2) を提供します。 ) ラッパー。この特定のケースでは、unix.IoctlSetInt ラッパーを使用できます。
メモリに関する考慮事項
IoctlSetInt および他の IOCTL ラッパーが小さなメモリ バッファを渡すことに注意することが重要です。カーネルに。 Go のガベージ コレクターはこれを認識しないため、カーネルによって使用されている間にメモリが移動または割り当て解除される可能性があります。
これに対処するには、cgo 経由で C 拡張機能を使用して malloc でバッファを作成することを検討してください。これにより、バッファーが移動または解放されなくなり、潜在的なメモリの問題が回避されます。
以上がGolang で IOCTL を実装し、「引数が無効です」エラーを回避するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。