home *** CD-ROM | disk | FTP | other *** search
/ Programming Win32 Under the API / ProgrammingWin32UnderTheApiPatVillani.iso / src / mingw-runtime-19991107 / mingw / crt1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-07-31  |  5.7 KB  |  235 lines

  1. /*
  2.  * crt1.c
  3.  *
  4.  * Source code for the startup proceedures used by all programs. This code
  5.  * is compiled to make crt1.o, which should be located in the library path.
  6.  *
  7.  * This code is part of the Mingw32 package.
  8.  *
  9.  * Contributors:
  10.  *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
  11.  *  Maintained by Mumit Khan <khan@xraylith.wisc.EDU>
  12.  *
  13.  *  THIS SOFTWARE IS NOT COPYRIGHTED
  14.  *
  15.  *  This source code is offered for use in the public domain. You may
  16.  *  use, modify or distribute it freely.
  17.  *
  18.  *  This code is distributed in the hope that it will be useful but
  19.  *  WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY
  20.  *  DISCLAMED. This includes but is not limited to warrenties of
  21.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  22.  *
  23.  * $Revision: 1.7 $
  24.  * $Author: khan $
  25.  * $Date: 1999/04/05 18:54:36 $
  26.  *
  27.  */
  28.  
  29. #include <stdlib.h>
  30. #include <stdio.h>
  31. #include <io.h>
  32. #include <fcntl.h>
  33. #include <process.h>
  34. #include <float.h>
  35. #include <windows.h>
  36. #include <signal.h>
  37.  
  38. /* NOTE: The code for initializing the _argv, _argc, and environ variables
  39.  *       has been moved to a separate .c file which is included in both
  40.  *       crt1.c and dllcrt1.c. This means changes in the code don't have to
  41.  *       be manually synchronized, but it does lead to this not-generally-
  42.  *       a-good-idea use of include. */
  43. #include "init.c"
  44.  
  45. extern int main (int, char **, char **);
  46.  
  47. /*
  48.  * Must have the correct app type for MSVCRT. 
  49.  */
  50.  
  51. #ifdef __MSVCRT__
  52. #define __UNKNOWN_APP    0
  53. #define __CONSOLE_APP    1
  54. #define __GUI_APP        2
  55. __MINGW_IMPORT void __set_app_type(int);
  56. #endif /* __MSVCRT__ */
  57.  
  58. /*
  59.  * Setup the default file handles to have the _CRT_fmode mode, as well as
  60.  * any new files created by the user.
  61.  */
  62. extern unsigned int _CRT_fmode;
  63.  
  64. static void
  65. _mingw32_init_fmode ()
  66. {
  67.   /* Don't set the file mode if the user hasn't set any value for it. */
  68.   if (_CRT_fmode)
  69.     {
  70.       _fmode = _CRT_fmode;
  71.  
  72.       /*
  73.        * This overrides the default file mode settings for stdin,
  74.        * stdout and stderr. At first I thought you would have to
  75.        * test with isatty, but it seems that the DOS console at
  76.        * least is smart enough to handle _O_BINARY stdout and
  77.        * still display correctly.
  78.        */
  79.       if (stdin)
  80.     {
  81.       _setmode (_fileno (stdin), _CRT_fmode);
  82.     }
  83.       if (stdout)
  84.     {
  85.       _setmode (_fileno (stdout), _CRT_fmode);
  86.     }
  87.       if (stderr)
  88.     {
  89.       _setmode (_fileno (stderr), _CRT_fmode);
  90.     }
  91.     }
  92. }
  93.  
  94. /* This function will be called when a trap occurs. Thanks to Jacob
  95.    Navia for his contribution. */
  96. static CALLBACK long
  97. _gnu_exception_handler (EXCEPTION_POINTERS * exception_data)
  98. {
  99.   void (*old_handler) (int);
  100.   long action = EXCEPTION_CONTINUE_SEARCH;
  101.   int reset_fpu = 0;
  102.  
  103.   switch (exception_data->ExceptionRecord->ExceptionCode)
  104.     {
  105.     case EXCEPTION_ACCESS_VIOLATION:
  106.       /* test if the user has set SIGSEGV */
  107.       old_handler = signal (SIGSEGV, SIG_DFL);
  108.       if (old_handler == SIG_IGN)
  109.     {
  110.       /* this is undefined if the signal was raised by anything other
  111.          than raise ().  */
  112.       signal (SIGSEGV, SIG_IGN);
  113.       action = EXCEPTION_CONTINUE_EXECUTION;
  114.     }
  115.       else if (old_handler != SIG_DFL)
  116.     {
  117.       /* This means 'old' is a user defined function. Call it */
  118.       (*old_handler) (SIGSEGV);
  119.       action = EXCEPTION_CONTINUE_EXECUTION;
  120.     }
  121.       break;
  122.  
  123.     case EXCEPTION_FLT_INVALID_OPERATION:
  124.     case EXCEPTION_FLT_DIVIDE_BY_ZERO:
  125.     case EXCEPTION_FLT_DENORMAL_OPERAND:
  126.     case EXCEPTION_FLT_OVERFLOW:
  127.     case EXCEPTION_FLT_UNDERFLOW:
  128.     case EXCEPTION_FLT_INEXACT_RESULT:
  129.       reset_fpu = 1;
  130.       /* fall through. */
  131.  
  132.     case EXCEPTION_INT_DIVIDE_BY_ZERO:
  133.       /* test if the user has set SIGFPE */
  134.       old_handler = signal (SIGFPE, SIG_DFL);
  135.       if (old_handler == SIG_IGN)
  136.     {
  137.       signal (SIGFPE, SIG_IGN);
  138.       if (reset_fpu)
  139.         _fpreset ();
  140.       action = EXCEPTION_CONTINUE_EXECUTION;
  141.     }
  142.       else if (old_handler != SIG_DFL)
  143.     {
  144.       /* This means 'old' is a user defined function. Call it */
  145.       (*old_handler) (SIGFPE);
  146.       action = EXCEPTION_CONTINUE_EXECUTION;
  147.     }
  148.       break;
  149.  
  150.     default:
  151.       break;
  152.     }
  153.   return action;
  154. }
  155.  
  156. /*
  157.  * The function mainCRTStartup is the entry point for all console programs.
  158.  */
  159. static int
  160. __mingw_CRTStartup ()
  161. {
  162.   int nRet;
  163.  
  164.   /*
  165.    * Set up the top-level exception handler so that signal handling
  166.    * works as expected. The mapping between ANSI/POSIX signals and
  167.    * Win32 SE is not 1-to-1, so caveat emptore.
  168.    * 
  169.    */
  170.   SetUnhandledExceptionFilter (_gnu_exception_handler);
  171.  
  172.   /*
  173.    * Initialize floating point unit.
  174.    */
  175.   _fpreset ();            /* Supplied by the runtime library. */
  176.  
  177.   /*
  178.    * Set up __argc, __argv and _environ.
  179.    */
  180.   _mingw32_init_mainargs ();
  181.  
  182.   /*
  183.    * Sets the default file mode for stdin, stdout and stderr, as well
  184.    * as files later opened by the user, to _CRT_fmode.
  185.    * NOTE: DLLs don't do this because that would be rude!
  186.    */
  187.   _mingw32_init_fmode ();
  188.  
  189.   /*
  190.    * Call the main function. If the user does not supply one
  191.    * the one in the 'libmingw32.a' library will be linked in, and
  192.    * that one calls WinMain. See main.c in the 'lib' dir
  193.    * for more details.
  194.    */
  195.   nRet = main (_argc, _argv, environ);
  196.  
  197.   /*
  198.    * Perform exit processing for the C library. This means
  199.    * flushing output and calling 'atexit' registered functions.
  200.    */
  201.   _cexit ();
  202.  
  203.   ExitProcess (nRet);
  204.  
  205.   return 0;
  206. }
  207.  
  208. /*
  209.  * The function mainCRTStartup is the entry point for all console programs.
  210.  */
  211. int
  212. mainCRTStartup ()
  213. {
  214. #ifdef __MSVCRT__
  215.   __set_app_type (__CONSOLE_APP);
  216. #endif
  217.   __mingw_CRTStartup ();
  218.   return 0;
  219. }
  220.  
  221. /*
  222.  * For now the GUI startup function is the same as the console one.
  223.  * This simply gets rid of the annoying warning about not being able
  224.  * to find WinMainCRTStartup when linking GUI applications.
  225.  */
  226. int
  227. WinMainCRTStartup ()
  228. {
  229. #ifdef __MSVCRT__
  230.   __set_app_type (__GUI_APP);
  231. #endif
  232.   __mingw_CRTStartup ();
  233. }
  234.  
  235.