errno.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /*
  2. * Part of Scheme 48 1.9. See file COPYING for notices and license.
  3. *
  4. * Authors: Mike Sperber, Will Noble
  5. */
  6. /*
  7. * Scheme 48/POSIX errno mapping
  8. * (largely copied & renamed from the signal mapping in proc.c)
  9. */
  10. #include <stdio.h>
  11. #include <errno.h>
  12. #include <unistd.h>
  13. #include <stdlib.h>
  14. #include "scheme48.h"
  15. /*
  16. * Mapping from our `canonical' errno numbers to the local OS's
  17. * numbers. To avoid having to manually keep the values here in sync
  18. * with the NAMED-ERRNOS finite record type, we generate the values
  19. * using a Scheme program.
  20. */
  21. static int errno_map[] = {
  22. #include "s48_errno.h"
  23. };
  24. extern void s48_init_posix_errno(void);
  25. static s48_ref_t posix_initialize_named_errnos(s48_call_t call);
  26. /*
  27. * Vector of Scheme errno objects imported from Scheme.
  28. */
  29. static s48_ref_t posix_errnos_vector_binding;
  30. /*
  31. * Install all exported functions in Scheme48.
  32. */
  33. void
  34. s48_init_posix_errno(void)
  35. {
  36. S48_EXPORT_FUNCTION(posix_initialize_named_errnos);
  37. posix_errnos_vector_binding =
  38. s48_get_imported_binding_2("posix-errnos-vector");
  39. }
  40. static s48_ref_t
  41. posix_initialize_named_errnos(s48_call_t call)
  42. {
  43. int i, length;
  44. s48_ref_t named_errnos;
  45. s48_shared_binding_check_2(call, posix_errnos_vector_binding);
  46. named_errnos = s48_shared_binding_ref_2(call, posix_errnos_vector_binding);
  47. if(! s48_vector_p_2(call, named_errnos))
  48. s48_assertion_violation_2(call,
  49. "posix_initialize_named_errnos", "not a vector", 1,
  50. named_errnos);
  51. length = s48_unsafe_vector_length_2(call, named_errnos);
  52. for(i = 0; i < length; i++) {
  53. s48_ref_t named_errno = s48_unsafe_vector_ref_2(call, named_errnos, i);
  54. int canonical = s48_extract_long_2(call, s48_unsafe_record_ref_2(call, named_errno, 1));
  55. int c_errno = errno_map[canonical];
  56. s48_ref_t scm_errno = (c_errno == -1) ?
  57. s48_false_2(call) :
  58. s48_enter_long_2(call, c_errno);
  59. s48_unsafe_record_set_2(call, named_errno, 2, scm_errno); }
  60. return s48_unspecific_2(call);
  61. }