Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/sysklogd/logread.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 815 by niro, Sat Sep 1 22:45:15 2007 UTC revision 816 by niro, Fri Apr 24 18:33:46 2009 UTC
# Line 9  Line 9 
9   * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.   * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
10   */   */
11    
12  #include "busybox.h"  #include "libbb.h"
13  #include <sys/ipc.h>  #include <sys/ipc.h>
14  #include <sys/sem.h>  #include <sys/sem.h>
15  #include <sys/shm.h>  #include <sys/shm.h>
16    
17  #define DEBUG 0  #define DEBUG 0
18    
19    /* our shared key (syslogd.c and logread.c must be in sync) */
20  enum { KEY_ID = 0x414e4547 }; /* "GENA" */  enum { KEY_ID = 0x414e4547 }; /* "GENA" */
21    
22  static struct shbuf_ds {  struct shbuf_ds {
23   int32_t size;           // size of data written   int32_t size;           // size of data - 1
  int32_t head;           // start of message list  
24   int32_t tail;           // end of message list   int32_t tail;           // end of message list
25   char data[1];           // data/messages   char data[1];           // messages
26  } *buf;                         // shared memory pointer  };
27    
28  // Semaphore operation structures  static const struct sembuf init_sem[3] = {
29  static struct sembuf SMrup[1] = {{0, -1, IPC_NOWAIT | SEM_UNDO}}; // set SMrup   {0, -1, IPC_NOWAIT | SEM_UNDO},
30  static struct sembuf SMrdn[2] = {{1, 0}, {0, +1, SEM_UNDO}}; // set SMrdn   {1, 0}, {0, +1, SEM_UNDO}
31    };
32    
33    struct globals {
34     struct sembuf SMrup[1]; // {0, -1, IPC_NOWAIT | SEM_UNDO},
35     struct sembuf SMrdn[2]; // {1, 0}, {0, +1, SEM_UNDO}
36     struct shbuf_ds *shbuf;
37    };
38    #define G (*(struct globals*)&bb_common_bufsiz1)
39    #define SMrup (G.SMrup)
40    #define SMrdn (G.SMrdn)
41    #define shbuf (G.shbuf)
42    #define INIT_G() do { \
43     memcpy(SMrup, init_sem, sizeof(init_sem)); \
44    } while (0)
45    
46    static void error_exit(const char *str) NORETURN;
 static void error_exit(const char *str) ATTRIBUTE_NORETURN;  
47  static void error_exit(const char *str)  static void error_exit(const char *str)
48  {  {
49   //release all acquired resources   //release all acquired resources
50   shmdt(buf);   shmdt(shbuf);
51   bb_perror_msg_and_die(str);   bb_perror_msg_and_die(str);
52  }  }
53    
# Line 47  static void sem_up(int semid) Line 60  static void sem_up(int semid)
60   error_exit("semop[SMrup]");   error_exit("semop[SMrup]");
61  }  }
62    
63  static void interrupted(int sig ATTRIBUTE_UNUSED)  static void interrupted(int sig UNUSED_PARAM)
64  {  {
65   signal(SIGINT, SIG_IGN);   signal(SIGINT, SIG_IGN);
66   shmdt(buf);   shmdt(shbuf);
67   exit(0);   exit(EXIT_SUCCESS);
68  }  }
69    
70  int logread_main(int argc, char **argv)  int logread_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
71    int logread_main(int argc UNUSED_PARAM, char **argv)
72  {  {
73   int cur;   unsigned cur;
74   int log_semid; /* ipc semaphore id */   int log_semid; /* ipc semaphore id */
75   int log_shmid; /* ipc shared memory id */   int log_shmid; /* ipc shared memory id */
76   smallint follow = getopt32(argc, argv, "f");   smallint follow = getopt32(argv, "f");
77    
78     INIT_G();
79    
80   log_shmid = shmget(KEY_ID, 0, 0);   log_shmid = shmget(KEY_ID, 0, 0);
81   if (log_shmid == -1)   if (log_shmid == -1)
82   bb_perror_msg_and_die("can't find syslogd buffer");   bb_perror_msg_and_die("can't find syslogd buffer");
83    
84   // Attach shared memory to our char*   /* Attach shared memory to our char* */
85   buf = shmat(log_shmid, NULL, SHM_RDONLY);   shbuf = shmat(log_shmid, NULL, SHM_RDONLY);
86   if (buf == NULL)   if (shbuf == NULL)
87   bb_perror_msg_and_die("can't access syslogd buffer");   bb_perror_msg_and_die("can't access syslogd buffer");
88    
89   log_semid = semget(KEY_ID, 0, 0);   log_semid = semget(KEY_ID, 0, 0);
90   if (log_semid == -1)   if (log_semid == -1)
91   error_exit("can't get access to semaphores for syslogd buffer");   error_exit("can't get access to semaphores for syslogd buffer");
92    
  // attempt to redefine ^C signal  
93   signal(SIGINT, interrupted);   signal(SIGINT, interrupted);
94    
95   // Suppose atomic memory move   /* Suppose atomic memory read */
96   cur = follow ? buf->tail : buf->head;   /* Max possible value for tail is shbuf->size - 1 */
97     cur = shbuf->tail;
98    
99     /* Loop for logread -f, one pass if there was no -f */
100   do {   do {
101     unsigned shbuf_size;
102     unsigned shbuf_tail;
103     const char *shbuf_data;
104  #if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING  #if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING
105   char *buf_data;   int i;
106   int log_len, j;   int len_first_part;
107     int len_total = len_total; /* for gcc */
108     char *copy = copy; /* for gcc */
109  #endif  #endif
110   if (semop(log_semid, SMrdn, 2) == -1)   if (semop(log_semid, SMrdn, 2) == -1)
111   error_exit("semop[SMrdn]");   error_exit("semop[SMrdn]");
112    
113     /* Copy the info, helps gcc to realize that it doesn't change */
114     shbuf_size = shbuf->size;
115     shbuf_tail = shbuf->tail;
116     shbuf_data = shbuf->data; /* pointer! */
117    
118   if (DEBUG)   if (DEBUG)
119   printf("head:%i cur:%d tail:%i size:%i\n",   printf("cur:%d tail:%i size:%i\n",
120   buf->head, cur, buf->tail, buf->size);   cur, shbuf_tail, shbuf_size);
121    
122   if (buf->head == buf->tail || cur == buf->tail) {   if (!follow) {
123   if (follow) {   /* advance to oldest complete message */
124     /* find NUL */
125     cur += strlen(shbuf_data + cur);
126     if (cur >= shbuf_size) { /* last byte in buffer? */
127     cur = strnlen(shbuf_data, shbuf_tail);
128     if (cur == shbuf_tail)
129     goto unlock; /* no complete messages */
130     }
131     /* advance to first byte of the message */
132     cur++;
133     if (cur >= shbuf_size) /* last byte in buffer? */
134     cur = 0;
135     } else { /* logread -f */
136     if (cur == shbuf_tail) {
137   sem_up(log_semid);   sem_up(log_semid);
138   fflush(stdout);   fflush(stdout);
139   sleep(1); /* TODO: replace me with a sleep_on */   sleep(1); /* TODO: replace me with a sleep_on */
140   continue;   continue;
141   }   }
  puts("<empty syslog>");  
142   }   }
143    
144   // Read Memory   /* Read from cur to tail */
145  #if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING  #if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING
146   log_len = buf->tail - cur;   len_first_part = len_total = shbuf_tail - cur;
147   if (log_len < 0)   if (len_total < 0) {
148   log_len += buf->size;   /* message wraps: */
149   buf_data = xmalloc(log_len);   /* [SECOND PART.........FIRST PART] */
150     /*  ^data      ^tail    ^cur      ^size */
151   if (buf->tail >= cur)   len_total += shbuf_size;
152   j = log_len;   }
153   else   copy = xmalloc(len_total + 1);
154   j = buf->size - cur;   if (len_first_part < 0) {
155   memcpy(buf_data, buf->data + cur, j);   /* message wraps (see above) */
156     len_first_part = shbuf_size - cur;
157   if (buf->tail < cur)   memcpy(copy + len_first_part, shbuf_data, shbuf_tail);
158   memcpy(buf_data + buf->size - cur, buf->data, buf->tail);   }
159   cur = buf->tail;   memcpy(copy, shbuf_data + cur, len_first_part);
160     copy[len_total] = '\0';
161     cur = shbuf_tail;
162  #else  #else
163   while (cur != buf->tail) {   while (cur != shbuf_tail) {
164   fputs(buf->data + cur, stdout);   fputs(shbuf_data + cur, stdout);
165   cur += strlen(buf->data + cur) + 1;   cur += strlen(shbuf_data + cur) + 1;
166   if (cur >= buf->size)   if (cur >= shbuf_size)
167   cur = 0;   cur = 0;
168   }   }
169  #endif  #endif
170   // release the lock on the log chain   unlock:
171     /* release the lock on the log chain */
172   sem_up(log_semid);   sem_up(log_semid);
173    
174  #if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING  #if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING
175   for (j = 0; j < log_len; j += strlen(buf_data+j) + 1) {   for (i = 0; i < len_total; i += strlen(copy + i) + 1) {
176   fputs(buf_data + j, stdout);   fputs(copy + i, stdout);
177   }   }
178   free(buf_data);   free(copy);
179  #endif  #endif
180   } while (follow);   } while (follow);
181    
182   shmdt(buf);   shmdt(shbuf);
183    
184   fflush_stdout_and_exit(EXIT_SUCCESS);   fflush_stdout_and_exit(EXIT_SUCCESS);
185  }  }

Legend:
Removed from v.815  
changed lines
  Added in v.816