diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-08-17 19:18:06 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-08-17 19:18:06 +0000 |
commit | 1b97efd66aecdd79fa6501bc90aefe9998464347 (patch) | |
tree | 8587f85eaefb2223f4542abcdd8e4fa21647829b /libbb | |
parent | 72d260dbdac310f59d9df5bc32e69abaa3d15dfd (diff) | |
download | busybox-w32-1b97efd66aecdd79fa6501bc90aefe9998464347.tar.gz busybox-w32-1b97efd66aecdd79fa6501bc90aefe9998464347.tar.bz2 busybox-w32-1b97efd66aecdd79fa6501bc90aefe9998464347.zip |
httpd shring and logging update, part 1 or 7
text data bss dec hex filename
9836 0 0 9836 266c busybox.t1/networking/httpd.o.orig
9724 0 0 9724 25fc busybox.t2/networking/httpd.o
9657 0 0 9657 25b9 busybox.t3/networking/httpd.o
9342 0 0 9342 247e busybox.t4/networking/httpd.o
9342 0 0 9342 247e busybox.t5/networking/httpd.o
9262 0 0 9262 242e busybox.t6/networking/httpd.o
9283 0 0 9283 2443 busybox.t7/networking/httpd.o
9334 0 0 9334 2476 busybox.t8/networking/httpd.o
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/verror_msg.c | 126 |
1 files changed, 100 insertions, 26 deletions
diff --git a/libbb/verror_msg.c b/libbb/verror_msg.c index 082e7bf3c..e51003134 100644 --- a/libbb/verror_msg.c +++ b/libbb/verror_msg.c | |||
@@ -7,45 +7,119 @@ | |||
7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include "libbb.h" | ||
11 | #include <syslog.h> | 10 | #include <syslog.h> |
11 | #include "libbb.h" | ||
12 | 12 | ||
13 | smallint logmode = LOGMODE_STDIO; | 13 | smallint logmode = LOGMODE_STDIO; |
14 | const char *msg_eol = "\n"; | 14 | const char *msg_eol = "\n"; |
15 | 15 | ||
16 | void bb_verror_msg(const char *s, va_list p, const char* strerr) | 16 | void bb_verror_msg(const char *s, va_list p, const char* strerr) |
17 | { | 17 | { |
18 | /* va_copy is used because it is not portable | 18 | char *msg; |
19 | * to use va_list p twice */ | 19 | int applet_len, strerr_len, msgeol_len, used; |
20 | va_list p2; | 20 | |
21 | va_copy(p2, p); | 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 | msg[used++] = ':'; | ||
49 | msg[used++] = ' '; | ||
50 | strcpy(&msg[used], strerr); | ||
51 | used += strerr_len; | ||
52 | } | ||
53 | strcpy(&msg[used], msg_eol); | ||
54 | |||
55 | if (logmode & LOGMODE_STDIO) { | ||
56 | fflush(stdout); | ||
57 | full_write(2, msg, used + msgeol_len); | ||
58 | } | ||
59 | if (logmode & LOGMODE_SYSLOG) { | ||
60 | syslog(LOG_ERR, "%s", msg + applet_len); | ||
61 | } | ||
62 | free(msg); | ||
63 | } | ||
64 | |||
65 | |||
66 | #ifdef VERSION_WITH_WRITEV | ||
67 | |||
68 | /* Code size is approximately the same, but currently it's the only user | ||
69 | * of writev in entire bbox. __libc_writev in uclibc is ~50 bytes. */ | ||
70 | |||
71 | void bb_verror_msg(const char *s, va_list p, const char* strerr) | ||
72 | { | ||
73 | int strerr_len, msgeol_len; | ||
74 | struct iovec iov[3]; | ||
75 | |||
76 | #define used (iov[2].iov_len) | ||
77 | #define msgv (iov[2].iov_base) | ||
78 | #define msgc ((char*)(iov[2].iov_base)) | ||
79 | #define msgptr (&(iov[2].iov_base)) | ||
80 | |||
81 | if (!logmode) | ||
82 | return; | ||
22 | 83 | ||
23 | if (!s) /* nomsg[_and_die] uses NULL fmt */ | 84 | if (!s) /* nomsg[_and_die] uses NULL fmt */ |
24 | s = ""; /* some libc don't like printf(NULL) */ | 85 | s = ""; /* some libc don't like printf(NULL) */ |
25 | 86 | ||
87 | /* Prevent "derefing type-punned ptr will break aliasing rules" */ | ||
88 | used = vasprintf((char**)(void*)msgptr, s, p); | ||
89 | if (used < 0) | ||
90 | return; | ||
91 | |||
92 | /* This is ugly and costs +60 bytes compared to multiple | ||
93 | * fprintf's, but is guaranteed to do a single write. | ||
94 | * This is needed for e.g. httpd logging, when multiple | ||
95 | * children can produce log messages simultaneously. */ | ||
96 | |||
97 | strerr_len = strerr ? strlen(strerr) : 0; | ||
98 | msgeol_len = strlen(msg_eol); | ||
99 | /* +3 is for ": " before strerr and for terminating NUL */ | ||
100 | msgv = xrealloc(msgv, used + strerr_len + msgeol_len + 3); | ||
101 | if (strerr) { | ||
102 | msgc[used++] = ':'; | ||
103 | msgc[used++] = ' '; | ||
104 | strcpy(msgc + used, strerr); | ||
105 | used += strerr_len; | ||
106 | } | ||
107 | strcpy(msgc + used, msg_eol); | ||
108 | used += msgeol_len; | ||
109 | |||
26 | if (logmode & LOGMODE_STDIO) { | 110 | if (logmode & LOGMODE_STDIO) { |
111 | iov[0].iov_base = (char*)applet_name; | ||
112 | iov[0].iov_len = strlen(applet_name); | ||
113 | iov[1].iov_base = (char*)": "; | ||
114 | iov[1].iov_len = 2; | ||
115 | /*iov[2].iov_base = msgc;*/ | ||
116 | /*iov[2].iov_len = used;*/ | ||
27 | fflush(stdout); | 117 | fflush(stdout); |
28 | fprintf(stderr, "%s: ", applet_name); | 118 | writev(2, iov, 3); |
29 | vfprintf(stderr, s, p); | ||
30 | if (!strerr) | ||
31 | fputs(msg_eol, stderr); | ||
32 | else | ||
33 | fprintf(stderr, "%s%s%s", | ||
34 | s[0] ? ": " : "", | ||
35 | strerr, msg_eol); | ||
36 | } | 119 | } |
37 | if (ENABLE_FEATURE_SYSLOG && (logmode & LOGMODE_SYSLOG)) { | 120 | if (logmode & LOGMODE_SYSLOG) { |
38 | if (!strerr) | 121 | syslog(LOG_ERR, "%s", msgc); |
39 | vsyslog(LOG_ERR, s, p2); | ||
40 | else { | ||
41 | char *msg; | ||
42 | if (vasprintf(&msg, s, p2) < 0) { | ||
43 | fprintf(stderr, "%s: %s\n", applet_name, bb_msg_memory_exhausted); | ||
44 | xfunc_die(); | ||
45 | } | ||
46 | syslog(LOG_ERR, "%s: %s", msg, strerr); | ||
47 | free(msg); | ||
48 | } | ||
49 | } | 122 | } |
50 | va_end(p2); | 123 | free(msgc); |
51 | } | 124 | } |
125 | #endif | ||