signal handling...



  • Hallo zusammen,

    ich will einen blockierenden systemcall mit einem signal (in diesem Fall SIGINT) unterbrechen, damit der Benutzer nicht endlos warten muss. Leider waren meine ersten Versuche nicht erfolgreich.

    Ich habe mal versucht es auf ein Minimalbeispiel zu reduzieren.

    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <unistd.h>
    
    int sigint_flag;
    
    void sigint_handler(int sig)
    {
    	sigint_flag = 1;
    }
    
    int main()
    {
    	int pid;
    
    	signal (SIGINT, sigint_handler);
    
    	sigint_flag = 0;
    
    	if ((pid = fork ()) == 0) {
    		sleep (100);
    		exit (0);
    	} else {
    		if (waitpid (pid, NULL, 0) == -1)
    			if (sigint_flag) {
    				printf ("waitpid erfolgreich unterbrochen\n");
    			}
    	}
    	return 0;
    }
    

    Und folgendes dachte ich mir dazu: Also der Kind-Prozess beendet sich nach 100 Sekunden und genau so lange wartet der Parent ja auch auf ihn mit waitpid ().
    Falls ich jetzt zwischendrinne Ctl-C mache, wird signal-handler ausgeführt, also das flag auf 1 gesetzt, waitpid gibt -1 zurück, und ich muss nur das flag überprüfen ob das wirklich an SIGINT lag.

    Aber offensichtlich scheint es anders zu laufen. Wenn ich nämlich das Programm starte und ich Ctl-C eingebe ist gleich das gesamte Programm weg.

    Kann mir vll. jemand sagen, was da wirklich im Hintergrund abläuft? Und wie man mein Prog reparieren kann?

    vielen Dank.



  • Es liegt an unix system.

    Du kannst zwar Strg-C abfangen, aber nicht aufhalten - es wird auf jeden fall ausgeführt. Z.B. über Rückgabewert könntest du sehen dass es gefangen wurde - aber es "ändern" kannst du nicht.

    edit: es gibt noch ein oder zwei - weiß ich nicht mehr genau - signale die nicht "aufgehalten" werden können - der rest schon. Es ist auch sinnvoll so, sonst könnten Programme existieren die du nicht beenden könntest



  • Normalerweise soltle man SIGINT aber eigentlich aufhalten können
    Die beiden nicht Auffangbaren Signale sind SIGSTOP und SIGKILL.
    Ich glaube eher dass das Ctrl-C an _beide_ prozesse geht, da beide ja mit der Tastatur verbunden sind (und soweit ich weiß werden Signalhandler nicht an das Kind "vererbt", kann aber sein dass ich falsch liege). Versuche mal vor dem sleep (im Kindprozess) signal(SIGINT,SIG_IGN); aufzurufen und sag obs dann klappt



  • SIGINT und SIGSTOP ist doch fast das gleiche, nur dass du bei SIGSTOP erstmal nicht mehr in die Liste der Prozesse kommen wirst, die demnächst CPU-Zeit kriegen.



  • SIGINT und SIGSTOP sind absolut unterschiedlich. SIGSTOP friert den Prozess ein (sodass man ihn später mit SIGCONT wieder wecken kann) während SIGINT (sofern nicht abgefangen) das Programm terminiert. Also für mich ist das ein gewaltiger Unterschied


Anmelden zum Antworten