1 /* vi: set sw=4 ts=4: */
5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
10 #if ENABLE_FEATURE_SYSLOG
14 #if ENABLE_FEATURE_SYSLOG
15 smallint syslog_level
= LOG_ERR
;
17 smallint logmode
= LOGMODE_STDIO
;
18 const char *msg_eol
= "\n";
20 void FAST_FUNC
bb_verror_msg(const char *s
, va_list p
, const char* strerr
)
23 int applet_len
, strerr_len
, msgeol_len
, used
;
28 if (!s
) /* nomsg[_and_die] uses NULL fmt */
29 s
= ""; /* some libc don't like printf(NULL) */
31 used
= vasprintf(&msg
, s
, p
);
35 /* This is ugly and costs +60 bytes compared to multiple
36 * fprintf's, but is guaranteed to do a single write.
37 * This is needed for e.g. httpd logging, when multiple
38 * children can produce log messages simultaneously. */
40 applet_len
= strlen(applet_name
) + 2; /* "applet: " */
41 strerr_len
= strerr
? strlen(strerr
) : 0;
42 msgeol_len
= strlen(msg_eol
);
43 /* can't use xrealloc: it calls error_msg on failure,
44 * that may result in a recursion */
45 /* +3 is for ": " before strerr and for terminating NUL */
46 msg1
= realloc(msg
, applet_len
+ used
+ strerr_len
+ msgeol_len
+ 3);
48 msg
[used
++] = '\n'; /* overwrites NUL */
52 /* TODO: maybe use writev instead of memmoving? Need full_writev? */
53 memmove(msg
+ applet_len
, msg
, used
);
55 strcpy(msg
, applet_name
);
56 msg
[applet_len
- 2] = ':';
57 msg
[applet_len
- 1] = ' ';
59 if (s
[0]) { /* not perror_nomsg? */
63 strcpy(&msg
[used
], strerr
);
66 strcpy(&msg
[used
], msg_eol
);
70 if (logmode
& LOGMODE_STDIO
) {
72 full_write(STDERR_FILENO
, msg
, used
);
74 #if ENABLE_FEATURE_SYSLOG
75 if (logmode
& LOGMODE_SYSLOG
) {
76 syslog(syslog_level
, "%s", msg
+ applet_len
);
82 #ifdef VERSION_WITH_WRITEV
83 /* Code size is approximately the same, but currently it's the only user
84 * of writev in entire bbox. __libc_writev in uclibc is ~50 bytes. */
85 void FAST_FUNC
bb_verror_msg(const char *s
, va_list p
, const char* strerr
)
87 int strerr_len
, msgeol_len
;
90 #define used (iov[2].iov_len)
91 #define msgv (iov[2].iov_base)
92 #define msgc ((char*)(iov[2].iov_base))
93 #define msgptr (&(iov[2].iov_base))
98 if (!s
) /* nomsg[_and_die] uses NULL fmt */
99 s
= ""; /* some libc don't like printf(NULL) */
101 /* Prevent "derefing type-punned ptr will break aliasing rules" */
102 used
= vasprintf((char**)(void*)msgptr
, s
, p
);
106 /* This is ugly and costs +60 bytes compared to multiple
107 * fprintf's, but is guaranteed to do a single write.
108 * This is needed for e.g. httpd logging, when multiple
109 * children can produce log messages simultaneously. */
111 strerr_len
= strerr
? strlen(strerr
) : 0;
112 msgeol_len
= strlen(msg_eol
);
113 /* +3 is for ": " before strerr and for terminating NUL */
114 msgv
= xrealloc(msgv
, used
+ strerr_len
+ msgeol_len
+ 3);
118 strcpy(msgc
+ used
, strerr
);
121 strcpy(msgc
+ used
, msg_eol
);
124 if (logmode
& LOGMODE_STDIO
) {
125 iov
[0].iov_base
= (char*)applet_name
;
126 iov
[0].iov_len
= strlen(applet_name
);
127 iov
[1].iov_base
= (char*)": ";
129 /*iov[2].iov_base = msgc;*/
130 /*iov[2].iov_len = used;*/
132 writev(STDERR_FILENO
, iov
, 3);
134 # if ENABLE_FEATURE_SYSLOG
135 if (logmode
& LOGMODE_SYSLOG
) {
136 syslog(LOG_ERR
, "%s", msgc
);
144 void FAST_FUNC
bb_error_msg_and_die(const char *s
, ...)
149 bb_verror_msg(s
, p
, NULL
);
154 void FAST_FUNC
bb_error_msg(const char *s
, ...)
159 bb_verror_msg(s
, p
, NULL
);