Причина, по которой вы можете заменить ppoll()
на poll()
здесь, на данный момент - , а не , потому что маска сигнала, предоставленная ppoll()
, пуста - это действительно обычный случай - но потому чтомаска сигнала до ppoll()
также, вероятно, пуста.
Это возможно только потому, что оболочка в настоящее время не пытается обрабатывать какие-либо сигналы.Как только вы захотите подать сигналы оболочки, вам нужно будет использовать следующую последовательность:
/* Block all signals */
sigprocmask(SIG_SETMASK, all_signals);
/* Check and handle any signals that have occured. */
check_signals();
/* Wait for activity on a file descriptor or a signal */
ppoll(..., empty_set);
ppoll()
здесь необходимо, потому что в противном случае возникает состояние гонки - сигнал может поступить между check_signals();
и poll()
вызов, который будет пропущен.Следовательно, сигналы блокируются на эту длительность, затем атомно разблокируется в ppoll()
.
Поскольку ppoll()
является расширением GNU, которое Solaris не предоставляет, вам необходимо изменить кодиспользовать pselect()
, которая является стандартной функцией POSIX.
Чтобы преобразовать ваш код в pselect()
, замените начало цикла на:
do
{
fd_set rdset;
int nfds = STDIN_FILENO + 1;
FD_ZERO(&rdset);
FD_SET(STDIN_FILENO, &rdset);
ret = pselect(nfds, &rdset, NULL, NULL, &timeout, &sigmask);
if (ret < 0) {
if (errno == EINTR)
continue;
else
break;
}
if (FD_ISSET(STDIN_FILENO, &rdset))
{
ret = read(STDIN_FILENO, &line[count], sizeof(line) - count);
/* ... */
Youзатем можно удалить переменную fds
, поскольку она больше не нужна.
Обратите внимание, что я добавил код, чтобы проверить возвращаемое значение pselect()
на наличие ошибок - старый код должен был выполнятьто же самое для ppoll()
.