Contents of /trunk/mkinitrd-magellan/busybox/libbb/verror_msg.c
Parent Directory | Revision Log
Revision 816 -
(show annotations)
(download)
Fri Apr 24 18:33:46 2009 UTC (15 years, 5 months ago) by niro
File MIME type: text/plain
File size: 3373 byte(s)
Fri Apr 24 18:33:46 2009 UTC (15 years, 5 months ago) by niro
File MIME type: text/plain
File size: 3373 byte(s)
-updated to busybox-1.13.4
1 | /* vi: set sw=4 ts=4: */ |
2 | /* |
3 | * Utility routines. |
4 | * |
5 | * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> |
6 | * |
7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
8 | */ |
9 | |
10 | #include "libbb.h" |
11 | #include <syslog.h> |
12 | |
13 | smallint logmode = LOGMODE_STDIO; |
14 | const char *msg_eol = "\n"; |
15 | |
16 | void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr) |
17 | { |
18 | char *msg; |
19 | int applet_len, strerr_len, msgeol_len, used; |
20 | |
21 | if (!logmode) |
22 | return; |
23 | |
24 | if (!s) /* nomsg[_and_die] uses NULL fmt */ |
25 | s = ""; /* some libc don't like printf(NULL) */ |
26 | |
27 | used = vasprintf(&msg, s, p); |
28 | if (used < 0) |
29 | return; |
30 | |
31 | /* This is ugly and costs +60 bytes compared to multiple |
32 | * fprintf's, but is guaranteed to do a single write. |
33 | * This is needed for e.g. httpd logging, when multiple |
34 | * children can produce log messages simultaneously. */ |
35 | |
36 | applet_len = strlen(applet_name) + 2; /* "applet: " */ |
37 | strerr_len = strerr ? strlen(strerr) : 0; |
38 | msgeol_len = strlen(msg_eol); |
39 | /* +3 is for ": " before strerr and for terminating NUL */ |
40 | msg = xrealloc(msg, applet_len + used + strerr_len + msgeol_len + 3); |
41 | /* TODO: maybe use writev instead of memmoving? Need full_writev? */ |
42 | memmove(msg + applet_len, msg, used); |
43 | used += applet_len; |
44 | strcpy(msg, applet_name); |
45 | msg[applet_len - 2] = ':'; |
46 | msg[applet_len - 1] = ' '; |
47 | if (strerr) { |
48 | if (s[0]) { /* not perror_nomsg? */ |
49 | msg[used++] = ':'; |
50 | msg[used++] = ' '; |
51 | } |
52 | strcpy(&msg[used], strerr); |
53 | used += strerr_len; |
54 | } |
55 | strcpy(&msg[used], msg_eol); |
56 | |
57 | if (logmode & LOGMODE_STDIO) { |
58 | fflush(stdout); |
59 | full_write(STDERR_FILENO, msg, used + msgeol_len); |
60 | } |
61 | if (logmode & LOGMODE_SYSLOG) { |
62 | syslog(LOG_ERR, "%s", msg + applet_len); |
63 | } |
64 | free(msg); |
65 | } |
66 | |
67 | |
68 | #ifdef VERSION_WITH_WRITEV |
69 | |
70 | /* Code size is approximately the same, but currently it's the only user |
71 | * of writev in entire bbox. __libc_writev in uclibc is ~50 bytes. */ |
72 | |
73 | void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr) |
74 | { |
75 | int strerr_len, msgeol_len; |
76 | struct iovec iov[3]; |
77 | |
78 | #define used (iov[2].iov_len) |
79 | #define msgv (iov[2].iov_base) |
80 | #define msgc ((char*)(iov[2].iov_base)) |
81 | #define msgptr (&(iov[2].iov_base)) |
82 | |
83 | if (!logmode) |
84 | return; |
85 | |
86 | if (!s) /* nomsg[_and_die] uses NULL fmt */ |
87 | s = ""; /* some libc don't like printf(NULL) */ |
88 | |
89 | /* Prevent "derefing type-punned ptr will break aliasing rules" */ |
90 | used = vasprintf((char**)(void*)msgptr, s, p); |
91 | if (used < 0) |
92 | return; |
93 | |
94 | /* This is ugly and costs +60 bytes compared to multiple |
95 | * fprintf's, but is guaranteed to do a single write. |
96 | * This is needed for e.g. httpd logging, when multiple |
97 | * children can produce log messages simultaneously. */ |
98 | |
99 | strerr_len = strerr ? strlen(strerr) : 0; |
100 | msgeol_len = strlen(msg_eol); |
101 | /* +3 is for ": " before strerr and for terminating NUL */ |
102 | msgv = xrealloc(msgv, used + strerr_len + msgeol_len + 3); |
103 | if (strerr) { |
104 | msgc[used++] = ':'; |
105 | msgc[used++] = ' '; |
106 | strcpy(msgc + used, strerr); |
107 | used += strerr_len; |
108 | } |
109 | strcpy(msgc + used, msg_eol); |
110 | used += msgeol_len; |
111 | |
112 | if (logmode & LOGMODE_STDIO) { |
113 | iov[0].iov_base = (char*)applet_name; |
114 | iov[0].iov_len = strlen(applet_name); |
115 | iov[1].iov_base = (char*)": "; |
116 | iov[1].iov_len = 2; |
117 | /*iov[2].iov_base = msgc;*/ |
118 | /*iov[2].iov_len = used;*/ |
119 | fflush(stdout); |
120 | writev(2, iov, 3); |
121 | } |
122 | if (logmode & LOGMODE_SYSLOG) { |
123 | syslog(LOG_ERR, "%s", msgc); |
124 | } |
125 | free(msgc); |
126 | } |
127 | #endif |