Pergunta

Se eu colocar atexit( fn ); Na pilha de saída, ela será executada quando o programa sair: retornar main() ou via exit().

Posso removê -lo da pilha?

Por que eu quero fazer isso, você pergunta?

Eu estava experimentando um simples mecanismo de tentativa usando atexit, setjmp e longjmp. Seria perfeito se eu pudesse undo-atexit(fn); - Mesmo que funcionasse apenas para a última função registrada.

Editar:

Após a sugestão de Monoceres para fazer minha própria pilha ...

A pilha funciona apenas com um apanhador de exceção por enquanto.

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();
}
Foi útil?

Solução

Por que não construir sua própria pilha que você chama de uma função ATEXIT () única? Dessa forma, você pode manipular a pilha o quanto quiser.

Outras dicas

Não, você não pode fazer isso, mas pode usar o sinalizador global para que seu manipulador de saída não faça nada se o sinalizador estiver definido.

Alternativamente, você pode ligar _Exit() (C99) - Ele executará procedimento de saída normal (feche todos os descritores abertos, envie todos os sinais necessários e pais/filhos), mas não chamará o manipulador de saída.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top