1/*
2 Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
3
4 This file is part of libzmq, the ZeroMQ core engine in C++.
5
6 libzmq is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License (LGPL) as published
8 by the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 As a special exception, the Contributors give you permission to link
12 this library with independent modules to produce an executable,
13 regardless of the license terms of these independent modules, and to
14 copy and distribute the resulting executable under terms of your choice,
15 provided that you also meet, for each linked independent module, the
16 terms and conditions of the license of that module. An independent
17 module is a module which is not derived from or based on this library.
18 If you modify this library, you must extend this exception to your
19 version of the library.
20
21 libzmq is distributed in the hope that it will be useful, but WITHOUT
22 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
24 License for more details.
25
26 You should have received a copy of the GNU Lesser General Public License
27 along with this program. If not, see <http://www.gnu.org/licenses/>.
28*/
29
30#ifndef __ZMQ_ERR_HPP_INCLUDED__
31#define __ZMQ_ERR_HPP_INCLUDED__
32
33#include <assert.h>
34#if defined _WIN32_WCE
35#include "..\builds\msvc\errno.hpp"
36#else
37#include <errno.h>
38#endif
39#include <string.h>
40#include <stdlib.h>
41#include <stdio.h>
42
43#ifndef ZMQ_HAVE_WINDOWS
44#include <netdb.h>
45#endif
46
47#include "likely.hpp"
48
49// 0MQ-specific error codes are defined in zmq.h
50
51// EPROTO is not used by OpenBSD and maybe other platforms.
52#ifndef EPROTO
53#define EPROTO 0
54#endif
55
56namespace zmq
57{
58const char *errno_to_string (int errno_);
59#if defined __clang__
60#if __has_feature(attribute_analyzer_noreturn)
61void zmq_abort (const char *errmsg_) __attribute__ ((analyzer_noreturn));
62#endif
63#elif defined __MSCVER__
64__declspec(noreturn) void zmq_abort (const char *errmsg_);
65#else
66void zmq_abort (const char *errmsg_);
67#endif
68void print_backtrace ();
69}
70
71#ifdef ZMQ_HAVE_WINDOWS
72
73namespace zmq
74{
75const char *wsa_error ();
76const char *
77wsa_error_no (int no_,
78 const char *wsae_wouldblock_string_ = "Operation would block");
79void win_error (char *buffer_, size_t buffer_size_);
80int wsa_error_to_errno (int errcode_);
81}
82
83// Provides convenient way to check WSA-style errors on Windows.
84#define wsa_assert(x) \
85 do { \
86 if (unlikely (!(x))) { \
87 const char *errstr = zmq::wsa_error (); \
88 if (errstr != NULL) { \
89 fprintf (stderr, "Assertion failed: %s [%i] (%s:%d)\n", \
90 errstr, WSAGetLastError (), __FILE__, __LINE__); \
91 fflush (stderr); \
92 zmq::zmq_abort (errstr); \
93 } \
94 } \
95 } while (false)
96
97// Provides convenient way to assert on WSA-style errors on Windows.
98#define wsa_assert_no(no) \
99 do { \
100 const char *errstr = zmq::wsa_error_no (no); \
101 if (errstr != NULL) { \
102 fprintf (stderr, "Assertion failed: %s (%s:%d)\n", errstr, \
103 __FILE__, __LINE__); \
104 fflush (stderr); \
105 zmq::zmq_abort (errstr); \
106 } \
107 } while (false)
108
109// Provides convenient way to check GetLastError-style errors on Windows.
110#define win_assert(x) \
111 do { \
112 if (unlikely (!(x))) { \
113 char errstr[256]; \
114 zmq::win_error (errstr, 256); \
115 fprintf (stderr, "Assertion failed: %s (%s:%d)\n", errstr, \
116 __FILE__, __LINE__); \
117 fflush (stderr); \
118 zmq::zmq_abort (errstr); \
119 } \
120 } while (false)
121
122#endif
123
124// This macro works in exactly the same way as the normal assert. It is used
125// in its stead because standard assert on Win32 in broken - it prints nothing
126// when used within the scope of JNI library.
127#define zmq_assert(x) \
128 do { \
129 if (unlikely (!(x))) { \
130 fprintf (stderr, "Assertion failed: %s (%s:%d)\n", #x, __FILE__, \
131 __LINE__); \
132 fflush (stderr); \
133 zmq::zmq_abort (#x); \
134 } \
135 } while (false)
136
137// Provides convenient way to check for errno-style errors.
138#define errno_assert(x) \
139 do { \
140 if (unlikely (!(x))) { \
141 const char *errstr = strerror (errno); \
142 fprintf (stderr, "%s (%s:%d)\n", errstr, __FILE__, __LINE__); \
143 fflush (stderr); \
144 zmq::zmq_abort (errstr); \
145 } \
146 } while (false)
147
148// Provides convenient way to check for POSIX errors.
149#define posix_assert(x) \
150 do { \
151 if (unlikely (x)) { \
152 const char *errstr = strerror (x); \
153 fprintf (stderr, "%s (%s:%d)\n", errstr, __FILE__, __LINE__); \
154 fflush (stderr); \
155 zmq::zmq_abort (errstr); \
156 } \
157 } while (false)
158
159// Provides convenient way to check for errors from getaddrinfo.
160#define gai_assert(x) \
161 do { \
162 if (unlikely (x)) { \
163 const char *errstr = gai_strerror (x); \
164 fprintf (stderr, "%s (%s:%d)\n", errstr, __FILE__, __LINE__); \
165 fflush (stderr); \
166 zmq::zmq_abort (errstr); \
167 } \
168 } while (false)
169
170// Provides convenient way to check whether memory allocation have succeeded.
171#define alloc_assert(x) \
172 do { \
173 if (unlikely (!x)) { \
174 fprintf (stderr, "FATAL ERROR: OUT OF MEMORY (%s:%d)\n", __FILE__, \
175 __LINE__); \
176 fflush (stderr); \
177 zmq::zmq_abort ("FATAL ERROR: OUT OF MEMORY"); \
178 } \
179 } while (false)
180
181#endif
182