2010-02-22 15 views
10

Si coloco atexit(fn); en la pila de salida, se ejecutará cuando el programa salga: regresa de main() o de exit().¿Puedo deshacer o eliminar un comando atexit?

¿Puedo eliminarlo de la pila?

¿Por qué quiero hacer esto, usted pregunta?

Estaba experimentando con un mecanismo de prueba simple usando atexit, setjmp y longjmp. Sería perfecto si pudiera undo-atexit(fn); - incluso si es sólo funcionaría para la última función registrada.

Editar:

Siguiendo la sugerencia monoceres' para hacer mi propia pila ...

La pila sólo funciona con un receptor excepción por ahora.

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 tiene un 'unatexit()'; ver http://pic.dhe.ibm.com/infocenter/aix/v6r1/index.jsp?topic=%2Fcom.ibm.aix.basetechref%2Fdoc%2Fbasetrf1%2Fexit.htm –

Respuesta

14

¿Por qué no construyes tu propia pila que llamas desde una sola función atexit()? De esa forma podrías manipular la pila todo lo que quieras.

+1

Excelente idea. Gracias. – philcolbourn

7

No, no lo puede hacer, pero se puede utilizar el indicador global, de modo que su manejador de salida va a hacer nada si se establece el indicador.

Como alternativa, puede llamar al _Exit() (C99) - llevará a cabo el procedimiento de salida normal (cierre todas las descripciones abiertas, envíe todas las señales necesarias y padres/hijos) pero no llamará al controlador de salida.

+0

Eso pensé. Pensaré en esto. Gracias. – philcolbourn