0

私のシェルスクリプトは次のとおりです。

waiter()
{
    wait
    echo wait exit with $?
}


trap waiter SIGCHLD
rm -f fifo
mkfifo fifo
set -m

sleep 5&
read dummy < fifo

ところが、シグナルトラップアクションで中断してしまいました。

bogon:xunlei ly$ waiter()
> {
>     wait
>     echo wait exit with $?
> }
bogon:xunlei ly$ 
bogon:xunlei ly$ 
bogon:xunlei ly$ trap waiter SIGCHLD
bogon:xunlei ly$ rm -f fifo
wait exit with 0
bogon:xunlei ly$ mkfifo fifo
wait exit with 0
bogon:xunlei ly$ set -m
bogon:xunlei ly$ 
bogon:xunlei ly$ sleep 5&
[1] 1089
bogon:xunlei ly$ read dummy < fifo
wait exit with 0
-bash: fifo: Interrupted system call

私が知っているように、システム コール:'read' は、FIFO からの読み取り時に割り込みから自動的に再開できます。私はそれを検証するためのコードを書きます:

set -x
cat <<-EOC  > $$.r.c
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

int main(void)
{
    int fd = open("fifo", O_RDONLY);
    if (fd < 0 ){
        fprintf(stderr, "open");
        exit(1);
     }
    char buf [1024] = {0};
    int n = read(fd, buf, 1024);
    if(n < 0){
        fprintf(stderr, "read:%s",strerror(errno));
        exit(1);
     }
     write(1,buf,n);
     return 0;

}
EOC

cc -o  $$.r $$.r.c
rm -f $$.r.c

waiter()
{
    wait
    echo wait exit with $?
}


trap waiter SIGCHLD
rm -f fifo
mkfifo fifo
set -m

sleep 5&
read dummy < fifo

sleep 5&
./$$.r

trap '' SIGCHLD

2 番目の c プログラムのシステム コール ハンドルを読み取り、シグナル割り込みを再開します。私の環境は:OS X 10.7, bash:3.2.48(1)-releaseです。前もって感謝します。

4

1 に答える 1

0

Unix/Linux システム コールは、中断された場合に自動的に再起動しません。たとえば、read(2)の man ページを見ると、次のように表示されます。

[読み取ったバイト数] が要求されたバイト数よりも小さい場合はエラーではありません。これは、たとえば、現在実際に使用できるバイト数が少ないため (おそらく、ファイルの終わりに近づいていたため、またはパイプまたは端末から読み取っているため)、または read() が a によって中断されたために発生する可能性があります。信号。

また、バイトがまったく読み取られない場合は、0 ではなく -1 が返され、errno に EINTR が設定されます。

于 2012-05-17T09:20:43.753 に答える