aboutsummaryrefslogtreecommitdiff
path: root/sysklogd/syslogd.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-08-12 21:33:06 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-08-12 21:33:06 +0000
commit5f1b149d541ebba7cab841cb647f113248f9fb8f (patch)
treee7f962fba89b6e201b4c857e32d85c9671b3db0d /sysklogd/syslogd.c
parent1b9064d5355b5c26676e8447a1900116066e42e4 (diff)
downloadbusybox-w32-5f1b149d541ebba7cab841cb647f113248f9fb8f.tar.gz
busybox-w32-5f1b149d541ebba7cab841cb647f113248f9fb8f.tar.bz2
busybox-w32-5f1b149d541ebba7cab841cb647f113248f9fb8f.zip
syslogd,logread: get rid of head pointer, fix logread bug in the process
function old new delta logread_main 450 462 +12 syslogd_main 1246 1252 +6 shbuf - 4 +4 buf 34 30 -4 packed_usage 22729 22724 -5 log_locally 957 767 -190 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 2/3 up/down: 22/-199) Total: -177 bytes text data bss dec hex filename 773886 1116 11316 786318 bff8e busybox_old 773714 1116 11316 786146 bfee2 busybox_unstripped
Diffstat (limited to 'sysklogd/syslogd.c')
-rw-r--r--sysklogd/syslogd.c55
1 files changed, 12 insertions, 43 deletions
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index 0ed16bc9e..6ecbd16f0 100644
--- a/sysklogd/syslogd.c
+++ b/sysklogd/syslogd.c
@@ -46,8 +46,7 @@ enum { MAX_READ = 256 };
46 46
47/* Semaphore operation structures */ 47/* Semaphore operation structures */
48struct shbuf_ds { 48struct shbuf_ds {
49 int32_t size; /* size of data written */ 49 int32_t size; /* size of data - 1 */
50 int32_t head; /* start of message list */
51 int32_t tail; /* end of message list */ 50 int32_t tail; /* end of message list */
52 char data[1]; /* data/messages */ 51 char data[1]; /* data/messages */
53}; 52};
@@ -212,8 +211,9 @@ static void ipcsyslog_init(void)
212 bb_perror_msg_and_die("shmat"); 211 bb_perror_msg_and_die("shmat");
213 } 212 }
214 213
215 G.shbuf->size = G.shm_size - offsetof(struct shbuf_ds, data); 214 memset(G.shbuf, 0, G.shm_size);
216 G.shbuf->head = G.shbuf->tail = 0; 215 G.shbuf->size = G.shm_size - offsetof(struct shbuf_ds, data) - 1;
216 /*G.shbuf->tail = 0;*/
217 217
218 // we'll trust the OS to set initial semval to 0 (let's hope) 218 // we'll trust the OS to set initial semval to 0 (let's hope)
219 G.s_semid = semget(KEY_ID, 2, IPC_CREAT | IPC_EXCL | 1023); 219 G.s_semid = semget(KEY_ID, 2, IPC_CREAT | IPC_EXCL | 1023);
@@ -231,7 +231,6 @@ static void ipcsyslog_init(void)
231static void log_to_shmem(const char *msg, int len) 231static void log_to_shmem(const char *msg, int len)
232{ 232{
233 int old_tail, new_tail; 233 int old_tail, new_tail;
234 char *c;
235 234
236 if (semop(G.s_semid, G.SMwdn, 3) == -1) { 235 if (semop(G.s_semid, G.SMwdn, 3) == -1) {
237 bb_perror_msg_and_die("SMwdn"); 236 bb_perror_msg_and_die("SMwdn");
@@ -240,49 +239,20 @@ static void log_to_shmem(const char *msg, int len)
240 /* Circular Buffer Algorithm: 239 /* Circular Buffer Algorithm:
241 * -------------------------- 240 * --------------------------
242 * tail == position where to store next syslog message. 241 * tail == position where to store next syslog message.
243 * head == position of next message to retrieve ("print"). 242 * tail's max value is (shbuf->size - 1)
244 * if head == tail, there is no "unprinted" messages left. 243 * Last byte of buffer is never used and remains NUL.
245 * head is typically advanced by separate "reader" program,
246 * but if there isn't one, we have to do it ourself.
247 * messages are NUL-separated.
248 */ 244 */
249 len++; /* length with NUL included */ 245 len++; /* length with NUL included */
250 again: 246 again:
251 old_tail = G.shbuf->tail; 247 old_tail = G.shbuf->tail;
252 new_tail = old_tail + len; 248 new_tail = old_tail + len;
253 if (new_tail < G.shbuf->size) { 249 if (new_tail < G.shbuf->size) {
254 /* No need to move head if shbuf->head <= old_tail,
255 * else... */
256 if (old_tail < G.shbuf->head && G.shbuf->head <= new_tail) {
257 /* ...need to move head forward */
258 c = memchr(G.shbuf->data + new_tail, '\0',
259 G.shbuf->size - new_tail);
260 if (!c) /* no NUL ahead of us, wrap around */
261 c = memchr(G.shbuf->data, '\0', old_tail);
262 if (!c) { /* still nothing? point to this msg... */
263 G.shbuf->head = old_tail;
264 } else {
265 /* convert pointer to offset + skip NUL */
266 G.shbuf->head = c - G.shbuf->data + 1;
267 }
268 }
269 /* store message, set new tail */ 250 /* store message, set new tail */
270 memcpy(G.shbuf->data + old_tail, msg, len); 251 memcpy(G.shbuf->data + old_tail, msg, len);
271 G.shbuf->tail = new_tail; 252 G.shbuf->tail = new_tail;
272 } else { 253 } else {
273 /* we need to break up the message and wrap it around */
274 /* k == available buffer space ahead of old tail */ 254 /* k == available buffer space ahead of old tail */
275 int k = G.shbuf->size - old_tail - 1; 255 int k = G.shbuf->size - old_tail;
276 if (G.shbuf->head > old_tail) {
277 /* we are going to overwrite head, need to
278 * move it out of the way */
279 c = memchr(G.shbuf->data, '\0', old_tail);
280 if (!c) { /* nothing? point to this msg... */
281 G.shbuf->head = old_tail;
282 } else { /* convert pointer to offset + skip NUL */
283 G.shbuf->head = c - G.shbuf->data + 1;
284 }
285 }
286 /* copy what fits to the end of buffer, and repeat */ 256 /* copy what fits to the end of buffer, and repeat */
287 memcpy(G.shbuf->data + old_tail, msg, k); 257 memcpy(G.shbuf->data + old_tail, msg, k);
288 msg += k; 258 msg += k;
@@ -294,7 +264,7 @@ static void log_to_shmem(const char *msg, int len)
294 bb_perror_msg_and_die("SMwup"); 264 bb_perror_msg_and_die("SMwup");
295 } 265 }
296 if (DEBUG) 266 if (DEBUG)
297 printf("head:%d tail:%d\n", G.shbuf->head, G.shbuf->tail); 267 printf("tail:%d\n", G.shbuf->tail);
298} 268}
299#else 269#else
300void ipcsyslog_cleanup(void); 270void ipcsyslog_cleanup(void);
@@ -339,11 +309,10 @@ static void log_locally(char *msg)
339 } 309 }
340#if ENABLE_FEATURE_ROTATE_LOGFILE 310#if ENABLE_FEATURE_ROTATE_LOGFILE
341 { 311 {
342 struct stat statf; 312 struct stat statf;
343 313 G.isRegular = (fstat(G.logFD, &statf) == 0 && S_ISREG(statf.st_mode));
344 G.isRegular = (fstat(G.logFD, &statf) == 0 && (statf.st_mode & S_IFREG)); 314 /* bug (mostly harmless): can wrap around if file > 4gb */
345 /* bug (mostly harmless): can wrap around if file > 4gb */ 315 G.curFileSize = statf.st_size;
346 G.curFileSize = statf.st_size;
347 } 316 }
348#endif 317#endif
349 } 318 }