ИМЯ signal-safety - функции async-signal-safe
ОПИСАНИЕ Функцией async-signal-safe называется функция, которую безопасно вызывать внутри обработчика сигналов. Многие функции не являются async-signal-safe. В частности, нереентерабельные функции, обычно, небезопасно вызывать в обработчиках сигналов.
Виды проблем, которые делают функцию небезопасной, можно быстро понять на примере реализации библиотеки stdio, все функции которой являются не async-signal-safe.
При выполнении буферизируемого ввода-вывода в файл функции stdio должны вести статически выделенный буфер и связанные с ним счётчики и индексы (или указатели), содержащие количество данных и текущее положение в буфере. Предположим, что основная программа находится в середине вызова функции stdio, например printf(3), которая обновляет часть буфера и связанных переменных. Если в этот момент программа прервётся обработчиком сигнала, который также вызывает printf(3), то второй вызов printf(3) будет работать с не целостными данными и результат будет непредсказуем.
Чтобы не возникало проблем с небезопасными функциями есть два варианта:
1. Следить, чтобы (а) обработчик сигнала вызывал только функции async-signal-safe, и (б) сам обработчик сигнала был реентерабельным по отношению к глобальным переменным основной программы.
2. Блокировать доставку сигнала в основной программе при вызове небезопасных функций или при работе с глобальными данными, доступными из обработчика сигнала.
Обычно, второй вариант труден для программ любой сложности, поэтому используется первый вариант.
В POSIX.1 определён набор функций, реализация которых должна быть async-signal-safe (реализация может предоставлять безопасную реализацию и других функций, но это не требуется стандартом и другие реализации могут не предоставлять те же гарантии) Обычно, функция является async-signal-safe или потому что она реентерабельная, или из-за её атомарности по отношению к сигналам (т. е., её выполнение не может быть прервано обработчиком сигнала).
Набор функций async-signal-safe по POSIX.1 показан в таблице далее. Функции, если не указано обратное, являются async-signal-safe и по POSIX.1-2001; в таблице отмечены изменения в последующих стандартах.
функция Примечания abort(3) Добавлена в POSIX.1-2003 accept(2) access(2) aio_error(3) aio_return(3) aio_suspend(3) Смотрите замечания далее alarm(2) bind(2) cfgetispeed(3) cfgetospeed(3) cfsetispeed(3) cfsetospeed(3) dup2(2) execl(3) Добавлена в POSIX.1-2008; смотрите замечания ниже execle(3) Смотрите замечания далее execv(3) Добавлена в POSIX.1-2008 execve(2) _exit(2) _Exit(2) faccessat(2) Добавлена в POSIX.1-2008 fchdir(2) Добавлена в POSIX.1-2013 fchmod(2) fchmodat(2) Добавлена в POSIX.1-2008 fchown(2) fchownat(2) Добавлена в POSIX.1-2008 fcntl(2) fdatasync(2) fexecve(3) Добавлена в POSIX.1-2008 ffs(3) Добавлена в POSIX.1-2016 fork(2) Смотрите замечания далее fstat(2) fstatat(2) Добавлена в POSIX.1-2008 fsync(2) ftruncate(2) futimens(3) Добавлена в POSIX.1-2008 getegid(2) geteuid(2) getgid(2) getgroups(2) getpeername(2) getpgrp(2) getpid(2) getppid(2) getsockname(2) getsockopt(2) getuid(2) htonl(3) Добавлена в POSIX.1-2016 htons(3) Добавлена в POSIX.1-2016 kill(2) link(2) linkat(2) Добавлена в POSIX.1-2008 listen(2) longjmp(3) Добавлена в POSIX.1-2016; смотрите замечания ниже lseek(2) lstat(2) memccpy(3) Добавлена в POSIX.1-2016 memchr(3) Добавлена в POSIX.1-2016 memcmp(3) Добавлена в POSIX.1-2016 memcpy(3) Добавлена в POSIX.1-2016 memmove(3) Добавлена в POSIX.1-2016 memset(3) Добавлена в POSIX.1-2016 mkdir(2) mkdirat(2) Добавлена в POSIX.1-2008 mkfifo(3) mkfifoat(3) Добавлена в POSIX.1-2008 mknod(2) Добавлена в POSIX.1-2008 mknodat(2) Добавлена в POSIX.1-2008 ntohl(3) Добавлена в POSIX.1-2016 ntohs(3) Добавлена в POSIX.1-2016 pthread_self(3) Добавлена в POSIX.1-2013 pthread_sigmask(3) Добавлена в POSIX.1-2013 raise(3) read(2) readlink(2) readlinkat(2) Добавлена в POSIX.1-2008 recv(2) recvfrom(2) recvmsg(2) rename(2) renameat(2) Добавлена в POSIX.1-2008 rmdir(2) select(2) sem_post(3) send(2) sendmsg(2) sendto(2) setgid(2) setpgid(2) setsid(2) setsockopt(2) setuid(2) shutdown(2) sigaction(2) sigaddset(3) sigdelset(3) sigemptyset(3) sigfillset(3) sigismember(3) siglongjmp(3) Добавлена в POSIX.1-2016; смотрите замечания ниже signal(2) sigpause(3) sigpending(2) sigprocmask(2) sigqueue(2) sigset(3) sigsuspend(2) sleep(3) sockatmark(3) Добавлена в POSIX.1-2004 socket(2) socketpair(2) stat(2) stpcpy(3) Добавлена в POSIX.1-2016 stpncpy(3) Добавлена в POSIX.1-2016 strcat(3) Добавлена в POSIX.1-2016 strchr(3) Добавлена в POSIX.1-2016 strcmp(3) Добавлена в POSIX.1-2016 strcpy(3) Добавлена в POSIX.1-2016 strcspn(3) Добавлена в POSIX.1-2016 strlen(3) Добавлена в POSIX.1-2016 strncat(3) Добавлена в POSIX.1-2016 strncmp(3) Добавлена в POSIX.1-2016 strncpy(3) Добавлена в POSIX.1-2016 strnlen(3) Добавлена в POSIX.1-2016 strpbrk(3) Добавлена в POSIX.1-2016 strrchr(3) Добавлена в POSIX.1-2016 strspn(3) Добавлена в POSIX.1-2016 tcgetpgrp(3) tcsendbreak(3) tcsetattr(3) tcsetpgrp(3) time(2) timer_getoverrun(2) timer_gettime(2) timer_settime(2) times(2) umask(2) uname(2) unlink(2) unlinkat(2) Добавлена в POSIX.1-2008 utime(2) utimensat(2) Добавлена в POSIX.1-2008 utimes(2) Добавлена в POSIX.1-2008 wait(2) waitpid(2) wcpcpy(3) Добавлена в POSIX.1-2016 wcpncpy(3) Добавлена в POSIX.1-2016 wcscat(3) Добавлена в POSIX.1-2016 wcschr(3) Добавлена в POSIX.1-2016 wcscmp(3) Добавлена в POSIX.1-2016 wcscpy(3) Добавлена в POSIX.1-2016 wcscspn(3) Добавлена в POSIX.1-2016 wcslen(3) Добавлена в POSIX.1-2016 wcsncat(3) Добавлена в POSIX.1-2016 wcsncmp(3) Добавлена в POSIX.1-2016 wcsncpy(3) Добавлена в POSIX.1-2016 wcsnlen(3) Добавлена в POSIX.1-2016 wcspbrk(3) Добавлена в POSIX.1-2016 wcsrchr(3) Добавлена в POSIX.1-2016 wcsspn(3) Добавлена в POSIX.1-2016 wcsstr(3) Добавлена в POSIX.1-2016 wcstok(3) Добавлена в POSIX.1-2016 wmemchr(3) Добавлена в POSIX.1-2016 wmemcmp(3) Добавлена в POSIX.1-2016 wmemcpy(3) Добавлена в POSIX.1-2016 wmemmove(3) Добавлена в POSIX.1-2016 wmemset(3) Добавлена в POSIX.1-2016 write(2)
Замечания:
* В POSIX.1-2001 и POSIX.1-2004 требуется, чтобы функции fpathconf(3), pathconf(3) и sysconf(3) были async-signal-safe, но это требование удалено в POSIX.1-2008.
* Если обработчик сигнала прерывает выполнение небезопасной функции и обработчик завершается вызовом longjmp(3) или siglongjmp(3) и далее программа вызывает небезопасную функцию, то поведение программы непредсказуемо.
* В POSIX.1-2003 уточнено, что если приложение вызывает fork(2) из обработчика сигнала и и зарегистрированный обработчик fork (с помощью pthread_atfork(3)) вызывает не async-signal-safe функцию, то поведение непредсказуемо. Вероятно, в будущих версиях стандарта вызов fork(2) будет удалён из списка функций async-signal-safe. сигналов, так как в ней используется pthread_mutex_lock(3).
СМОТРИТЕ ТАКЖЕ sigaction(2), signal(7), standards(7)
|