The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Сигналы и переходы jmp"
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (C/C++)
Изначальное сообщение [ Отслеживать ]

"Сигналы и переходы jmp"  +/
Сообщение от horse315 (ok) on 04-Ноя-10, 18:11 
Вашему вниманию несчастное универское задание:

---
# Составить программу, которая заданное число раз (для определенности 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?_

Высказать мнение | Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Сигналы и переходы jmp"  +/
Сообщение от ACCA (ok) on 05-Ноя-10, 10:28 
Так работает:

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.

Высказать мнение | Ответить | Правка | ^ | Наверх | Cообщить модератору

2. "Сигналы и переходы jmp"  +/
Сообщение от horse315 (ok) on 05-Ноя-10, 11:13 
>[оверквотинг удален]
>     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 не внимательно прочитал((

Высказать мнение | Ответить | Правка | ^ | Наверх | Cообщить модератору

3. "Сигналы и переходы jmp"  +/
Сообщение от guest email(??) on 06-Ноя-10, 16:15 
> Рекомендуется использовать системные вызовы 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

Высказать мнение | Ответить | Правка | ^ | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру