任意のシステムコールを実行する
syscall
は、第一引数に指定したシステムコールを呼び出します。
残りの引数はシステムコールの引数として引き渡されます。
Windows など、syscall
が実装されていなければ、例外を投げます。
引数は次のように解釈されます。
まず、引数に数値が与えられた場合、その引数は整数として引き渡されます。
そうでなければ、その文字列の値を指しているポインターを引き渡します。
ただし、その文字列は、事前にあなた自身で書き込みに耐えうるだけの長さにしておかなければいけません。
syscall
への引数として文字リテラル(または読み取り専用文字列)を使うことはできません。
それは、Perl はすべての文字列がポインターを通して書き込まれる可能性があると想定する必要があるからです。
もし整数の引数がリテラルでなく、数値コンテキストで解釈できそうにないなら、
強制的に 0
を加算して数値に見えるようにしなければいけないかもしれません。
次のコードは、syswrite
をエミュレートしています
(逆もしかり):
require 'syscall.ph'; # may need to run h2ph
my $s = "hi there\n";
syscall(SYS_write(), fileno(STDOUT), $s, length $s);
Perl は syscall
に最大で 14 個までしか引数をサポートしていませんが、通常はこれで十分なはずです。
syscall
は、呼び出したシステムコールが返す値をそのまま返します。
システムコールが失敗したら、syscall
は -1
を返し、
$! (errno) をセットします。
システムコールによっては、失敗でないにもかかわらず正常な値として -1
を返すこともあります。
そのようなコールでは、その呼び出しの前に $! = 0
を割り当て、
syscall
が -1
を返したら $! の値をチェックすると良いでしょう。
syscall(SYS_pipe())
には問題があります:
これは生成したパイプの読み出し側のファイル番号を返しますが、もう一方の側のファイル番号を取り出す方法がありません。
pipe
を使えば、この問題は回避できます。