Annotation of /tags/mkinitrd-6_2_0/libbb/verror_msg.c
Parent Directory | Revision Log
Revision 984 -
(hide annotations)
(download)
Sun May 30 11:32:42 2010 UTC (14 years, 4 months ago) by niro
Original Path: trunk/mkinitrd-magellan/busybox/libbb/verror_msg.c
File MIME type: text/plain
File size: 3607 byte(s)
Sun May 30 11:32:42 2010 UTC (14 years, 4 months ago) by niro
Original Path: trunk/mkinitrd-magellan/busybox/libbb/verror_msg.c
File MIME type: text/plain
File size: 3607 byte(s)
-updated to busybox-1.16.1 and enabled blkid/uuid support in default config
1 | niro | 532 | /* 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 | niro | 816 | smallint logmode = LOGMODE_STDIO; |
14 | niro | 532 | const char *msg_eol = "\n"; |
15 | |||
16 | niro | 816 | void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr) |
17 | niro | 532 | { |
18 | niro | 984 | char *msg, *msg1; |
19 | niro | 816 | int applet_len, strerr_len, msgeol_len, used; |
20 | niro | 532 | |
21 | niro | 816 | 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 | niro | 984 | /* can't use xrealloc: it calls error_msg on failure, |
40 | * that may result in a recursion */ | ||
41 | niro | 816 | /* +3 is for ": " before strerr and for terminating NUL */ |
42 | niro | 984 | msg1 = realloc(msg, applet_len + used + strerr_len + msgeol_len + 3); |
43 | if (!msg1) { | ||
44 | msg[used++] = '\n'; /* overwrites NUL */ | ||
45 | applet_len = 0; | ||
46 | } else { | ||
47 | msg = msg1; | ||
48 | /* TODO: maybe use writev instead of memmoving? Need full_writev? */ | ||
49 | memmove(msg + applet_len, msg, used); | ||
50 | used += applet_len; | ||
51 | strcpy(msg, applet_name); | ||
52 | msg[applet_len - 2] = ':'; | ||
53 | msg[applet_len - 1] = ' '; | ||
54 | if (strerr) { | ||
55 | if (s[0]) { /* not perror_nomsg? */ | ||
56 | msg[used++] = ':'; | ||
57 | msg[used++] = ' '; | ||
58 | } | ||
59 | strcpy(&msg[used], strerr); | ||
60 | used += strerr_len; | ||
61 | niro | 816 | } |
62 | niro | 984 | strcpy(&msg[used], msg_eol); |
63 | used += msgeol_len; | ||
64 | niro | 816 | } |
65 | |||
66 | niro | 532 | if (logmode & LOGMODE_STDIO) { |
67 | niro | 984 | fflush_all(); |
68 | full_write(STDERR_FILENO, msg, used); | ||
69 | niro | 532 | } |
70 | niro | 816 | if (logmode & LOGMODE_SYSLOG) { |
71 | syslog(LOG_ERR, "%s", msg + applet_len); | ||
72 | niro | 532 | } |
73 | niro | 816 | free(msg); |
74 | niro | 532 | } |
75 | niro | 816 | |
76 | |||
77 | #ifdef VERSION_WITH_WRITEV | ||
78 | |||
79 | /* Code size is approximately the same, but currently it's the only user | ||
80 | * of writev in entire bbox. __libc_writev in uclibc is ~50 bytes. */ | ||
81 | |||
82 | void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr) | ||
83 | { | ||
84 | int strerr_len, msgeol_len; | ||
85 | struct iovec iov[3]; | ||
86 | |||
87 | #define used (iov[2].iov_len) | ||
88 | #define msgv (iov[2].iov_base) | ||
89 | #define msgc ((char*)(iov[2].iov_base)) | ||
90 | #define msgptr (&(iov[2].iov_base)) | ||
91 | |||
92 | if (!logmode) | ||
93 | return; | ||
94 | |||
95 | if (!s) /* nomsg[_and_die] uses NULL fmt */ | ||
96 | s = ""; /* some libc don't like printf(NULL) */ | ||
97 | |||
98 | /* Prevent "derefing type-punned ptr will break aliasing rules" */ | ||
99 | used = vasprintf((char**)(void*)msgptr, s, p); | ||
100 | if (used < 0) | ||
101 | return; | ||
102 | |||
103 | /* This is ugly and costs +60 bytes compared to multiple | ||
104 | * fprintf's, but is guaranteed to do a single write. | ||
105 | * This is needed for e.g. httpd logging, when multiple | ||
106 | * children can produce log messages simultaneously. */ | ||
107 | |||
108 | strerr_len = strerr ? strlen(strerr) : 0; | ||
109 | msgeol_len = strlen(msg_eol); | ||
110 | /* +3 is for ": " before strerr and for terminating NUL */ | ||
111 | msgv = xrealloc(msgv, used + strerr_len + msgeol_len + 3); | ||
112 | if (strerr) { | ||
113 | msgc[used++] = ':'; | ||
114 | msgc[used++] = ' '; | ||
115 | strcpy(msgc + used, strerr); | ||
116 | used += strerr_len; | ||
117 | } | ||
118 | strcpy(msgc + used, msg_eol); | ||
119 | used += msgeol_len; | ||
120 | |||
121 | if (logmode & LOGMODE_STDIO) { | ||
122 | iov[0].iov_base = (char*)applet_name; | ||
123 | iov[0].iov_len = strlen(applet_name); | ||
124 | iov[1].iov_base = (char*)": "; | ||
125 | iov[1].iov_len = 2; | ||
126 | /*iov[2].iov_base = msgc;*/ | ||
127 | /*iov[2].iov_len = used;*/ | ||
128 | niro | 984 | fflush_all(); |
129 | writev(STDERR_FILENO, iov, 3); | ||
130 | niro | 816 | } |
131 | if (logmode & LOGMODE_SYSLOG) { | ||
132 | syslog(LOG_ERR, "%s", msgc); | ||
133 | } | ||
134 | free(msgc); | ||
135 | } | ||
136 | #endif |