mph.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. * Common/shared macros and routines.
  3. *
  4. * This file contains macros of the form
  5. *
  6. * mph_return_if_TYPE_overflow(val);
  7. *
  8. * Which tests `val' for a TYPE underflow/overflow (that is, is `val' within
  9. * the range for TYPE?). If `val' can't fit in TYPE, errno is set to
  10. * EOVERFLOW, and `return -1' is executed (which is why it's a macro).
  11. *
  12. * Assumptions:
  13. *
  14. * I'm working from GLibc, so that's the basis for my assumptions. They may
  15. * not be completely portable, in which case I'll need to fix my assumptions.
  16. * :-(
  17. *
  18. * See the typedefs for type size assumptions. These typedefs *must* be kept
  19. * in sync with the types used in Mono.Posix.dll.
  20. *
  21. * See also:
  22. * http://developer.apple.com/documentation/Darwin/Reference/ManPages/
  23. */
  24. #ifndef INC_mph_H
  25. #define INC_mph_H
  26. #include <config.h>
  27. #include <stddef.h> /* offsetof */
  28. #include <limits.h> /* LONG_MAX, ULONG_MAX */
  29. #include <errno.h> /* for ERANGE */
  30. #include <glib.h> /* for g* types, etc. */
  31. #ifdef HAVE_STDINT_H
  32. #include <stdint.h> /* for SIZE_MAX */
  33. #endif
  34. #if __APPLE__ || __BSD__ || __FreeBSD__
  35. #define MPH_ON_BSD
  36. #endif
  37. #ifdef HAVE_VISIBILITY_HIDDEN
  38. #define MPH_INTERNAL __attribute__((visibility("hidden")))
  39. #else
  40. #define MPH_INTERNAL
  41. #endif
  42. #if defined (PLATFORM_WIN32) && !defined (EOVERFLOW)
  43. #define EOVERFLOW 75
  44. #endif /* def PLATFORM_WIN32 && ndef EOVERFLOW */
  45. #if !defined (PLATFORM_WIN32)
  46. /*
  47. * Solaris doesn't define these BSD values, and if they're not present then
  48. * map.c:Mono_Posix_FromSeekFlags() breaks badly; see:
  49. * http://bugzilla.gnome.org/show_bug.cgi?id=370081
  50. */
  51. #ifndef L_SET
  52. #define L_SET SEEK_SET
  53. #endif /* ndef L_SET */
  54. #ifndef L_INCR
  55. #define L_INCR SEEK_CUR
  56. #endif /* ndef L_INCR */
  57. #ifndef L_XTND
  58. #define L_XTND SEEK_END
  59. #endif /* ndef L_XTND */
  60. /*
  61. * XATTR_AUTO is a synonym for 0 within XattrFlags, but most systems don't
  62. * define it. map.c doesn't know that, though, so we ensure that it's defined
  63. * so that the value 0 round-trips through MonoPosixHelper.
  64. */
  65. #ifndef XATTR_AUTO
  66. #define XATTR_AUTO 0
  67. #endif /* ndef XATTR_AUTO */
  68. #endif /* ndef PLATFORM_WIN32 */
  69. typedef gint64 mph_blkcnt_t;
  70. typedef gint64 mph_blksize_t;
  71. typedef guint64 mph_dev_t;
  72. typedef guint64 mph_ino_t;
  73. typedef guint64 mph_nlink_t;
  74. typedef gint64 mph_off_t;
  75. typedef guint64 mph_size_t;
  76. typedef gint64 mph_ssize_t;
  77. typedef gint32 mph_pid_t;
  78. typedef guint32 mph_gid_t;
  79. typedef guint32 mph_uid_t;
  80. typedef gint64 mph_time_t;
  81. typedef gint64 mph_clock_t;
  82. typedef guint64 mph_fsblkcnt_t;
  83. typedef guint64 mph_fsfilcnt_t;
  84. /* Some versions of OS X don't define these typedefs, needed by map.c */
  85. #ifndef HAVE_BLKCNT_T
  86. typedef mph_blkcnt_t blkcnt_t;
  87. #endif
  88. #ifndef HAVE_BLKSIZE_T
  89. typedef mph_blksize_t blksize_t;
  90. #endif
  91. #ifndef HAVE_SUSECONDS_T
  92. typedef gint64 suseconds_t;
  93. #endif
  94. #ifdef HAVE_LARGE_FILE_SUPPORT
  95. #define MPH_OFF_T_MAX G_MAXINT64
  96. #define MPH_OFF_T_MIN G_MININT64
  97. #else
  98. #define MPH_OFF_T_MAX G_MAXINT32
  99. #define MPH_OFF_T_MIN G_MININT32
  100. #endif
  101. #ifdef SIZE_MAX
  102. #define MPH_SIZE_T_MAX SIZE_MAX
  103. #elif SIZEOF_SIZE_T == 8
  104. #define MPH_SIZE_T_MAX G_MAXUINT64
  105. #elif SIZEOF_SIZE_T == 4
  106. #define MPH_SIZE_T_MAX G_MAXUINT32
  107. #else
  108. #error "sizeof(size_t) is unknown!"
  109. #endif
  110. #define _mph_return_val_if_cb_(val, ret, cb) G_STMT_START{ \
  111. if (cb (val)) { \
  112. errno = EOVERFLOW; \
  113. return ret; \
  114. }}G_STMT_END
  115. #define mph_have_long_overflow(var) ((var) > LONG_MAX || (var) < LONG_MIN)
  116. #define mph_return_val_if_long_overflow(var, ret) \
  117. _mph_return_val_if_cb_(var, ret, mph_have_long_overflow)
  118. #define mph_return_if_long_overflow(var) mph_return_val_if_long_overflow(var, -1)
  119. #define mph_have_ulong_overflow(var) ((var) > ULONG_MAX)
  120. #define mph_return_val_if_ulong_overflow(var, ret) \
  121. _mph_return_val_if_cb_(var, ret, mph_have_ulong_overflow)
  122. #define mph_return_if_ulong_overflow(var) mph_return_val_if_ulong_overflow(var, -1)
  123. #define mph_have_size_t_overflow(var) ((var) > MPH_SIZE_T_MAX)
  124. #define mph_return_val_if_size_t_overflow(var, ret) \
  125. _mph_return_val_if_cb_(var, ret, mph_have_size_t_overflow)
  126. #define mph_return_val_if_ssize_t_overflow(var, ret) \
  127. _mph_return_val_if_cb_(var, ret, mph_have_long_overflow)
  128. #define mph_return_if_size_t_overflow(var) mph_return_val_if_size_t_overflow(var, -1)
  129. #define mph_return_if_ssize_t_overflow(var) mph_return_val_if_ssize_t_overflow(var, -1)
  130. #define mph_have_off_t_overflow(var) \
  131. (((var) < MPH_OFF_T_MIN) || ((var) > MPH_OFF_T_MAX))
  132. #define mph_return_val_if_off_t_overflow(var, ret) \
  133. _mph_return_val_if_cb_(var, ret, mph_have_off_t_overflow)
  134. #define mph_return_if_off_t_overflow(var) mph_return_val_if_size_t_overflow(var, -1)
  135. #define mph_return_if_time_t_overflow(var) mph_return_if_long_overflow(var)
  136. #define mph_return_if_val_in_list5(var,a,b,c,d,e) \
  137. do { \
  138. int v = (var); \
  139. if (v == a || v == b || v == c || v == d || v == e) \
  140. return -1; \
  141. } while (0)
  142. /*
  143. * Helper function for functions which use ERANGE (such as getpwnam_r and
  144. * getgrnam_r). These functions accept buffers which are dynamically
  145. * allocated so that they're only as large as necessary. However, Linux and
  146. * Mac OS X differ on how to signal an error value.
  147. *
  148. * Linux returns the error value directly, while Mac OS X is more traditional,
  149. * returning -1 and setting errno accordingly.
  150. *
  151. * Unify the checking in one place.
  152. */
  153. static inline int
  154. recheck_range (int ret)
  155. {
  156. if (ret == ERANGE)
  157. return 1;
  158. if (ret == -1)
  159. return errno == ERANGE;
  160. return 0;
  161. }
  162. typedef unsigned int mph_string_offset_t;
  163. enum {
  164. MPH_STRING_OFFSET_PTR = 0x0,
  165. MPH_STRING_OFFSET_ARRAY = 0x1,
  166. MPH_STRING_OFFSET_MASK = 0x1
  167. };
  168. #define MPH_STRING_OFFSET(type,member,kind) ((offsetof(type,member) << 1) | kind)
  169. MPH_INTERNAL char*
  170. _mph_copy_structure_strings (
  171. void *to, const mph_string_offset_t *to_offsets,
  172. const void *from, const mph_string_offset_t *from_offsets,
  173. size_t num_strings);
  174. #endif /* ndef INC_mph_H */
  175. /*
  176. * vim: noexpandtab
  177. */