2010-02-22 5 views
10

यदि मैं निकास स्टैक पर atexit(fn); डालता हूं, तो प्रोग्राम बाहर निकलने पर इसे निष्पादित किया जाएगा: main() से या exit() के माध्यम से।क्या मैं एक अस्थायी कमांड को पूर्ववत या हटा सकता हूं?

क्या मैं इसे ढेर से हटा सकता हूं?

मैं ऐसा क्यों करना चाहता हूं, आप पूछते हैं?

मैं atexit, setjmp और longjmp का उपयोग कर एक सरल प्रयास-पकड़ तंत्र के साथ प्रयोग कर रहा था। यह सही होगा अगर मैं undo-atexit(fn); कर सकता हूं - भले ही यह केवल अंतिम पंजीकृत फ़ंक्शन के लिए काम करेगा।

संपादित करें:

अपने ही ढेर बनाने के लिए monoceres 'सुझाव के बाद ...

ढेर केवल अब के लिए एक अपवाद पकड़ने के साथ काम करता है।

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

एईक्स में 'unatexit()' है; http://pic.dhe.ibm.com/infocenter/aix/v6r1/index.jsp?topic=%2Fcom.ibm.aix.basetechref%2Fdoc%2Fbasetrf1%2Fexit.htm –

उत्तर

14

अपने स्वयं के ढेर का निर्माण क्यों न करें जिसे आप एक ही एटएक्सिट() फ़ंक्शन से कॉल करते हैं? इस तरह आप जो भी चाहते हैं उस ढेर में हेरफेर कर सकते हैं।

+1

उत्कृष्ट विचार। धन्यवाद। – philcolbourn

7

नहीं, आप यह नहीं कर सकते, लेकिन आप वैश्विक ध्वज उपयोग करती हैं इसलिए अपने से बाहर निकलें हैंडलर कुछ भी नहीं कर रही होगी कर सकते हैं अगर ध्वज सेट है।

वैकल्पिक रूप से आप _Exit() (सी 99) पर कॉल कर सकते हैं - यह सामान्य निकास प्रक्रिया (सभी खुले डिस्क्रिप्टर बंद करें, सभी आवश्यक सिग्नल और माता-पिता/बच्चों को भेजें) करेगा लेकिन बाहर निकलने वाले हैंडलर को कॉल नहीं करेंगे।

+0

मैंने ऐसा सोचा। मैं इसके बारे में सोचूंगा। धन्यवाद। – philcolbourn

संबंधित मुद्दे