-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathstderr.h
172 lines (145 loc) · 7.06 KB
/
stderr.h
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
/*
@(#)File: $RCSfile: stderr.h,v $
@(#)Version: $Revision: 10.16 $
@(#)Last changed: $Date: 2022/04/07 17:47:31 $
@(#)Purpose: Header file for standard error functions
@(#)Author: J Leffler
@(#)Copyright: (C) JLSS 1989-2022
@(#)Product: SCC Version 8.0.3 (2022-05-30)
*/
#if !defined(STDERR_H)
#define STDERR_H
#if defined(MAIN_PROGRAM)
#if !defined(lint)
/* Prevent over-aggressive optimizers from eliminating ID string */
extern const char jlss_id_stderr_h[];
const char jlss_id_stderr_h[] = "@(#)$Id: stderr.h,v 10.16 2022/04/07 17:47:31 jleffler Exp $";
#endif /* lint */
#endif
#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif /* HAVE_CONFIG_H */
#if defined(JLSS_STDERR)
#undef USE_STDERR_FILEDESC
#define USE_STDERR_FILEDESC
#if defined(HAVE_SYSLOG) && defined(HAVE_SYSLOG_H)
#undef USE_STDERR_SYSLOG
#define USE_STDERR_SYSLOG
#endif /* HAVE_SYSLOG && HAVE_SYSLOG_H */
#endif /* JLSS_STDERR */
#include <stdio.h>
#include <stdarg.h>
#if !defined(NORETURN)
#if __STDC_VERSION__ >= 201112L
#define NORETURN _Noreturn
#elif defined(__GNUC__)
#define NORETURN __attribute__((noreturn))
#else
#define NORETURN /* If only */
#endif /* __STDC_VERSION__ || __GNUC__ */
#endif /* NORETURN */
#if !defined(DEPRECATED)
#if defined(__GNUC__)
#define DEPRECATED __attribute__((deprecated))
#else
#define DEPRECATED /* If only */
#endif /* __GNUC__ */
#endif /* DEPRECATED */
#if !defined(PRINTFLIKE)
#if defined(__GNUC__)
#define PRINTFLIKE(n, m) __attribute__((format(printf, n, m)))
#else
#define PRINTFLIKE(n, m) /* If only */
#endif /* __GNUC__ */
#endif /* PRINTFLIKE */
/* -- Definitions for error handling */
enum { ERR_STAT = 1 }; /* Default exit status */
enum { ERR_DEFAULT = 0x0000 }; /* Default flag */
enum { ERR_NOFLUSH = 0x0001 }; /* Do not flush open files */
enum { ERR_EXIT = 0x0004 }; /* Exit -- do not return */
enum { ERR_ABORT = 0x0008 }; /* Abort -- do not return */
enum { ERR_STAMP = 0x0020 }; /* Timestamp messages (whole second) */
enum { ERR_NOARG0 = 0x0040 }; /* Do not print arg0 prefix */
enum { ERR_PID = 0x0080 }; /* Include pid=nnnnn info */
enum { ERR_ERRNO = 0x0100 }; /* Include system error */
enum { ERR_MILLI = 0x0200 }; /* Timestamp messages (millisecond) */
enum { ERR_MICRO = 0x0400 }; /* Timestamp messages (microsecond) */
enum { ERR_NANO = 0x0800 }; /* Timestamp messages (nanosecond) */
#if defined(USE_STDERR_SYSLOG)
/* Definitions related to using syslog */
enum { ERR_LOG_EMERG = 0x01000 }; /* system is unusable */
enum { ERR_LOG_ALERT = 0x02000 }; /* action must be taken immediately */
enum { ERR_LOG_CRIT = 0x04000 }; /* critical conditions */
enum { ERR_LOG_ERR = 0x08000 }; /* error conditions */
enum { ERR_LOG_WARNING = 0x10000 }; /* warning conditions */
enum { ERR_LOG_NOTICE = 0x20000 }; /* normal but significant condition */
enum { ERR_LOG_INFO = 0x40000 }; /* informational */
enum { ERR_LOG_DEBUG = 0x80000 }; /* debug-level messages */
enum { ERR_LOG_LEVEL_HI = ERR_LOG_EMERG|ERR_LOG_ALERT|ERR_LOG_CRIT|ERR_LOG_ERR };
enum { ERR_LOG_LEVEL_LO = ERR_LOG_WARNING|ERR_LOG_NOTICE|ERR_LOG_INFO|ERR_LOG_DEBUG };
enum { ERR_LOG_LEVEL = ERR_LOG_LEVEL_HI|ERR_LOG_LEVEL_LO };
#endif /* USE_STDERR_SYSLOG */
/* -- Standard combinations of flags */
enum { ERR_REM = ERR_DEFAULT };
enum { ERR_ERR = ERR_EXIT };
enum { ERR_ABT = ERR_ABORT };
enum { ERR_LOG = ERR_STAMP|ERR_PID };
enum { ERR_SYSREM = ERR_REM|ERR_ERRNO };
enum { ERR_SYSERR = ERR_ERR|ERR_ERRNO };
/* -- Maximum recorded length of argv[0]; extra is truncated */
enum { ERR_MAXLEN_ARGV0 = 63 };
/* -- Global definitions */
extern const char *err_getarg0(void);
extern void err_setarg0(const char *argv0);
extern FILE *err_stderr(FILE *fp);
extern const char *err_rcs_string(const char *s, char *buffer, size_t buflen);
extern NORETURN void err_abort(const char *format, ...) PRINTFLIKE(1, 2);
extern NORETURN void err_error(const char *format, ...) PRINTFLIKE(1, 2);
extern NORETURN void err_help(const char *use_str, const char *hlp_str);
extern NORETURN void err_helplist(const char *use_str, const char * const *help_list);
extern NORETURN void err_internal(const char *function, const char *format, ...) PRINTFLIKE(2, 3);
extern NORETURN void err_syserr(const char *format, ...) PRINTFLIKE(1, 2);
extern NORETURN void err_syserror(int errnum, const char *format, ...) PRINTFLIKE(2, 3);
extern NORETURN void err_usage(const char *usestr);
extern NORETURN void err_version(const char *program, const char *verinfo);
extern void err_vlogmsg(FILE *fp, int flags, int estat, const char *format, va_list args);
extern void err_logmsg(FILE *fp, int flags, int estat, const char *format, ...) PRINTFLIKE(4, 5);
extern void err_print(int flags, int estat, const char *format, va_list args);
extern void err_printversion(const char *program, const char *verinfo);
extern void err_remark(const char *format, ...) PRINTFLIKE(1, 2);
extern void err_report(int flags, int estat, const char *format, ...) PRINTFLIKE(3, 4);
extern void err_sysrem(const char *format, ...) PRINTFLIKE(1, 2);
extern void err_sysremark(int errnum, const char *format, ...) PRINTFLIKE(2, 3);
extern int err_getlogopts(void); /* Get default log options */
extern int err_setlogopts(int new_opts); /* Set default log options */
/* Time format of NULL sets default format - returns previous format */
extern const char *err_settimeformat(const char *new_fmt);
extern const char *err_gettimeformat(void);
/* Format a possibly multi-line usage message - mostly internal */
extern void err_fmt_usage(size_t buflen, char *buffer, const char *s1);
#if defined(USE_STDERR_FILEDESC)
extern int err_use_fd(int fd); /* Use file descriptor */
#endif /* USE_STDERR_FILEDESC */
#if defined(USE_STDERR_SYSLOG)
/* In case of doubt, use zero for both logopts and facility */
extern int err_use_syslog(int logopts, int facility); /* Configure/use syslog() */
#endif /* USE_STDERR_SYSLOG */
/*
** JL 2003-07-31: Security Note.
** Question: given that err_remark("abc\n") and err_remark1("abc")
** produce the same output, when should you use err_remark1()
** instead of err_remark()?
** Answer 1: trivia - when you can't put the newline in the string.
** Answer 2: security - when the argument contains user input and could,
** therefore, contain conversion specifiers, etc. The code in
** err_remark() does not (and cannot) verify that you have
** passed correct arguments for the conversion specifiers in
** the format string.
** Answer 3: inertia - when migrating code that uses remark().
**
** Generalizing: when you use a function that has 'const char *format'
** in the prototype above, make sure your code is fully in charge of the
** format string to avoid security lapses. Do not allow the user to
** provide that string unless you stringently check it beforehand.
*/
#endif /* STDERR_H */