2 * Common/shared macros and routines.
4 * This file contains macros of the form
6 * mph_return_if_TYPE_overflow(val);
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).
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.
18 * See the typedefs for type size assumptions. These typedefs *must* be kept
19 * in sync with the types used in Mono.Posix.dll.
22 * http://developer.apple.com/documentation/Darwin/Reference/ManPages/
30 #include <limits.h> /* LONG_MAX, ULONG_MAX */
31 #include <errno.h> /* for ERANGE */
32 #include <glib.h> /* for g* types, etc. */
35 #include <stdint.h> /* for SIZE_MAX */
38 #if __APPLE__ || __BSD__ || __FreeBSD__
42 #ifdef HAVE_VISIBILITY_HIDDEN
43 #define MPH_INTERNAL __attribute__((visibility("hidden")))
48 #if defined (PLATFORM_WIN32) && !defined (EOVERFLOW)
50 #endif /* def PLATFORM_WIN32 && ndef EOVERFLOW */
52 #if !defined (PLATFORM_WIN32)
55 * Solaris doesn't define these BSD values, and if they're not present then
56 * map.c:Mono_Posix_FromSeekFlags() breaks badly; see:
57 * http://bugzilla.gnome.org/show_bug.cgi?id=370081
61 #define L_SET SEEK_SET
62 #endif /* ndef L_SET */
65 #define L_INCR SEEK_CUR
66 #endif /* ndef L_INCR */
69 #define L_XTND SEEK_END
70 #endif /* ndef L_XTND */
72 #endif /* ndef PLATFORM_WIN32 */
74 typedef gint64 mph_blkcnt_t;
75 typedef gint64 mph_blksize_t;
76 typedef guint64 mph_dev_t;
77 typedef guint64 mph_ino_t;
78 typedef guint64 mph_nlink_t;
79 typedef gint64 mph_off_t;
80 typedef guint64 mph_size_t;
81 typedef gint64 mph_ssize_t;
82 typedef gint32 mph_pid_t;
83 typedef guint32 mph_gid_t;
84 typedef guint32 mph_uid_t;
85 typedef gint64 mph_time_t;
86 typedef gint64 mph_clock_t;
87 typedef guint64 mph_fsblkcnt_t;
88 typedef guint64 mph_fsfilcnt_t;
90 /* Some versions of OS X don't define these typedefs, needed by map.c */
92 typedef mph_blkcnt_t blkcnt_t;
95 #ifndef HAVE_BLKSIZE_T
96 typedef mph_blksize_t blksize_t;
99 #ifndef HAVE_SUSECONDS_T
100 typedef gint64 suseconds_t;
103 #ifdef HAVE_LARGE_FILE_SUPPORT
104 #define MPH_OFF_T_MAX G_MAXINT64
105 #define MPH_OFF_T_MIN G_MININT64
107 #define MPH_OFF_T_MAX G_MAXINT32
108 #define MPH_OFF_T_MIN G_MININT32
112 #define MPH_SIZE_T_MAX SIZE_MAX
113 #elif SIZEOF_SIZE_T == 8
114 #define MPH_SIZE_T_MAX G_MAXUINT64
115 #elif SIZEOF_SIZE_T == 4
116 #define MPH_SIZE_T_MAX G_MAXUINT32
118 #error "sizeof(size_t) is unknown!"
121 #define _mph_return_val_if_cb_(val, ret, cb) G_STMT_START{ \
127 #define mph_have_long_overflow(var) ((var) > LONG_MAX || (var) < LONG_MIN)
129 #define mph_return_val_if_long_overflow(var, ret) \
130 _mph_return_val_if_cb_(var, ret, mph_have_long_overflow)
132 #define mph_return_if_long_overflow(var) mph_return_val_if_long_overflow(var, -1)
134 #define mph_have_ulong_overflow(var) ((var) > ULONG_MAX)
136 #define mph_return_val_if_ulong_overflow(var, ret) \
137 _mph_return_val_if_cb_(var, ret, mph_have_ulong_overflow)
139 #define mph_return_if_ulong_overflow(var) mph_return_val_if_ulong_overflow(var, -1)
141 #define mph_have_size_t_overflow(var) ((var) > MPH_SIZE_T_MAX)
143 #define mph_return_val_if_size_t_overflow(var, ret) \
144 _mph_return_val_if_cb_(var, ret, mph_have_size_t_overflow)
146 #define mph_return_val_if_ssize_t_overflow(var, ret) \
147 _mph_return_val_if_cb_(var, ret, mph_have_long_overflow)
149 #define mph_return_if_size_t_overflow(var) mph_return_val_if_size_t_overflow(var, -1)
151 #define mph_return_if_ssize_t_overflow(var) mph_return_val_if_ssize_t_overflow(var, -1)
153 #define mph_have_off_t_overflow(var) \
154 (((var) < MPH_OFF_T_MIN) || ((var) > MPH_OFF_T_MAX))
156 #define mph_return_val_if_off_t_overflow(var, ret) \
157 _mph_return_val_if_cb_(var, ret, mph_have_off_t_overflow)
159 #define mph_return_if_off_t_overflow(var) mph_return_val_if_size_t_overflow(var, -1)
161 #define mph_return_if_time_t_overflow(var) mph_return_if_long_overflow(var)
164 * Helper function for functions which use ERANGE (such as getpwnam_r and
165 * getgrnam_r). These functions accept buffers which are dynamically
166 * allocated so that they're only as large as necessary. However, Linux and
167 * Mac OS X differ on how to signal an error value.
169 * Linux returns the error value directly, while Mac OS X is more traditional,
170 * returning -1 and setting errno accordingly.
172 * Unify the checking in one place.
175 recheck_range (int ret)
180 return errno == ERANGE;
185 _mph_copy_structure_strings (
186 void *to, const size_t *to_offsets,
187 const void *from, const size_t *from_offsets,
190 #endif /* ndef INC_mph_H */