ioctl に構造体のポインタを渡して値を返してもらうような場合があると思います。
このような場合、文字列つくってそのまま渡せば struct のポインタになるようでした。
つまり pack/unpack("P") を使ってこう書くのは
Termios2::FORMAT = "I!I!I!I!CC19I!I!"
Termios2::FORMAT_POINTER = "P44"
# バッファ
v = tio.values.flatten.pack(Termios2::FORMAT)
# pack("P") でポインタを取得
pointer = [v].pack(Termios2::FORMAT_POINTER)
# ポインタを数値として渡す
self.ioctl(TCGETS2, pointer.unpack("L!")[0])
# unpack("P") でポインタから値を取得し、構造体を unpack
tio = Termios2.new(*pointer.unpack(Termios2::FORMAT_POINTER)[0].unpack(Termios2::FORMAT))
単に文字列を引数に渡す方法で簡単に書ける
# バッファ
v = tio.values.flatten.pack(Termios2::FORMAT)
self.ioctl(TCGETS2, v) # v が ioctl 内で書き変わる
tio = Termios2.new(*v.unpack(Termios2::FORMAT))
v の長さが構造のサイズに足りてないと死にます
備考
リファレンスの IO#ioctl には以下のように書いてあるんだけど、意味がわからなかった……
If it is a string, it is interpreted as a binary sequence of bytes.