Сигналы UNIX - это червячная банка, просто чтобы сказать это.
Есть 2 лагеря в отношении системных вызовов и сигналов.
- Семантика SysV / Posix: системные вызовы прерываютсясигнал, они возвращают ошибку и устанавливают errno в EINTR
- . Системные вызовы семантики BSD автоматически перезапускаются при возникновении сигнала (ну, большинство из них в любом случае, а некоторые нет, например, select / poll / sleep).
При использовании signal () по умолчанию используется одно из двух выше: в системах BSD и Linux по умолчанию используется семантика BSD, а у каждого [нужного цитирования] есть семантика SysV.(В Linux это зависит от многих вещей, например, компиляция с -std = c99 дает семантику SysV, с -std = gnu99 дает семантику BSD. См., Например, http://www.gnu.org/s/hello/manual/libc/Interrupted-Primitives.html)
Когда вы устанавливаете обработчик сигнала с sigaction (), вы можете выбрать семантику с флагами SA_RESTART.
В основном:
- Не используйте сигналы, если можете помочь.
- Используйте BSDсемантика, если вы можете.
- В коде, который должен быть переносимым и обрабатывать сигналы, вам нужно обернуть каждый системный вызов в цикл, который проверяет вызов на сбой, проверяет errno на EINTR и снова выполняет системный вызов(или сделать что-то на основе перехваченного сигнала).
- библиотечные вызовы могут использовать сигналы, даже если ваш код этого не делает. Системные вызовы
- в целом, с семантикой SysV / Posix, вернутся -1 и установите для errno значение EINTR. Но прочитайте документацию, чтобы узнать, что это за состояние ошибки.
РЕДАКТИРОВАТЬ: отредактировано, поскольку я перепутал семантику BSD против Sysv.