(1)  | 終了処理の登録と実行(atexit)ルーチンの作成例  | 
 
終了処理の登録を行うライブラリatexit関数の作成法を示します。
atexit関数では、引数として渡された関数のアドレスを、終了処理のテーブルに登録します。登録された関数の個数が限界値(ここでは、登録できる個数を32個とします)を超えた場合、あるいは同じ関数が二度以上登録された場合はリターン値として0以外(ここでは1)を返します。そうでなければ0を返します。
以下にプログラム例を示します。
#include <stdlib.h>  
  
long _atexit_count=0 ;  
  
void (*_atexit_buf[32])(void) ;  
  
#ifdef __cplusplus 
extern "C" 
#endif  
long atexit(void (*f)(void))  
{
    int i; 
  
    for(i=0; i<_atexit_count ; i++)        // 既に登録されていないかチェックします 
        if(_atexit_buf[i]==f) 
            return 1;  
    if (_atexit_count==32)                 // 登録数の限界値をチェックします 
        return 1;  
    else {
        _atexit_buf[_atexit_count++]=f;    // 関数のアドレスを登録します 
        return 0; 
    } 
} 
 | 
 
(2)  | プログラムの終了(exit)ルーチンの作成例  | 
 
プログラムの終了処理を行うライブラリexit関数の作成法を示します。プログラムの終了処理は、ユーザシステムによって異なりますので、以下のプログラム例を参考に、ユーザシステムの仕様に従った終了処理を作成してください。
exit関数は、引数として渡されたプログラムの終了コードに従ってプログラムの終了処理を行い、プログラム起動時の環境に戻ります。ここでは、終了コードを外部変数に設定して、main関数を呼び出す直前にsetjmp関数で退避した環境に戻ることによって実現します。プログラム実行前の環境に戻るためには、次の関数「callmain」を作成し、初期設定関数「PowerON_Reset_PC」から関数「main」を呼び出す代わりに、関数「callmain」を呼び出してください。
以下にプログラム例を示します。
#include <setjmp.h>  
#include <stddef.h> 
  
extern long _atexit_count ;  
extern void (*_atexit_buf[32])(void) ; 
#ifdef __cplusplus 
extern "C" 
#endif  
void _CLOSEALL(void); 
int main(void); 
extern jmp_buf _init_env ;  
int _exit_code ;  
  
#ifdef __cplusplus 
extern "C" 
#endif  
void exit(int code)  
{
    int i; 
    _exit_code=code ;                           // _exit_codeにリターンコードを設定します 
    for(i=_atexit_count-1; i>=0; i--)           // atexit関数で登録した関数を順次実行します 
        (*_atexit_buf[i])(); 
    _CLOSEALL();                                // オープンした関数を全てクローズします 
    longjmp(_init_env, 1) ;                     // setjmpで退避した環境にリターンします 
} 
#ifdef __cplusplus 
extern "C" 
#endif  
void callmain(void) 
{
     // setjmpを用いて現在の環境を退避し、main関数を呼び出します 
     if(!setjmp(_init_env)) 
         _exit_code=main();                     // exit関数からのリターン時には処理を終了します 
} 
 | 
 
異常終了の場合は、ご使用になっているユーザシステムの仕様に従って、プログラムを異常終了させる処理を行ってください。
C++プログラムを使用する場合、以下のときにもabort関数を呼び出します。
-  | クラス配列のdelete時に情報が取れなかった場合  | 
 
-  | クラスオブジェクトのデストラクタコール情報登録時に矛盾が発生した場合  | 
 
 
以下、標準出力装置にメッセージを出力したあと、ファイルをクローズしてから無限ループしてリセットを待つプログラム例を示します。
#include <stdio.h> 
#ifdef __cplusplus 
extern "C" 
#endif  
void _CLOSEALL(void); 
#ifdef __cplusplus 
extern "C" 
#endif  
void abort(void) 
{
        printf("program is abort !!\n");     // メッセージを出力します
        _CLOSEALL();                         // ファイルをクローズします 
        while(1)    ;                        // 無限ループします 
} 
 |