Welcome to mirror list, hosted at ThFree Co, Russian Federation.

mph.h « support - github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 49a5e9781fcfd121a5998b6adf55b6bc79ad45ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
 * Common/shared macros and routines.
 *
 * This file contains macros of the form
 *
 *   mph_return_if_TYPE_overflow(val);
 *
 * Which tests `val' for a TYPE underflow/overflow (that is, is `val' within
 * the range for TYPE?).  If `val' can't fit in TYPE, errno is set to
 * EOVERFLOW, and `return -1' is executed (which is why it's a macro).
 *
 * Assumptions:
 *
 * I'm working from GLibc, so that's the basis for my assumptions.  They may
 * not be completely portable, in which case I'll need to fix my assumptions.
 * :-(
 *
 * See the typedefs for type size assumptions.  These typedefs *must* be kept
 * in sync with the types used in Mono.Posix.dll.
 */

#ifndef INC_mph_H
#define INC_mph_H

#include <config.h>

#include <limits.h>             /* LONG_MAX, ULONG_MAX */
#include <errno.h>              /* for ERANGE */
#include <glib/gtypes.h>        /* for g* types, etc. */

#ifdef HAVE_STDINT_H
#include <stdint.h>             /* for SIZE_MAX */
#endif

#if __APPLE__ || __BSD__
#define MPH_ON_BSD
#endif

typedef    gint64 mph_blkcnt_t;
typedef    gint64 mph_blksize_t;
typedef   guint64 mph_dev_t;
typedef   guint64 mph_ino_t;
typedef   guint64 mph_nlink_t;
typedef    gint64 mph_off_t;
typedef   guint64 mph_size_t;
typedef    gint64 mph_ssize_t;
typedef    gint32 mph_pid_t;
typedef   guint32 mph_gid_t;
typedef   guint32 mph_uid_t;
typedef    gint64 mph_time_t;
typedef    gint64 mph_clock_t;

#ifdef HAVE_LARGE_FILE_SUPPORT
#define MPH_OFF_T_MAX G_MAXINT64
#define MPH_OFF_T_MIN G_MININT64
#else
#define MPH_OFF_T_MAX G_MAXINT32
#define MPH_OFF_T_MIN G_MININT32
#endif

#ifdef SIZE_MAX
#define MPH_SIZE_T_MAX SIZE_MAX
#elif SIZEOF_SIZE_T == 8
#define MPH_SIZE_T_MAX  G_MAXUINT64
#elif SIZEOF_SIZE_T == 4
#define MPH_SIZE_T_MAX  G_MAXUINT32
#else
#error "sizeof(size_t) is unknown!"
#endif

#define _mph_return_val_if_cb_(val, ret, cb) G_STMT_START{ \
	if (cb (val)) { \
		errno = EOVERFLOW; \
		return ret; \
	}}G_STMT_END

#define mph_have_long_overflow(var) ((var) > LONG_MAX || (var) < LONG_MIN)

#define mph_return_val_if_long_overflow(var, ret) \
	_mph_return_val_if_cb_(var, ret, mph_have_long_overflow)

#define mph_return_if_long_overflow(var) mph_return_val_if_long_overflow(var, -1)

#define mph_have_ulong_overflow(var) ((var) > ULONG_MAX)

#define mph_return_val_if_ulong_overflow(var, ret) \
	_mph_return_val_if_cb_(var, ret, mph_have_ulong_overflow)

#define mph_return_if_ulong_overflow(var) mph_return_val_if_ulong_overflow(var, -1)

#define mph_have_size_t_overflow(var) ((var) > MPH_SIZE_T_MAX)

#define mph_return_val_if_size_t_overflow(var, ret) \
	_mph_return_val_if_cb_(var, ret, mph_have_size_t_overflow)

#define mph_return_if_size_t_overflow(var) mph_return_val_if_size_t_overflow(var, -1)

#define mph_have_off_t_overflow(var) \
	(((var) < MPH_OFF_T_MIN) || ((var) > MPH_OFF_T_MAX))

#define mph_return_val_if_off_t_overflow(var, ret) \
	_mph_return_val_if_cb_(var, ret, mph_have_off_t_overflow)

#define mph_return_if_off_t_overflow(var) mph_return_val_if_size_t_overflow(var, -1)

#define mph_return_if_time_t_overflow(var) mph_return_if_long_overflow(var)

/*
 * Helper function for functions which use ERANGE (such as getpwnam_r and
 * getgrnam_r).  These functions accept buffers which are dynamically
 * allocated so that they're only as large as necessary.  However, Linux and
 * Mac OS X differ on how to signal an error value.
 *
 * Linux returns the error value directly, while Mac OS X is more traditional,
 * returning -1 and setting errno accordingly.
 *
 * Unify the checking in one place.
 */
static inline int
recheck_range (int ret)
{
	if (ret == ERANGE)
		return 1;
	if (ret == -1)
		return errno == ERANGE;
	return 0;
}

#endif /* ndef INC_mph_H */

/*
 * vim: noexpandtab
 */