関連記事
GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ
概要
以下、自分用のメモです。
syscallパッケージやunixには Syscall という関数が用意されています。
これはsyscall(2)のラッパーです。間接システムコールと呼ばれます。
普段ほぼ利用することなんて無い関数ですが、極々たまにglibcにラップされていないシステムコールをGo側から呼び出したい場合などに利用できたりします。
個人的に、存在はしってましたが使ったこと無かったので、試しにサンプル作ってみました。
unixパッケージの方を利用しています。
今回は Syscallのサンプルです。こちらは引数が3つまでのシステムコールに利用します。
3つ以上の場合は Syscall6の方を利用します。
サンプル(間接システムコールの呼び出し)
main.go
//go:build linux package main import ( "fmt" "log" "os" "golang.org/x/sys/unix" ) func main() { log.SetFlags(0) if err := run(); err != nil { log.Fatal(err) } } func run() error { // // unix.Syscall() のサンプル // // unix.Syscall(), unix.Syscall6() は、指定したシステムコールを呼び出すための関数。 // // unix.Syscall() は引数が3つ指定できるシステムコール呼び出し関数。 // これより多い場合は6つ指定できる unix.Syscall6() を利用する。 // // // getpid(2) // getpid(2)は引数が無い関数 (pid_t getpid(void);) // const ( ZERO uintptr = 0 // unix.Syscall()で指定する際に利用する不要な引数値 ) var ( trap uintptr = unix.SYS_GETPID r1, r2 uintptr err unix.Errno // unix.Syscall()の場合は error ではなく unix.Errno であることに注意 ) r1, r2, err = unix.Syscall(trap, ZERO, ZERO, ZERO) if err != 0 { return fmt.Errorf("getpid: %d", err) } log.Printf("[syscall] r1=%d, r2=%d", r1, r2) log.Printf("[pid ] syscall=%d, os=%d", r1, os.Getpid()) return nil }
Taskfile.yml
# https://taskfile.dev version: '3' tasks: default: cmds: - rm -f ./app - go build -o app . - ./app
実行結果
$ task task: [default] rm -f ./app task: [default] go build -o app . task: [default] ./app [syscall] r1=31142, r2=0 [pid ] syscall=31142, os=31142
参考情報
try-golang/examples/syscall/syscall at main · devlights/try-golang · GitHub
Goのおすすめ書籍
過去の記事については、以下のページからご参照下さい。
サンプルコードは、以下の場所で公開しています。