1 /* File: "os_base.c" */
3 /* Copyright (c) 1994-2012 by Marc Feeley, All Rights Reserved. */
6 * This module implements the most basic operating system services.
9 #define ___INCLUDED_FROM_OS_BASE
10 #define ___VERSION 406003
17 /*---------------------------------------------------------------------------*/
20 ___base_module ___base_mod
=
29 #ifdef ___DEBUG_ALLOC_MEM_TRACE
36 #ifdef ___BASE_MODULE_INIT
42 /*---------------------------------------------------------------------------*/
44 /* Standard I/O emulation */
48 ___P((const char *path
,
55 return fopen (path
, mode
);
60 ___P((___FILE
*stream
),
64 return fclose (stream
);
82 return fread (ptr
, size
, nmemb
, stream
);
87 ___P((const void *ptr
,
100 return fwrite (ptr
, size
, nmemb
, stream
);
105 ___P((___FILE
*stream
),
109 return fflush (stream
);
118 ___P((const char *format
,
125 ___FILE
*stream
= ___base_mod
.debug
;
130 va_start (ap
, format
);
131 result
= vfprintf (stream
, format
, ap
);
142 /*---------------------------------------------------------------------------*/
144 /* Memory allocation. */
148 ___P((unsigned long bytes
),
150 unsigned long bytes
;)
157 InterlockedIncrement (&___base_mod
.alloc_mem_calls
);
161 ___base_mod
.alloc_mem_calls
++;
166 #ifdef USE_TempNewHandle
168 if (___base_mod
.setup
&& ___base_mod
.has_OSDispatch
)
172 Handle h
= TempNewHandle (sizeof (Handle
) + bytes
, &err
);
173 if (e
!= noErr
|| h
== 0)
177 *___CAST(Handle
*,p
) = h
;
178 ptr
= p
+ sizeof (Handle
);
181 ptr
= malloc (bytes
);
185 ptr
= malloc (bytes
);
199 #ifdef ___DEBUG_ALLOC_MEM_TRACE
200 ___printf ("%p FREED\n", ptr
);
207 InterlockedIncrement (&___base_mod
.free_mem_calls
);
211 ___base_mod
.free_mem_calls
++;
216 #ifdef USE_TempNewHandle
218 if (___base_mod
.setup
&& ___base_mod
.has_OSDispatch
)
221 Handle h
= *___CAST(Handle
*,___CAST(Ptr
,ptr
) - sizeof (Handle
));
223 TempDisposeHandle (h
, &e
);
237 #ifdef ___DEBUG_ALLOC_MEM_TRACE
240 void * ___alloc_mem_debug
241 ___P((unsigned long bytes
,
253 ptr
= ___alloc_mem (bytes
);
256 ___printf ("%p (%lu bytes) ALLOCATED AT \"%s\"@%d.1\n",
262 ___printf ("%p (%lu bytes) ALLOCATED\n", ptr
, bytes
);
272 void *___alloc_mem_code
273 ___P((unsigned long bytes
),
275 unsigned long bytes
;)
278 #ifndef USE_VirtualAlloc
287 ___BOOL executable
= 1;
290 bytes
+ sizeof (long),
291 PROT_READ
| PROT_WRITE
| (executable
? PROT_EXEC
: 0),
292 MAP_PRIVATE
| MAP_ANON
,
296 if (ptr
== MAP_FAILED
)
299 *___CAST(long*,ptr
) = bytes
;
301 return ___CAST(long*,ptr
)+1;
305 #ifdef USE_VirtualAlloc
307 ___BOOL executable
= 1;
309 void *ptr
= VirtualAlloc (NULL
,
313 ? PAGE_EXECUTE_READWRITE
322 void ___free_mem_code
328 #ifndef USE_VirtualAlloc
335 long* p
= ___CAST(long*,ptr
)-1;
337 munmap (p
, *p
+ sizeof (long));
341 #ifdef USE_VirtualAlloc
343 VirtualFree (ptr
, 0, MEM_RELEASE
);
349 /*---------------------------------------------------------------------------*/
351 /* Program startup */
355 * ___main_char, ___main_UCS_2, and ___winmain are variants of main
356 * entry points which differ in the format of the arguments; the first
357 * two are always compiled in since they could be useful on all
358 * systems for embedding of Gambit.
362 /* To keep command line and runtime flag information around: */
364 ___program_startup_info_struct ___program_startup_info
=
366 0, /* argument vector */
367 0 /* runtime flag string */
379 ___EXP_FUNC(int,___main_char
)
382 ___mod_or_lnk (*linker
)(___global_state_struct
*),
390 ___mod_or_lnk (*linker
)();
395 if (___setup_base_module () != ___FIX(___NO_ERR
))
396 result
= ___EXIT_CODE_OSERR
;
399 if (___NONNULLCHARSTRINGLIST_to_NONNULLUCS_2STRINGLIST
401 &___program_startup_info
.argv
)
402 != ___FIX(___NO_ERR
))
403 result
= ___EXIT_CODE_SOFTWARE
;
406 if (___CHARSTRING_to_UCS_2STRING
408 &___program_startup_info
.script_line
)
409 != ___FIX(___NO_ERR
))
410 result
= ___EXIT_CODE_SOFTWARE
;
413 result
= ___main (linker
);
415 ___free_UCS_2STRING (___program_startup_info
.script_line
);
418 ___free_NONNULLUCS_2STRINGLIST (___program_startup_info
.argv
);
421 ___cleanup_base_module ();
428 ___EXP_FUNC(int,___main_UCS_2
)
430 ___UCS_2STRING argv
[],
431 ___mod_or_lnk (*linker
)(___global_state_struct
*),
438 ___UCS_2STRING argv
[];
439 ___mod_or_lnk (*linker
)();
444 if (___setup_base_module () != ___FIX(___NO_ERR
))
445 result
= ___EXIT_CODE_OSERR
;
448 ___program_startup_info
.argv
= argv
;
450 if (___CHARSTRING_to_UCS_2STRING
452 &___program_startup_info
.script_line
)
453 != ___FIX(___NO_ERR
))
454 result
= ___EXIT_CODE_SOFTWARE
;
457 result
= ___main (linker
);
459 ___free_UCS_2STRING (___program_startup_info
.script_line
);
462 ___cleanup_base_module ();
473 #define ___CMDLINE_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) ucs2
475 #define ___CMDLINE_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) native
479 ___HIDDEN ___SCMOBJ parse_windows_command_line
480 ___P((___STRING_TYPE(___CMDLINE_CE_SELECT
) cmdline
,
481 ___UCS_2STRING
**argv_return
),
484 ___STRING_TYPE(___CMDLINE_CE_SELECT
) cmdline
;
485 ___UCS_2STRING
**argv_return
;)
488 ___UCS_2STRING
*argv
= 0;
489 ___UCS_2STRING args
= 0;
490 int total_arg_len
= 0;
493 for (pass
=0; pass
<2; pass
++)
495 int in_double_quotes
;
497 ___STRING_TYPE(___CMDLINE_CE_SELECT
) p
;
498 ___CHAR_TYPE(___CMDLINE_CE_SELECT
) c
;
502 if ((argv
= ___CAST(___UCS_2STRING
*,
503 ___alloc_mem ((argc
+ 1)
504 * sizeof (___UCS_2STRING
)))) == 0)
505 return ___FIX(___HEAP_OVERFLOW_ERR
);
507 if (total_arg_len
> 0)
509 if ((args
= ___CAST(___UCS_2STRING
,
510 ___alloc_mem (total_arg_len
511 * sizeof (___UCS_2
)))) == 0)
514 return ___FIX(___HEAP_OVERFLOW_ERR
);
525 while ((c
= *p
) != '\0' && c
<= ' ')
531 in_double_quotes
= 0;
537 while ((c
= *p
) != '\0' && (in_double_quotes
|| c
> ' '))
544 nb_backslashes
= (nb_backslashes
<<1) + 1;
547 if ((nb_backslashes
& 1) == 0)
548 in_double_quotes
^= 1;
549 #ifndef PROCESS_PROGRAM_LIKE_OTHER_ARGS
551 nb_backslashes
= (nb_backslashes
<<1) + 1;
555 total_arg_len
+= ((nb_backslashes
+1)>>1);
559 while (nb_backslashes
> 1)
564 if (nb_backslashes
!= 0)
573 total_arg_len
+= nb_backslashes
+1;
577 while (nb_backslashes
-- > 0)
590 return ___FIX(___NO_ERR
);
594 ___HIDDEN
void free_windows_command_line
595 ___P((___UCS_2STRING
*argv
),
597 ___UCS_2STRING
*argv
;)
600 ___free_mem (argv
[0]);
606 ___EXP_FUNC(int,___winmain
)
607 ___P((HINSTANCE hInstance
,
608 HINSTANCE hPrevInstance
,
611 ___mod_or_lnk (*linker
)(___global_state_struct
*),
620 HINSTANCE hPrevInstance
;
623 ___mod_or_lnk (*linker
)(___global_state_struct
*);
628 if (___setup_base_module () != ___FIX(___NO_ERR
))
629 result
= ___EXIT_CODE_OSERR
;
632 /*********************************/
634 AllocConsole( ); /* Create Console Window */
635 freopen(_T("CONIN$"),_T("rb"),stdin
); /* reopen stdin handle as console window input */
636 freopen(_T("CONOUT$"),_T("wb"),stdout
); /* reopen stout handle as console window output */
637 freopen(_T("CONOUT$"),_T("wb"),stderr
); /* reopen stderr handle as console window output */
640 if (parse_windows_command_line
642 &___program_startup_info
.argv
)
643 != ___FIX(___NO_ERR
))
644 result
= ___EXIT_CODE_SOFTWARE
;
647 if (___CHARSTRING_to_UCS_2STRING
649 &___program_startup_info
.script_line
)
650 != ___FIX(___NO_ERR
))
651 result
= ___EXIT_CODE_SOFTWARE
;
654 ___program_startup_info
.hInstance
= hInstance
;
655 ___program_startup_info
.hPrevInstance
= hPrevInstance
;
656 ___program_startup_info
.lpCmdLine
= lpCmdLine
;
657 ___program_startup_info
.nCmdShow
= nCmdShow
;
659 result
= ___main (linker
);
661 ___free_UCS_2STRING (___program_startup_info
.script_line
);
664 free_windows_command_line (___program_startup_info
.argv
);
667 ___cleanup_base_module ();
677 /*---------------------------------------------------------------------------*/
679 /* Process termination. */
691 /*---------------------------------------------------------------------------*/
693 /* Error handling. */
701 if (___setup_params
.fatal_error
!= 0)
702 ___setup_params
.fatal_error (msgs
);
707 new_msgs
[0] = "*** FATAL ERROR -- ";
708 for (i
=0; i
<100-2; i
++)
712 new_msgs
[i
+1] = msgs
[i
];
714 new_msgs
[i
+1] = "\n";
716 ___display_error (new_msgs
);
719 ___exit_process (___EXIT_CODE_SOFTWARE
);
723 void ___display_error
728 if (___setup_params
.display_error
!= 0)
729 ___setup_params
.display_error (msgs
);
730 else if (___DEBUG_SETTINGS_LEVEL(___setup_params
.debug_settings
) > 0)
736 while (msg
[len
] != '\0')
738 ___fwrite (msg
, 1, len
, ___stderr
); /* ignore error */
744 /* Conversion of OS error codes to Scheme error codes. */
747 ___HIDDEN
char *error_number_to_string
752 static char txt
[] = "Error code ";
753 static char buf
[sizeof (txt
) + 20]; /* -2^63 is 20 characters in decimal */
754 char *p1
= buf
+ sizeof (buf
);
767 *--p1
= '0' + (n
/10 * 10 - n
);
774 p2
= txt
+ sizeof (txt
) - 1;
786 ___HIDDEN
char *errno_to_string
793 return strerror (code
);
797 return error_number_to_string (code
);
804 ___SCMOBJ ___err_code_from_errno_debug
812 ___SCMOBJ ___err_code_from_errno ___PVOID
818 ___printf ("*** OS ERROR AT \"%s\"@%d.1 -- errno=%d (%s)\n",
822 errno_to_string (e
));
826 return ___FIX(___UNKNOWN_ERR
);
828 return ___FIX(___ERRNO_ERR(e
));
838 ___HIDDEN
const char *h_errno_to_string
845 return hstrerror (code
);
849 static char *h_errno_messages
[] =
851 "Resolver Error 0 (no error)",
853 "Host name lookup failure",
854 "Unknown server error",
855 "No address associated with name"
858 if (code
>= 0 && code
<= 4)
859 return h_errno_messages
[code
];
861 return "Unknown resolver error";
868 ___SCMOBJ ___err_code_from_h_errno_debug
876 ___SCMOBJ ___err_code_from_h_errno ___PVOID
882 ___printf ("*** OS ERROR AT \"%s\"@%d.1 -- h_errno=%d (%s)\n",
886 h_errno_to_string (e
));
889 if (e
== NETDB_INTERNAL
)
890 return err_code_from_errno ();
892 #ifdef NETDB_WORKS_PROPERLY
894 if (e
== NETDB_SUCCESS
)
895 return ___FIX(___UNKNOWN_ERR
);
900 * Linux sometimes returns NETDB_SUCCESS when it should return
904 if (e
== NETDB_SUCCESS
)
905 return err_code_from_errno ();
909 return ___FIX(___H_ERRNO_ERR(e
));
916 #ifdef USE_getaddrinfo
919 ___HIDDEN
const char *gai_code_to_string
924 return gai_strerror (code
);
929 ___SCMOBJ ___err_code_from_gai_code_debug
940 ___SCMOBJ ___err_code_from_gai_code
949 if (code
== EAI_SYSTEM
)
950 e
= err_code_from_errno ();
954 e
= ___GAI_CODE_ERR(code
);
957 ___printf ("*** OS ERROR AT \"%s\"@%d.1 -- gai_code=%d (%s)\n",
961 gai_code_to_string (code
));
971 #ifdef USE_GetLastError
975 ___SCMOBJ ___err_code_from_GetLastError_debug
983 ___SCMOBJ ___err_code_from_GetLastError ___PVOID
986 DWORD e
= GetLastError ();
989 char buf
[___ERR_MAX_LENGTH
+1];
990 DWORD len
= FormatMessageA
991 (FORMAT_MESSAGE_FROM_SYSTEM
|FORMAT_MESSAGE_MAX_WIDTH_MASK
,
994 MAKELANGID(LANG_NEUTRAL
,SUBLANG_DEFAULT
),
998 ___printf ("*** OS ERROR AT \"%s\"@%d.1 -- GetLastError=%d (%s)\n",
1006 return ___FIX(___UNKNOWN_ERR
);
1008 if (e
== ERROR_FILE_NOT_FOUND
|| e
== ERROR_PATH_NOT_FOUND
)
1009 return ___ERR_CODE_ENOENT
;
1011 return ___FIX(___WIN32_ERR(e
));
1018 #ifdef USE_WSAGetLastError
1022 ___SCMOBJ ___err_code_from_WSAGetLastError_debug
1030 ___SCMOBJ ___err_code_from_WSAGetLastError ___PVOID
1033 DWORD e
= WSAGetLastError ();
1036 char buf
[___ERR_MAX_LENGTH
+1];
1037 DWORD len
= FormatMessageA
1038 (FORMAT_MESSAGE_FROM_SYSTEM
|FORMAT_MESSAGE_MAX_WIDTH_MASK
,
1041 MAKELANGID(LANG_NEUTRAL
,SUBLANG_DEFAULT
),
1045 ___printf ("*** OS ERROR AT \"%s\"@%d.1 -- WSAGetLastError=%d (%s)\n",
1053 return ___FIX(___UNKNOWN_ERR
);
1055 if (e
== WSAEWOULDBLOCK
)
1056 return ___ERR_CODE_EAGAIN
;
1058 return ___FIX(___WIN32_ERR(e
));
1068 ___HIDDEN
char *OSErr_to_string
1073 return error_number_to_string (code
);
1078 ___SCMOBJ ___err_code_from_OSErr_debug
1089 ___SCMOBJ ___err_code_from_OSErr
1096 ___printf ("*** OS ERROR AT \"%s\"@%d.1 -- OSErr=%d (%s)\n",
1100 OSErr_to_string (e
));
1104 return ___FIX(___UNKNOWN_ERR
);
1106 return ___FIX(___OSERR_ERR(e
));
1113 /* Conversion of Scheme error codes to error messages. */
1116 ___HIDDEN
char *c_type_name_table
[] =
1142 "unsigned-long-long",
1154 "nonnull-char-string",
1155 "nonnull-char-string-list",
1156 "ISO-8859-1-string",
1157 "nonnull-ISO-8859-1-string",
1158 "nonnull-ISO-8859-1-string-list",
1160 "nonnull-UTF-8-string",
1161 "nonnull-UTF-8-string-list",
1163 "nonnull-UTF-16-string",
1164 "nonnull-UTF-16-string-list",
1166 "nonnull-UCS-2-string",
1167 "nonnull-UCS-2-string-list",
1169 "nonnull-UCS-4-string",
1170 "nonnull-UCS-4-string-list",
1172 "nonnull-wchar_t-string",
1173 "nonnull-wchar_t-string-list",
1181 #define ___ERR_CODE_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) ucs2
1183 #define ___ERR_CODE_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) native
1187 #ifndef ___ERR_CODE_CE_SELECT
1188 #define ___ERR_CODE_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) native
1192 ___HIDDEN
void append_charstring
1193 ___P((___STRING_TYPE(___ERR_CODE_CE_SELECT
) buf
,
1199 ___STRING_TYPE(___ERR_CODE_CE_SELECT
) buf
;
1206 while (str
[i
] != '\0')
1208 if (p
>= ___ERR_MAX_LENGTH
)
1210 buf
[p
++] = ___CAST(___CHAR_TYPE(___ERR_CODE_CE_SELECT
),
1211 ___CAST(unsigned char,str
[i
++]));
1220 ___SCMOBJ ___os_err_code_to_string
1221 ___P((___SCMOBJ err
),
1227 ___ERR_CODE err_code
= ___INT(err
);
1228 int facility
= ___ERR_CODE_FACILITY(err_code
);
1229 ___CHAR_TYPE(___ERR_CODE_CE_SELECT
) buf
[___ERR_MAX_LENGTH
+1];
1234 if (facility
>= ___ERR_CODE_FACILITY_SYSTEM
)
1236 /* System specific error code */
1238 if (err_code
== ___UNWIND_C_STACK
)
1239 append_charstring (buf
, &pos
, "C stack can't be unwound further");
1240 else if (err_code
== ___SFUN_HEAP_OVERFLOW_ERR
)
1241 append_charstring (buf
, &pos
, "Heap overflow while allocating stack marker");
1242 else if (err_code
== ___IMPL_LIMIT_ERR
)
1243 append_charstring (buf
, &pos
, "Implementation limit encountered");
1244 else if (err_code
== ___UNIMPL_ERR
)
1245 append_charstring (buf
, &pos
, "Unimplemented operation");
1246 else if (err_code
== ___HEAP_OVERFLOW_ERR
)
1247 append_charstring (buf
, &pos
, "Heap overflow");
1248 else if (err_code
== ___CLOSED_DEVICE_ERR
)
1249 append_charstring (buf
, &pos
, "Device is closed");
1250 else if (err_code
== ___INVALID_OP_ERR
)
1251 append_charstring (buf
, &pos
, "Invalid operation");
1252 else if (err_code
== ___MODULE_VERSION_TOO_OLD_ERR
)
1253 append_charstring (buf
, &pos
, "Module was compiled with an older version of the compiler");
1254 else if (err_code
== ___MODULE_VERSION_TOO_NEW_ERR
)
1255 append_charstring (buf
, &pos
, "Module was compiled with a newer version of the compiler");
1256 else if (err_code
== ___MODULE_ALREADY_LOADED_ERR
)
1257 append_charstring (buf
, &pos
, "Can't load a given object file more than once");
1258 else if (err_code
== ___DYNAMIC_LOADING_NOT_AVAILABLE_ERR
)
1259 append_charstring (buf
, &pos
, "Dynamic loading is not available on this platform");
1260 else if (err_code
== ___DYNAMIC_LOADING_LOOKUP_ERR
)
1261 append_charstring (buf
, &pos
, "The object file did not contain the required function");
1262 else if ((err_code
>= ___STOC_BASE
&& err_code
<= ___STOC_MAX
) ||
1263 (err_code
>= ___CTOS_BASE
&& err_code
<= ___CTOS_MAX
))
1265 int arg_num
, c_type_index
;
1267 if (err_code
<= ___STOC_MAX
)
1269 arg_num
= (err_code
-___STOC_BASE
) & ((1<<7)-1);
1270 c_type_index
= (err_code
-___STOC_BASE
) >> 7;
1275 arg_num
= (err_code
-___CTOS_BASE
) & ((1<<7)-1);
1276 c_type_index
= (err_code
-___CTOS_BASE
) >> 7;
1279 if (arg_num
== ___RETURN_POS
)
1280 append_charstring (buf
, &pos
, "Can't convert result ");
1281 else if (arg_num
== 0)
1282 append_charstring (buf
, &pos
, "Can't convert ");
1288 while (d
< arg_num
/10)
1291 append_charstring (buf
, &pos
, "(Argument ");
1296 digit
[0] = (arg_num
/ d
% 10) + '0';
1297 append_charstring (buf
, &pos
, digit
);
1301 append_charstring (buf
, &pos
, ") Can't convert ");
1303 append_charstring (buf
, &pos
, dir
);
1304 append_charstring (buf
, &pos
, " ");
1305 append_charstring (buf
, &pos
, c_type_name_table
[c_type_index
]);
1308 append_charstring (buf
, &pos
, "Unknown error");
1310 else if (facility
>= ___ERR_CODE_FACILITY_MACOS
)
1312 /* MACOS error code */
1314 append_charstring (buf
, &pos
, "Unknown MACOS error");
1316 else if (facility
>= ___ERR_CODE_FACILITY_ERRNO
)
1318 /* ANSI-C errno error code */
1322 char *msg
= errno_to_string (___ERRNO_FROM_ERR_CODE(err_code
));
1325 msg
= "Unknown error";
1327 append_charstring (buf
, &pos
, msg
);
1331 else if (facility
>= ___ERR_CODE_FACILITY_H_ERRNO
)
1333 /* netdb h_errno error code */
1337 const char *msg
= h_errno_to_string (___H_ERRNO_FROM_ERR_CODE(err_code
));
1340 msg
= "Unknown error";
1342 append_charstring (buf
, &pos
, msg
);
1346 else if (facility
>= ___ERR_CODE_FACILITY_GAI_CODE
)
1348 /* getaddressinfo error code */
1350 #ifdef USE_getaddrinfo
1352 const char *msg
= gai_code_to_string (___GAI_CODE_FROM_ERR_CODE(err_code
));
1355 msg
= "Unknown error";
1357 append_charstring (buf
, &pos
, msg
);
1363 /* Windows HRESULT error code */
1365 #ifdef USE_FormatMessage
1368 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
|
1369 FORMAT_MESSAGE_MAX_WIDTH_MASK
,
1371 ___WIN32_FROM_ERR_CODE(err_code
),
1372 MAKELANGID(LANG_NEUTRAL
,SUBLANG_DEFAULT
),
1383 if ((e
= ___NONNULLSTRING_to_SCMOBJ
1387 ___CE(___ERR_CODE_CE_SELECT
)))
1388 != ___FIX(___NO_ERR
))
1391 ___release_scmobj (result
);
1397 /*---------------------------------------------------------------------------*/
1399 /* Floating point environment setup. */
1402 ___HIDDEN
void setup_fp ___PVOID
1404 #ifdef USE_get_fpc_csr
1406 /* Enable denormalized numbers. */
1410 csr
.fc_word
= get_fpc_csr ();
1411 csr
.fc_struct
.flush
= 0;
1412 set_fpc_csr (csr
.fc_word
);
1416 #ifdef USE_control87
1420 #define FP_EXC_MASK _MCW_EM
1422 (_EM_INVALID+_EM_ZERODIVIDE+_EM_OVERFLOW+_EM_UNDERFLOW+_EM_INEXACT+_EM_DENORMAL)
1424 _control87 (FP_EXC_CW
, FP_EXC_MASK
);
1428 #define FP_EXC_MASK MCW_EM
1430 (EM_INVALID+EM_ZERODIVIDE+EM_OVERFLOW+EM_UNDERFLOW+EM_INEXACT+EM_DENORMAL)
1432 _control87 (FP_EXC_CW
, FP_EXC_MASK
);
1438 #ifdef USE__FPU_SETCW
1441 (_FPU_MASK_IM+_FPU_MASK_ZM+_FPU_MASK_OM+_FPU_MASK_UM+_FPU_MASK_PM+ \
1442 _FPU_MASK_DM+_FPU_DOUBLE+_FPU_RC_NEAREST)
1444 fpu_control_t cw
= FPU_CW
;
1451 ___HIDDEN
void cleanup_fp ___PVOID
1456 /*---------------------------------------------------------------------------*/
1458 /* Interrupt handling. */
1464 void ___set_signal_handler
1466 void (*handler
) ___P((int sig
),())),
1470 void (*handler
) ___P((int sig
),());)
1472 #ifdef USE_sigaction
1473 struct sigaction act
;
1474 act
.sa_handler
= handler
;
1477 act
.sa_flags
|= SA_INTERRUPT
;
1479 sigemptyset (&act
.sa_mask
);
1480 sigaction (sig
, &act
, 0);
1484 signal (sig
, handler
);
1492 /*---------------------------------------------------------------------------*/
1494 /* Basic OS services module initialization/finalization. */
1497 #ifdef USE_CLASSIC_MACOS
1500 #define test_bit(n,i) ((n)&(1<<(i)))
1503 ___HIDDEN TrapType get_trap_type
1504 ___P((short trap_num
),
1508 /* OS traps start with A0, Tool traps with A8 or AA. */
1510 if (trap_num
& 0x0800)
1517 ___HIDDEN
short nb_toolbox_traps ___PVOID
1519 /* InitGraf (trap $A86E) is always implemented. */
1521 if (NGetTrapAddress (0xA86E, ToolTrap
) == NGetTrapAddress (0xAA6E, ToolTrap
))
1528 ___HIDDEN ___BOOL trap_exists
1529 ___P((short trap_num
),
1533 TrapType typ
= get_trap_type (trap_num
);
1534 if ((typ
== ToolTrap
) && ((trap_num
&= 0x07FF) >= nb_toolbox_traps ()))
1536 return (NGetTrapAddress (_Unimplemented
, ToolTrap
) !=
1537 NGetTrapAddress (trap_num
, typ
));
1544 ___SCMOBJ ___setup_base_module ___PVOID
1546 if (___base_mod
.refcount
== 0)
1548 #ifdef USE_CLASSIC_MACOS
1552 ___base_mod
.has_GetUTCDateTime
= trap_exists (_UTCDateTime
);
1553 ___base_mod
.has_GetDateTime
= trap_exists (_GetDateTime
);
1554 ___base_mod
.has_ReadLocation
= trap_exists (_ReadLocation
);
1555 ___base_mod
.has_Delay
= trap_exists (_Delay
);
1556 ___base_mod
.has_IdleUpdate
= trap_exists (_IdleUpdate
);
1557 ___base_mod
.has_WaitNextEvent
= trap_exists (_WaitNextEvent
);
1558 ___base_mod
.has_OSDispatch
= trap_exists (_OSDispatch
);
1560 ___base_mod
.has_FindFolder
=
1561 (Gestalt (gestaltFindFolderAttr
, &response
) == noErr
&&
1562 test_bit (response
, gestaltFindFolderPresent
));
1564 ___base_mod
.has_AliasMgr
=
1565 (Gestalt (gestaltAliasMgrAttr
, &response
) == noErr
&&
1566 test_bit (response
, gestaltAliasMgrPresent
));
1568 ___base_mod
.has_AppleEvents
=
1569 (Gestalt (gestaltAppleEventsAttr
, &response
) == noErr
&&
1570 test_bit (response
, gestaltAppleEventsPresent
));
1576 ___base_mod
.debug
= NULL
;
1580 ___base_mod
.debug
= ___fopen ("console", "w");
1582 ___base_mod
.debug
= ___fopen ("/dev/console", "w");
1587 ___base_mod
.debug
= ___fopen ("con:", "w");
1590 if (___base_mod
.debug
== NULL
)
1591 ___base_mod
.debug
= ___stderr
;
1593 ___printf ("*** START OF DEBUGGING TRACES\n");
1595 ___base_mod
.alloc_mem_calls
= 0;
1596 ___base_mod
.free_mem_calls
= 0;
1603 ___base_mod
.refcount
++;
1605 return ___FIX(___NO_ERR
);
1609 void ___cleanup_base_module ___PVOID
1611 if (--___base_mod
.refcount
== 0)
1617 if (___base_mod
.alloc_mem_calls
!= ___base_mod
.free_mem_calls
)
1619 ___printf ("*** MEMORY LEAK: alloc_mem_calls = %ld free_mem_calls = %ld\n",
1620 ___base_mod
.alloc_mem_calls
,
1621 ___base_mod
.free_mem_calls
);
1624 if (___base_mod
.debug
!= ___stdout
)
1625 ___fclose (___base_mod
.debug
);
1632 /*---------------------------------------------------------------------------*/