This file is indexed.

/usr/include/nih/error.h is in libnih-dev 1.0.3-4.3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
/* libnih
 *
 * Copyright © 2009 Scott James Remnant <scott@netsplit.com>.
 * Copyright © 2009 Canonical Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2, as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifndef NIH_ERROR_H
#define NIH_ERROR_H

/**
 * Many functions in libnih use these functions to report information about
 * errors, those that don't use the ordinary errno mechnism which can
 * also be reported within this framework.
 *
 * Errors are raised as NihError structures, kept globally.  Only one error
 * may be active at any one time, raising an error when another is already
 * raised will result in an assertion.
 *
 * Errors are raised with the nih_error_raise() or nih_error_raise_printf()
 * functions, passing the error number and a human-readable messages.
 *
 * System errors can be raised with nih_error_raise_system(), and both
 * caught errors and self-allocated errors can be raised with
 * nih_error_raise_error().
 *
 * You then report the error condition through your return value, or some
 * other stack-based method.
 *
 * A higher function that wishes to handle the error calls nih_error_get()
 * to retrieve it, it's an error to do so if you do not know that an error
 * is pending.  This returns the currently raised error structure.
 *
 * To clear the error, it should be freed with nih_free().  To return the
 * error from your own function, simply don't free it.
 *
 * Errors may be partitioned using contexts, a new context is pushed with
 * nih_error_push_context(); any errors raised are now stored in this
 * context and any previous raised errors are hidden from view.  The context
 * can be popped again with nih_error_pop_context() provided that any raised
 * error has been dealt with.  The previously hidden raised errors are now
 * visible again.
 *
 * To raise an error from one context, into another, you can't simply call
 * nih_error_get() before nih_error_pop_context() since the latter will
 * assert because of the unfreed error.  Instead nih_error_steal() may be
 * used which returns the error as nih_error_get() does but also removes
 * it from the context.
 *
 * nih_error_steal() may also be used to stash errors before trying an
 * alternate code path.
 **/

#include <nih/macros.h>

#include <errno.h>
#include <string.h>


/**
 * NihError:
 * @filename: filename where the error was raised,
 * @line: line number of @filename where the error was raised,
 * @function: function name the error was raised within,
 * @number: numeric identifier,
 * @message: human-readable message.
 *
 * This structure represents an error, defining the error @number for
 * programmers to capture and handle them and a human-readable @message
 * that should be pre-translated.
 *
 * The structure is allocated when an error occurs, and only one structure
 * may exist in one context at a time; when another error is raised, the
 * existing error, if any, is freed.
 *
 * You may also use this structure as the header for more complicated error
 * objects, in which case do not worry about setting @filename, @line or
 * @function since these are set when you call nih_error_raise_error(); the
 * correct way to do this is to place the macro NIH_ERROR_MEMBERS at the
 * front of your structure, rather than an NihError named member - this
 * makes code that uses your custom error a little easier.
 **/
typedef struct nih_error {
#define NIH_ERROR_MEMBERS			\
	const char *filename;			\
	int         line;			\
	const char *function;			\
						\
	int         number;			\
	const char *message;

	NIH_ERROR_MEMBERS
} NihError;


/**
 * nih_error_raise:
 * @number: numeric identifier,
 * @message: human-readable message.
 *
 * Raises an error with the given details in the current error context,
 * if an unhandled error already exists then an error message is emmitted
 * through the logging system; you should try to avoid this.
 *
 * @message should be a static string, as it will not be freed when the
 * error object is.
 **/
#define nih_error_raise(number, message) \
	_nih_error_raise (__FILE__, __LINE__, __FUNCTION__, number, message)

/**
 * nih_error_raise_printf:
 * @number: numeric identifier,
 * @format: format string for human-readable message.
 *
 * Raises an error with the given details in the current error context,
 * if an unhandled error already exists then an error message is emmitted
 * through the logging system; you should try to avoid this.
 *
 * The human-readable message for the error is parsed according to @format,
 * and allocated as a child of the error object so that it is freed.
 **/
#define nih_error_raise_printf(number, format, ...) \
	_nih_error_raise_printf (__FILE__, __LINE__, __FUNCTION__, \
				 number, format, __VA_ARGS__)

/**
 * nih_error_raise_system:
 *
 * Raises an error with details taken from the current value of errno,
 * if an unhandled error already exists then an error message is emmitted
 * through the logging system; you should try to avoid this.
 **/
#define nih_error_raise_system() \
	_nih_error_raise_system (__FILE__, __LINE__, __FUNCTION__)

/**
 * nih_error_raise_no_memory:
 *
 * Raises an ENOMEM system error, if an unhandled error already exists then
 * an error message is emitted through the logging system; you should try
 * to avoid this.
 **/
#define nih_error_raise_no_memory()				\
	_nih_error_raise (__FILE__, __LINE__, __FUNCTION__,	\
			  ENOMEM, strerror (ENOMEM))

/**
 * nih_error_raise_error:
 * @error: existing object to raise.
 *
 * Raises the existing error object in the current error context,
 * if an unhandled error already exists then an error message is emmitted
 * through the logging system; you should try to avoid this.
 *
 * This is normally used to raise a taken error that has not been handled,
 * or to raise a custom error object.
 *
 * The destructor of @error will be overwritten so that the context can
 * be cleared when the error is freed.
 **/
#define nih_error_raise_error(error) \
	_nih_error_raise_error (__FILE__, __LINE__, __FUNCTION__, error)


/**
 * nih_return_error:
 * @retval: return value for function,
 * @number: numeric identifier,
 * @message: human-readable message.
 *
 * Raises an error with the given details in the current error context,
 * if an unhandled error already exists then an error message is emmitted
 * through the logging system; you should try to avoid this.
 *
 * Will return from the current function with @retval, which may be left
 * empty to return from a void function.
 **/
#define nih_return_error(retval, number,  message)			\
	do {								\
		nih_error_raise (number, message);			\
		return retval;						\
	} while (0)

/**
 * nih_return_system_error:
 * @retval: return value for function.
 *
 * Raises an error with details taken from the current value of errno,
 * if an unhandled error already exists then an error message is emmitted
 * through the logging system; you should try to avoid this.
 *
 * Will return from the current function with @retval, which may be left
 * empty to return from a void function.
 **/
#define nih_return_system_error(retval)					\
	do {								\
		nih_error_raise_system ();				\
		return retval;						\
	} while (0)

/**
 * nih_return_no_memory_error:
 * @retval: return value for function.
 *
 * Raises an ENOMEM system error, if an unhandled error already exists then
 * an error message is emitted through the logging system; you should try
 * to avoid this.
 *
 * Will return from the current function with @retval, which may be left
 * empty to return from a void function.
 **/
#define nih_return_no_memory_error(retval)				\
	do {								\
		nih_error_raise_no_memory ();				\
		return retval;						\
	} while (0)


/**
 * NIH_SHOULD:
 * @_e: C expression.
 *
 * Repeats the expression @_e until it either yields a true value, or
 * raises an error other than ENOMEM.
 *
 * This can only be used when the expression always raises an error if
 * it does not yield a true value.
 *
 * The raised error remains raised and should be dealt with following
 * this function, thus you should store the value of the expression so you
 * know whether or not an error occurred.
 *
 * Returns: value of expression @_e which will be evaluated as many times
 * as necessary to become true.
 **/
#define NIH_SHOULD(_e)							\
	({								\
		typeof (_e) __ret;					\
		while (! (__ret = (_e))) {				\
			NihError *_nih_should_err;			\
									\
			_nih_should_err = nih_error_get ();		\
			if (_nih_should_err->number == ENOMEM) {	\
				nih_free (_nih_should_err);		\
			} else {					\
				break;					\
			}						\
		}							\
		__ret;							\
	})


NIH_BEGIN_EXTERN

void      nih_error_init          (void);

void      _nih_error_raise        (const char *filename, int line,
				   const char *function,
				   int number, const char *message);
void      _nih_error_raise_printf (const char *filename, int line,
				   const char *function,
				   int number, const char *format, ...)
	__attribute__ ((format (printf, 5, 6)));
void      _nih_error_raise_system (const char *filename, int line,
				   const char *function);
void      _nih_error_raise_error  (const char *filename, int line,
				   const char *function,
				   NihError *error);

NihError *nih_error_get           (void)
	__attribute__ ((warn_unused_result));
NihError *nih_error_steal         (void)
	__attribute__ ((warn_unused_result));

void      nih_error_push_context  (void);
void      nih_error_pop_context   (void);

NIH_END_EXTERN

#endif /* NIH_ERROR_H */