Scanf с сигналами - PullRequest
       24

Scanf с сигналами

1 голос
/ 25 марта 2010

У меня есть сигнал, который блокирует SIGINT и в основном говорит: "Извините, вы не можете выйти. \ N"

Проблема в том, что это может произойти во время сканирования.

Когда это происходит во время сканирования, scanf принимает printf в качестве ввода.

Как мне сделать printf, которая заставит scanf автоматически нажимать клавишу ввода? Мне все равно, что я получаю плохой вклад. Я просто хочу программно завершить это сканирование с помощью printf или чего-то еще.

Процесс:

scanf ("получить вещи") -> Пользователь может ввести материал в.

-> SIGINT происходит и переходит к моему обработчику.

-> Хендлер говорит «Бла-бла-бла» на стандартный вывод.

-> Сканф взял этот бла-бла-бла и ждет большего ввода.

Как мне сделать так, чтобы, когда я вернусь, scanf закончил (не важно, что он собрал, я просто хочу, чтобы он продолжался без помощи пользователя).

РЕДАКТИРОВАТЬ: если я посылаю два сигнала, то сканирование прекращается. Я хочу как-то программно эмулировать окончание scanf.

Ответы [ 2 ]

1 голос
/ 25 марта 2010

Ваш вопрос говорит о том, что вы запутались, или, возможно, английский не является вашим родным языком.

У меня есть сигнал, который блокирует SIGINT и в основном говорит: "Извините, вы не можете выйти. \ N"

То, что у вас может быть, это обработчик сигнала, который настроен на ответ на SIGINT. Кроме того, вы можете использовать функцию «signal ()» для установки обработчика, но вы должны стремиться использовать стандартную функцию «sigaction ()» POSIX для установки обработчика.

Проблема в том, что это может произойти во время сканирования.

В контексте «this», по-видимому, является сигналом прерывания, вводимым пользователем, который хочет остановить вашу программу. Будьте осторожны, останавливая людей, выходящих из программы с сигналом прерывания; если вы не позволите им сделать это, они будут более жестокими. Это может означать, что вместо этого они сгенерируют SIGQUIT (и, возможно, дамп ядра); если вы также заблокируете это, есть ряд других трюков, которые они могут попробовать, пока не дойдут до конечного 'kill -9 pid', на который ваша программа не сможет реагировать.

Когда это происходит во время сканирования, scanf принимает printf в качестве ввода.

Это сбивает с толку ... вы, вероятно, намекаете, что вывод из оператора 'printf ()' (предположительно тот, который говорит "Вы не можете выйти"), затем рассматривается как вход для 'scanf () «? Это кажется невероятным ... Это потребовало бы очень, очень странной настройки ввода / вывода процесса, и я все еще не уверен, что это может произойти.

Как мне сделать printf, которая заставит scanf автоматически нажимать клавишу ввода? Мне все равно, что я получаю плохой вклад. Я просто хочу программно завершить это сканирование с помощью printf или чего-то еще.

Существует несколько возможностей - отчасти это зависит от используемой вами O / S (даже если это POSIX.) Я не использую 'scanf ()'; Я считаю, что это слишком сложно контролировать. Если ваша система возобновит чтение после того, как обработчик прерываний вернется, у вас будет трудное время. Однако иногда «scanf ()» останавливается и возвращает количество обработанных элементов. Если «scanf ()», который у вас есть, не завершается, вам нужно будет подумать о вставке «sigsetjmp ()» в функцию, которая просто вызывает setjmp (), а затем вызывает вашу функцию, которая вызывает scanf () , Затем ваш обработчик сигнала может использовать siglongjmp () для возврата к этой промежуточной функции:

sigjmp_buf trap;

int intermediary(int argument)
{
    if (sigsetjmp(trap) == 0)
    {
         function_calling_scanf(argument);
         return 0;  // Success
    }
    // Report failure
    return -1;
}

Ваше описание продолжается:

Процесс:

   scanf("get stuff") -> User is able to enter stuff in.

-> SIGINT происходит и переходит к моему обработчику.

-> Хендлер говорит «Бла-бла-бла» на стандартный вывод.

-> Сканф взял этот бла-бла-бла и ждет большего ввода.

Откуда вы знаете, что scanf прочитал «бла-бла-бла»? Это кажется мне очень, очень невероятным.

Как мне сделать так, чтобы, когда я вернусь, scanf закончил (не важно, что он собрал, я просто хочу, чтобы он продолжался без помощи пользователя).

Используйте sigsetjmp().

РЕДАКТИРОВАТЬ: если я посылаю два сигнала, то сканирование прекращается. Я хочу как-то программно эмулировать окончание scanf.

Это означает, что вы используете 'signal ()' для установки вашего обработчика сигнала, а не 'sigaction ()'. При использовании «signal ()», когда происходит прерывание, обработчик сигнала возвращается к значению по умолчанию. С 'sigaction ()' вы должны запросить это поведение; по умолчанию принятый сигнал (SIGINT) блокируется на длительный срок, и обработчик сигнала остается в силе. Если второе прерывание происходит во время работы первого, второе удерживается до тех пор, пока не вернется первый обработчик (в этот момент обработчик будет введен повторно).

0 голосов
/ 25 марта 2010

Не используйте scanf, поскольку его буферизация или повторный код могут помешать. Если вы используете read(2) вызов, он должен вернуть -1 с ошибкой EINTR. Scanf может увидеть эту ошибку и повторить чтение. Вы всегда можете отсканировать данные из необработанного чтения.

Предполагается, что QNX совместим с POSIX для чтения, и у вас нет источника для сканирования для проверки.

...