0

我的shell脚本如下:

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

据我所知,从 FIFO 读取时,系统调用:'read' 可以从中断自动重启。我什至编写代码来验证它:

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

第二个 c 程序的读取系统调用句柄并重新启动信号中断。我的环境是:OS X 10.7, bash:3.2.48(1)-release。提前致谢。

4

1 回答 1

0

如果中断,Unix/Linux 系统调用不会自动重新启动。例如,如果您查看read(2)手册页,您将看到

如果[读取的字节数]小于请求的字节数,则不是错误;这可能会发生,例如因为现在实际可用的字节较少(可能是因为我们接近文件结尾,或者因为我们正在从管道或终端读取),或者因为 read() 被中断信号。

如果根本没有读取任何字节,则返回 -1 而不是 0,并将 errno 设置为 EINTR。

于 2012-05-17T09:20:43.753 回答