💡
Rustからlibc呼ぶときのエラーハンドリングがどうなってるか調べてみた
はじめに
Rustはシステムプログラミング言語なので、libc経由でシステムコールを呼ぶことが多いと思うのですが、C言語はエラーハンドリングの仕方がRustとは全く異なっていて返り値でエラーを判定してerrno
から取得するというやり方をしています。
じゃあ、Rustでエラーハンドリングするときはどうするの?というのを調べてみたのがこの記事です。
RustからOSのエラーを取得する方法
std::io::Error
にlast_os_error
というのが用意されていて、これで取得することができます。
例えばこんな感じで使えます。
use std::io::Error;
let os_error = Error::last_os_error();
println!("last OS error: {os_error:?}");
エラーハンドリングを行う方法
unsafe
ブロック内で返り値で判定し、last_os_error
で取得します。
例えばこんな感じです。
let ret = unsafe { libc::flock(file.as_raw_fd(), operation) };
if ret == -1 { Err(io::Error::last_os_error()) } else { Ok(Lock { _file: file }) }
実際に例えばここでそういう実装がされています。
同じ様な処理を何度も書くのが嫌なのか、共通化されている箇所もあります。
macroを使って複数の値に一度にimplするのは時々見る手法ですね。
macro_rules! impl_is_minus_one {
($($t:ident)*) => ($(impl IsMinusOne for $t {
fn is_minus_one(&self) -> bool {
*self == -1
}
})*)
}
おわりに
面白そうな話題だと思ったのですが、そんな大したことなかった…
Discussion