简体   繁体   中英

How to manage reads with signals in C?

I'm reading integers from a file in this way:

int v, num;
    for(;;) {
        v = read(fd, &num, sizeof(int));
        if (v == -1) {
            fprintf(stderr, "Error in read()\n");
            exit(EXIT_FAILURE);
        }
        if (v == 0) 
            break;
        [...]
    }

What does it happen if a signal arrives? How can I manage errno == EINTR? Do I have to repeat read if errno==EINTR?

If you didn't mess with signals, you don't have to worry about it. Here's why: a signal's action is either terminate, ignore, or invoke a handler (or stop / continue, but let's ignore these), so, unless you explicitly caught any signal, then you will never have to think about EINTR - it will only happen if read(2) was interrupted by a signal handler that you set up, was invoked and returned.

If you caught a signal, then whether or not slow syscalls are automatically restarted is controlled by the SA_RESTART flag that can be set/unset in the sa_flags field of struct sigaction before setting the signal handler. If you want read(2) and others to automatically restart after the handler returns, then you must specify this flag to keep code portable (the default behavior varies across platforms).

Under some conditions, there are a couple of interfaces that are not automatically restarted even if SA_RESTART is set; refer to man 7 signal to see a list.

In case you're wondering: slow syscalls are syscalls that can block forever under certain conditions: for example, read() s from a terminal or socket, open(2) on FIFOs, wait(2) and family, file locking interfaces, some ioctl(2) calls, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM