2010-02-22 12 views
10

Se inserisco atexit(fn); nello stack di uscita, verrà eseguito quando il programma termina: restituisce da main() o tramite exit().Posso annullare o rimuovere un comando atexit?

Posso rimuoverlo dallo stack?

Perché voglio fare questo, chiedi?

Stavo sperimentando un semplice meccanismo try-catch utilizzando atexit, setjmp e longjmp. Sarebbe perfetto se potessi undo-atexit(fn); - anche se funzionasse solo per l'ultima funzione registrata.

Edit:

Seguendo il suggerimento monoceres' a fare il mio proprio stack ...

Lo stack funziona solo con un collettore un'eccezione per ora.

void (*_catchFn[10])() = {0,0,0,0,0,0,0,0,0,0}; 

void _catch(){ 
    if (_catchFn[0] != 0){ 
    (_catchFn[0])(); 
    } 
} 

void _addCatch(void (*fn)()){ 
    _catchFn[0]=fn; 
} 

void _remCatch(void (*fn)()){ 
    _catchFn[0]=0; 
} 

void test(){ 
    jmp_buf env; 

    void catch(){     // we get here after an exit with a registered catch 
    longjmp(env,1);    // return to the line marked except... 
           // that first will get the value 1 
    } 
    int first = setjmp(env);  // ** return here ** 
    fprintf(stderr , "test: After setjmp. first=%d\n" , first); 
    if(first == 0){    // try this code 
    _addCatch(catch);   // register the catch function to 'catch' the exit 
    fprintf(stderr , "test: Before CHECK\n"); 
    // CHECK something and something bad happens and it exits 
    exit(1);      // like this 
    fprintf(stderr , "test: After CHECK - THIS SHOULD NEVER BE SEEN AFTER AN EXCEPTION.\n"); 
    }else{ 
    fprintf(stderr , "test: After longjmp return. first=%d\n" , first); 
    } 
    _remCatch(catch); 
    fprintf(stderr , "test: IT WORKED!\n"); 
    exit(1); // exit again to see if we are safe 
} 

int main(){ 
    atexit(_catch);    // register my global exception stack 
    test(); 
} 
+1

AIX ha un 'unatexit()'; vedi http://pic.dhe.ibm.com/infocenter/aix/v6r1/index.jsp?topic=%2Fcom.ibm.aix.basetechref%2Fdoc%2Fbasetrf1%2Fexit.htm –

risposta

14

Perché non creare il proprio stack che si chiama da una singola funzione atexit()? In questo modo è possibile manipolare lo stack tutto ciò che si desidera.

+1

Ottima idea. Grazie. – philcolbourn

7

No, non può farlo, ma è possibile utilizzare flag globale in modo che il gestore di uscita farà nulla se è impostato il flag.

In alternativa è possibile chiamare _Exit() (C99) - eseguirà la normale procedura di uscita (chiudi tutti i descrittori aperti, invia tutti i segnali necessari e padre/figli) ma non chiamerà il gestore di uscita.

+0

Ho pensato così. Ci penserò su questo. Grazie. – philcolbourn

Problemi correlati