XenevaOS
Loading...
Searching...
No Matches
err.h
Go to the documentation of this file.
1#ifndef __LINUX_ERR_H__
2#define __LINUX_ERR_H__
3
4/*
5 * DCL <linux/err.h> -- the IS_ERR/ERR_PTR family.
6 *
7 * These are load-bearing for tty_io.c, which is written in the style of "call,
8 * then ask whether the answer was a pointer or an error":
9 *
10 * tty = tty_open_by_driver(device, filp);
11 * if (IS_ERR(tty)) {
12 * retval = PTR_ERR(tty);
13 * if (retval != -EAGAIN || signal_pending(current))
14 * return retval;
15 * }
16 *
17 * The trick is that a 4096-entry errno space sits at the very top of the
18 * address space, so any value in -1..-4095 can be passed through a void*
19 * without ever being dereferenced -- IS_ERR() is a range check, not a NULL
20 * check. <linux/kernel.h> already carries IS_ERR_VALUE() (kernel.h:122); what
21 * was missing was everything built on it, which is why a ported file that only
22 * ever says `IS_ERR(p)` failed to compile before this header existed.
23 *
24 * ERR_CAST() and ERR_OR_PTR() are included because tty_io.c and serial_core.c
25 * both use them to move an error across a function boundary without
26 * converting it to a long and back.
27 */
28
29#include <linux/kernel.h> /* MAX_ERRNO, IS_ERR_VALUE, uintptr_t */
30
31/*
32 * <linux/fs.h> is pulled in here, deliberately, and the reason is not visible
33 * from either file on its own. fs.h defines ERR_PTR/PTR_ERR/IS_ERR *without*
34 * #ifndef guards (fs.h:173-175) because the helper they are built on --
35 * dcl_is_err() -- is a static inline that lives there. err.h was written to
36 * provide the same three, also guarded, which looked harmless and was not: a
37 * translation unit that reached err.h first got one spelling, and then a
38 * -Wmacro-redefined the moment fs.h arrived with the other. DCL/tty_buffer.c
39 * does exactly that -- <linux/errno.h> at line 7, <linux/tty.h> (-> fs.h) at
40 * line 9 -- and the two spellings are close enough to be a trap:
41 * `((void*)(long)(err))` vs `((void*)((long)(err)))`, and
42 * `IS_ERR_VALUE((unsigned long)(ptr))` vs `dcl_is_err(ptr)`.
43 *
44 * Including fs.h first makes fs.h's definitions the ones that land and the
45 * guarded ones below skip. One definition of IS_ERR in the tree instead of
46 * two that agree today.
47 */
48#include <linux/fs.h>
49
50#ifndef ERR_PTR
51#define ERR_PTR(err) ((void*)(long)(err))
52#endif
53
54#ifndef PTR_ERR
55#define PTR_ERR(ptr) ((long)(ptr))
56#endif
57
58#ifndef IS_ERR
59#define IS_ERR(ptr) IS_ERR_VALUE((unsigned long)(ptr))
60#endif
61
62#ifndef IS_ERR_OR_NULL
63#define IS_ERR_OR_NULL(ptr) (!(ptr) || IS_ERR(ptr))
64#endif
65
66#ifndef IS_ERR_OR_ZERO
67#define IS_ERR_OR_ZERO(ptr) (IS_ERR(ptr) ? PTR_ERR(ptr) : 0)
68#endif
69
70#ifndef ERR_CAST
71#define ERR_CAST(ptr) ((void*)(ptr))
72#endif
73
74#ifndef PTR_ERR_OR_NULL
75#define PTR_ERR_OR_NULL(ptr) (IS_ERR(ptr) ? PTR_ERR(ptr) : 0)
76#endif
77
78#endif /* __LINUX_ERR_H__ */