Вашему вниманию несчастное универское задание:---
# Составить программу, которая заданное число раз (для определенности 5) через определенный временной интервал (5 сек.) повторяет на экране запрос, ожидающий стандартный ввод. Процесс должен завершаться в случае корректного ответа на запрос или после исчерпывания заданного числа запросов. При написании программы рекомендуется использовать средства обработки сигнала от таймера и средства нелокального перехода.Рекомендуется использовать системные вызовы alarm, signal, read и функции setjmp и localjmp.
---И вот приблизительное решение, которое напрашивается. по идее должно бесконечно задавать вопрос, делая перерывы по 5 сек:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <setjmp.h>
#include <string.h>jmp_buf jmp;
void pauser(int sig){
printf("no time no time...\n");
sleep(5);
longjmp(jmp,2);
}int main(){
char buf[128];
const char ask[] = "Ioann IV sobriquet?\n";
const char ans[] = "Grozniy\n";
setjmp(jmp);
signal(SIGALRM, pauser);
alarm(5);
do{
write(1, ask, strlen(ask));
read(0,buf,128);
}while(strcmp(ans, buf)!=0);
exit(1);
}Но вот незадача, первый раз аларм сработал, снова выводится предложение ответить на вопрос и все, тишина) setjmp и alarm не дружат?
Типа:
Ioann IV sobriquet?_
no time no time...
Ioann IV sobriquet?_
Так работает:void pauser(int sig){
printf("no time no time...\n");
siglongjmp(jmp,1);
}int main(){
char buf[128];
const char ask[] = "Ioann IV sobriquet?\n";
const char ans[] = "Grozniy\n";
signal(SIGALRM, pauser);
sigsetjmp(jmp, SIGALRM);
alarm(5);
do{
write(1, ask, strlen(ask));
read(0,buf,128);
}while(strcmp(ans, buf)!=0);
exit(1);
}Поиграйся ещё, обобщи что существенно и напиши здесь, pls.
Неприлично мешать printf и write, выбери что-то одно. Ещё - выбрось \n, используй puts, так считается кошернее, читай с помощью fgets. При этом gets не годится, так как позволяет buffer overflow.
>[оверквотинг удален]
> do{
> write(1, ask, strlen(ask));
> read(0,buf,128);
> }while(strcmp(ans, buf)!=0);
> exit(1);
> }
> Поиграйся ещё, обобщи что существенно и напиши здесь, pls.
> Неприлично мешать printf и write, выбери что-то одно. Ещё - выбрось \n,
> используй puts, так считается кошернее, читай с помощью fgets. При этом
> gets не годится, так как позволяет buffer overflow.ОО все роскошно, спасибо! снова я man не внимательно прочитал((
> Рекомендуется использовать системные вызовы alarm, signal, read и функции setjmp и localjmp.Вам плохое рекомендуют.
Про longjmp из обработчика лучше забыть (он не восстановит статические переменные libc на момент вызова setjmp), в не учебных программах это может стать причиной больших и трудно отлавливаемых проблем.
Вместо signal лучше посмотрите на sigaction(2) вполне себе POSIX и не надо каждый раз заново переустанавливать обработчик.
printf(3) в обработчике использовать нельзя т.к. это не signal-safe функция. На некоторых *nix можно (v)s(n)printf() и syslog_r, а вот printf я не видел нигде. Список/Ссылка на него функций разрешенных к вызову из обработчика сигнала должен быть в man signal(2)> char buf[128];
> read(0,buf,128);корректнее все-таки читать sizeof(buf)-1 байт.
> Но вот незадача, первый раз аларм сработал, снова выводится предложение ответить на
> вопрос и все, тишина) setjmp и alarm не дружат?setjmp не сохраняет маску сигналов (это верно не для всех систем, но например линукс ведет себя именно так), т.е. из обработчика ваш код вываливается с заблокированным SIGALRM и вам надо либо явно разрешить его (sigprocmask(SIG_UNBLOCk,...), либо использовать sigsetjmp