/****************************************************************************/
/*                                                                          */
/* Sample Program 03 : INITTERM.C                                           */
/*                                                                          */
/* COPYRIGHT:                                                               */
/* ----------                                                               */
/* Copyright (C) International Business Machines Corp., 1991, 1993.         */
/*                                                                          */
/* DISCLAIMER OF WARRANTIES:                                                */
/* -------------------------                                                */
/* The following [enclosed] code is sample code created by IBM              */
/* Corporation.  This sample code is not part of any standard IBM product   */
/* and is provided to you solely for the purpose of assisting you in the    */
/* development of your applications.  The code is provided "AS IS",         */
/* without warranty of any kind.  IBM shall not be liable for any damages   */
/* arising out of your use of the sample code, even if they have been       */
/* advised of the possibility of such damages.                              */
/*                                                                          */
/****************************************************************************/

#define  INCL_DOSMODULEMGR
#define  INCL_DOSPROCESS
#include <os2.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/* _CRT_init is the C run-time environment initialization function.         */
/* It will return 0 to indicate success and -1 to indicate failure.         */

int _CRT_init(void);
#ifdef   STATIC_LINK

/* _CRT_term is the C run-time environment termination function.            */
/* It only needs to be called when the C run-time functions are statically  */
/* linked.                                                                  */

void _CRT_term(void);
#else

/* A clean up routine registered with DosExitList must be used if runtime   */
/* calls are required and the runtime is dynamically linked.  This will     */
/* guarantee that this clean up routine is run before the library DLL is    */
/* terminated.                                                              */

static void _System cleanup(ULONG ulReason);
#endif
size_t nSize;
int *pArray;

/* _DLL_InitTerm is the function that gets called by the operating system   */
/* loader when it loads and frees this DLL for each process that accesses   */
/* this DLL.  However, it only gets called the first time the DLL is loaded */
/* and the last time it is freed for a particular process.  The system      */
/* linkage convention MUST be used because the operating system loader is   */
/* calling this function.                                                   */
int _dllentry;

unsigned long _System _DLL_InitTerm(unsigned long hModule, unsigned long
                                    ulFlag)
{
   size_t i;
   APIRET rc;
   char namebuf[CCHMAXPATH];

   /* If ulFlag is zero then the DLL is being loaded so initialization should*/
   /* be performed.  If ulFlag is 1 then the DLL is being freed so          */
   /* termination should be performed.                                      */

   switch (ulFlag) {
      case 0 :

         /*******************************************************************/
         /* The C run-time environment initialization function must be      */
         /* called before any calls to C run-time functions that are not    */
         /* inlined.                                                        */
         /*******************************************************************/

         if (_CRT_init() == -1)
            return 0UL;
#ifndef  STATIC_LINK

         /*******************************************************************/
         /* A DosExitList routine must be used to clean up if runtime calls */
         /* are required and the runtime is dynamically linked.             */
         /*******************************************************************/

            if (rc = DosExitList(0x0000FF00|EXLST_ADD, cleanup))
            printf("DosExitList returned %lu\n", rc);
#endif
         if (rc = DosQueryModuleName(hModule, CCHMAXPATH, namebuf))
            printf("DosQueryModuleName returned %lu\n", rc);
         else
            printf("The name of this DLL is %s\n", namebuf);
         srand(17);
         nSize = (rand()%128)+32;
         printf("The array size for this process is %u\n", nSize);
         if ((pArray = malloc(nSize *sizeof(int))) == NULL) {
            printf("Could not allocate space for unsorted array.\n");
            return 0UL;
         }
         for (i = 0; i < nSize; ++i)
            pArray[i] = rand();
         break;
      case 1 :
#ifdef   STATIC_LINK
         printf("The array will now be freed.\n");
         free(pArray);
         _CRT_term();
#endif
         break;
      default  :
         printf("ulFlag = %lu\n", ulFlag);
         return 0UL;
   }

   /* A non-zero value must be returned to indicate success.                */

   return 1UL;
}
#ifndef  STATIC_LINK
static void cleanup(ULONG ulReason)
{
   if (!ulReason) {
      printf("The array will now be freed.\n");
      free(pArray);
   }
   DosExitList(EXLST_EXIT, cleanup);
   return ;
}
#endif
