www.usr.com/support/gpl/USR9113_release1.0.tar.gz
[bcm963xx.git] / userapps / opensource / busybox / sysklogd / logread.c
index 72bebc3..f45cef9 100755 (executable)
@@ -2,9 +2,9 @@
 /*
  * circular buffer syslog implementation for busybox
  *
- * Copyright (C) 2000 by Gennady Feldman <gfeldman@cachier.com>
+ * Copyright (C) 2000 by Gennady Feldman <gfeldman@gena01.com>
  *
- * Maintainer: Gennady Feldman <gena01@cachier.com> as of Mar 12, 2001
+ * Maintainer: Gennady Feldman <gfeldman@gena01.com> as of Mar 12, 2001
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #include <sys/shm.h>
 #include <signal.h>
 #include <setjmp.h>
+#include <unistd.h>
 #include "busybox.h"
 
-#if __GNU_LIBRARY__ < 5
-#error Sorry.  Looks like you are using libc5.  
-#error libc5 shm support isnt good enough.
-#error Please disable BB_FEATURE_IPC_SYSLOG 
-#endif 
-
-
 static const long KEY_ID = 0x414e4547; /*"GENA"*/
 
 static struct shbuf_ds {
        int size;               // size of data written
        int head;               // start of message list
        int tail;               // end of message list
-       int pre_tail;   //added by echo 
        char data[1];           // data/messages
 } *buf = NULL;                 // shared memory pointer
 
@@ -69,13 +62,13 @@ static void interrupted(int sig);
  */
 static inline void sem_up(int semid)
 {
-       if ( semop(semid, SMrup, 1) == -1 ) 
+       if ( semop(semid, SMrup, 1) == -1 )
                error_exit("semop[SMrup]");
 }
 
 /*
  * sem_down - down()'s a semaphore
- */                            
+ */
 static inline void sem_down(int semid)
 {
        if ( semop(semid, SMrdn, 2) == -1 )
@@ -85,17 +78,25 @@ static inline void sem_down(int semid)
 extern int logread_main(int argc, char **argv)
 {
        int i;
-       int msglen;
-       
+       int follow=0;
+
+       if (argc == 2 && strcmp(argv[1],"-f")==0) {
+               follow = 1;
+       } else {
+               /* no options, no getopt */
+               if (argc > 1)
+                       bb_show_usage();
+       }
+
        // handle intrrupt signal
        if (setjmp(jmp_env)) goto output_end;
-       
+
        // attempt to redefine ^C signal
        signal(SIGINT, interrupted);
-       
+
        if ( (log_shmid = shmget(KEY_ID, 0, 0)) == -1)
                error_exit("Can't find circular buffer");
-       
+
        // Attach shared memory to our char*
        if ( (buf = shmat(log_shmid, NULL, SHM_RDONLY)) == NULL)
                error_exit("Can't get access to circular buffer from syslogd");
@@ -103,31 +104,71 @@ extern int logread_main(int argc, char **argv)
        if ( (log_semid = semget(KEY_ID, 0, 0)) == -1)
                error_exit("Can't get access to semaphone(s) for circular buffer from syslogd");
 
-       sem_down(log_semid);    
-       // Read Memory 
-       i=buf->head;
-
-       //printf("head: %i tail: %i size: %i\n",buf->head,buf->tail,buf->size);
-       if (buf->head == buf->tail) {
-               printf("<empty syslog>\n");
-       }
-       
-       while ( i < buf->tail) {
-               msglen = strlen(buf->data+i);
-               if(i+msglen >= buf->size)
-                       break;
-               printf("%s", buf->data+i);
-               i+= strlen(buf->data+i) + 1;
-               /*if (i >= buf->size )
-                       i=0;*/
-       }
-       sem_up(log_semid);
+       // Suppose atomic memory move
+       i = follow ? buf->tail : buf->head;
+
+       do {
+#ifdef CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING
+               char *buf_data;
+               int log_len,j;
+#endif
+
+               sem_down(log_semid);
+
+               //printf("head: %i tail: %i size: %i\n",buf->head,buf->tail,buf->size);
+               if (buf->head == buf->tail || i==buf->tail) {
+                       if (follow) {
+                               sem_up(log_semid);
+                               sleep(1);       /* TODO: replace me with a sleep_on */
+                               continue;
+                       } else {
+                               printf("<empty syslog>\n");
+                       }
+               }
+
+               // Read Memory
+#ifdef CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING
+               log_len = buf->tail - i;
+               if (log_len < 0)
+                       log_len += buf->size;
+               buf_data = (char *)malloc(log_len);
+               if (!buf_data)
+                       error_exit("malloc failed");
+
+               if (buf->tail < i) {
+                       memcpy(buf_data, buf->data+i, buf->size-i);
+                       memcpy(buf_data+buf->size-i, buf->data, buf->tail);
+               } else {
+                       memcpy(buf_data, buf->data+i, buf->tail-i);
+               }
+               i = buf->tail;
+
+#else
+               while ( i != buf->tail) {
+                       printf("%s", buf->data+i);
+                       i+= strlen(buf->data+i) + 1;
+                       if (i >= buf->size )
+                               i=0;
+               }
+#endif
+               // release the lock on the log chain
+               sem_up(log_semid);
+
+#ifdef CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING
+               for (j=0; j < log_len; j+=strlen(buf_data+j)+1) {
+                       printf("%s", buf_data+j);
+                       if (follow)
+                               fflush(stdout);
+               }
+               free(buf_data);
+#endif
+       } while (follow);
 
 output_end:
-       if (log_shmid != -1) 
+       if (log_shmid != -1)
                shmdt(buf);
-               
-       return EXIT_SUCCESS;            
+
+       return EXIT_SUCCESS;
 }
 
 static void interrupted(int sig){
@@ -136,9 +177,11 @@ static void interrupted(int sig){
 }
 
 static void error_exit(const char *str){
+#ifdef DEBUG
        perror(str);
+#endif
        //release all acquired resources
-       if (log_shmid != -1) 
+       if (log_shmid != -1)
                shmdt(buf);
 
        exit(1);