From EDM2
Jump to: navigation, search

Keeps a list of routines that run when the current process ends.


DosExitList (ordercode, pfn)


ordercode (ULONG) - input 
DosExitList action and invocation order.
ordercode contains two one-byte fields in the low-order word. The high-order word is zero.
The low-order byte of the low-order word indicates which action DosExitList performs. This function can update the list of routines or transfer to the next address on the termination list at the completion of a routine. The values of the byte and their meanings are as follows:
1 EXLST_ADD Add an address to the termination list.
2 EXLST_REMOVE Remove an address from the termination list.
3 EXLST_EXIT When termination processing completes, transfer to the next address on the termination list.

The high-order byte of the low-order word indicates the invocation order. This value is valid only when the low-order byte is 1 (add an address). For the other low-order byte values, the high-order byte of the low-order word must be set to zero.

The invocation order indicates where the routine address is to be placed in an ordered list. This list determines the order in which the exit list routines are invoked. Routines with a value of 0 are invoked first, and routines with a value of 255 are invoked last. If more than one routine is added with the same invocation order value, the last routine to be added is invoked first. The following values are used by OS/2 components:

0x80 - 0x88        OS/2 Extended Edition Database Manager
0x90 - 0x98        OS/2 Extended Edition Communications Manager
0xA0 - 0xA8        OS/2 Presentation Manager
0xB0               OS/2 Keyboard (KBD) component
0xC0               OS/2 Video (VIO) component
0xD0               OS/2 Interprocess Communication (IPC) Queues component
pfn (PFNEXITLIST) - input 
The address of a routine to be run.

Return Code

ulrc (APIRET) - returns

DosExitList returns one of the following values:

  • 0 NO_ERROR


DosExitList is issued to define a routine that is to be given control when a process completes its execution. Multiple routines may be defined to receive control when a process is ending. For each process, the operating system maintains a list of addresses of defined exit list routines.

When the process is ending, the operating system transfers control to each address in this list. If there are multiple addresses in the list, they will each get control in numerical order by function invocation order, that is, low (0) will be first, and high (0xFF) will be last. In case of duplicate entries for the same value, the routines will be run in LIFO (last in, first out) order.

Library modules can issue DosExitList to free resources or to clear flags and semaphores in case the client process ends without notifying them.

Before transferring control to the routines in the termination list, the operating system resets the stack to its initial value. The routine must be in the address space of the ending process. The termination routine should perform its processing and then issue DosExitList with a value of 3 (EXLST_EXIT) for ordercode. The termination routine should be as short as possible.

Most system functions are allowed in an exit list routine. However, DosCreateThread and DosExecPgm are not.

An exit list routine must not call functions that have a better function order priority (that is, a lower value for ordercode) than itself. For example, an exit list routine with a function order value of 0x9A can use Presentation Services functions but not Communications Manager functions.

When the exit list routine receives control, the first parameter on the stack (located at ESP+4) contains a termination code that describes why the process ended. The values of the termination codes are as follows:

0 TC_EXIT        Normal exit
1 TC_HARDERROR   Hard-error halt
2 TC_TRAP        Trap operation for a 16-bit child process
3 TC_KILLPROCESS Unintercepted DosKillProcess
4 TC_EXCEPTION   Exception operation for a 32-bit child process

When the exit list routine receives control, all system semaphores owned by the process have their ownership transferred to the thread that performs exit list processing. This allows the thread to request serialization semaphores without danger of blocking in case the semaphore was held by another thread in the process that has already ended.

Note: All exit list routines must be declared as VOID APIENTRY. This ensures the integrity of the stack.

Example Code

This example adds an exit routine named "ExitRtn1" to the exit-list sequence. Routines in this sequence must use DosExitList instead of DosExit to end.

 #define INCL_DOSPROCESS              /* Process and thread values */
 #define INCL_DOSERRORS               /* DOS error values          */
 #include <os2.h>
 #include <stdio.h>

 VOID APIENTRY ExitRtn1(VOID);        /* Our exit routine */

 int main(VOID) {


    rc = DosExitList(EXLST_ADD             /* Add to exit-list sequence     */
                     | 0x00002A00,         /* Invocation order is 42 (0x2A) */
                     (PFNEXITLIST) ExitRtn1); /* Specify added exit routine */

    if (rc != NO_ERROR) {
      printf("DosExitList error: return code = %u\n", rc);
      return 1;

    printf("Routine main ends...\n");

    return NO_ERROR;

      /* All exit list routines must be declared as VOID APIENTRY.
         This ensures the integrity of the stack.                  */

    APIRET  erc = NO_ERROR;                     /* Return code */

    printf("... but ExitRtn1 runs last.\n");

           /* Might want to save data or close files here */

    erc = DosExitList(EXLST_EXIT,               /* Exit         */
                      (PFNEXITLIST) NULL);

    if (erc != NO_ERROR) {
      printf("DosExitList error: return code = %u\n", erc);


Related Functions