Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/sysklogd/logread.c
- Timestamp:
- Nov 6, 2007, 11:01:53 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/mindi-busybox/sysklogd/logread.c
r821 r1770 10 10 */ 11 11 12 13 #include "busybox.h" 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 12 #include "libbb.h" 17 13 #include <sys/ipc.h> 18 #include <sys/types.h>19 14 #include <sys/sem.h> 20 15 #include <sys/shm.h> 21 #include <signal.h>22 #include <setjmp.h>23 #include <unistd.h>24 16 25 static const long KEY_ID = 0x414e4547; /*"GENA"*/ 17 #define DEBUG 0 18 19 enum { KEY_ID = 0x414e4547 }; /* "GENA" */ 26 20 27 21 static struct shbuf_ds { 28 int size; // size of data written 29 int head; // start of message list 30 int tail; // end of message list 31 char data[1]; // data/messages 32 } *buf = NULL; // shared memory pointer 33 22 int32_t size; // size of data - 1 23 int32_t tail; // end of message list 24 char data[1]; // messages 25 } *shbuf; 34 26 35 27 // Semaphore operation structures … … 37 29 static struct sembuf SMrdn[2] = {{1, 0}, {0, +1, SEM_UNDO}}; // set SMrdn 38 30 39 static int log_shmid = -1; // ipc shared memory id40 static int log_semid = -1; // ipc semaphore id41 static jmp_buf jmp_env;42 31 43 static void error_exit(const char *str); 44 static void interrupted(int sig); 32 static void error_exit(const char *str) ATTRIBUTE_NORETURN; 33 static void error_exit(const char *str) 34 { 35 //release all acquired resources 36 shmdt(shbuf); 37 bb_perror_msg_and_die(str); 38 } 45 39 46 40 /* 47 41 * sem_up - up()'s a semaphore. 48 42 */ 49 static inlinevoid sem_up(int semid)43 static void sem_up(int semid) 50 44 { 51 if ( semop(semid, SMrup, 1) == -1)45 if (semop(semid, SMrup, 1) == -1) 52 46 error_exit("semop[SMrup]"); 53 47 } 54 48 55 /* 56 * sem_down - down()'s a semaphore 57 */ 58 static inline void sem_down(int semid) 49 static void interrupted(int sig ATTRIBUTE_UNUSED) 59 50 { 60 if ( semop(semid, SMrdn, 2) == -1 ) 61 error_exit("semop[SMrdn]"); 51 signal(SIGINT, SIG_IGN); 52 shmdt(shbuf); 53 exit(0); 62 54 } 63 55 56 int logread_main(int argc, char **argv); 64 57 int logread_main(int argc, char **argv) 65 58 { 66 int i; 67 int follow=0; 59 int cur; 60 int log_semid; /* ipc semaphore id */ 61 int log_shmid; /* ipc shared memory id */ 62 smallint follow = getopt32(argv, "f"); 68 63 69 if (argc == 2 && argv[1][0]=='-' && argv[1][1]=='f') { 70 follow = 1; 71 } else { 72 /* no options, no getopt */ 73 if (argc > 1) 74 bb_show_usage(); 75 } 64 log_shmid = shmget(KEY_ID, 0, 0); 65 if (log_shmid == -1) 66 bb_perror_msg_and_die("can't find syslogd buffer"); 76 67 77 // handle interrupt signal 78 if (setjmp(jmp_env)) goto output_end; 68 /* Attach shared memory to our char* */ 69 shbuf = shmat(log_shmid, NULL, SHM_RDONLY); 70 if (shbuf == NULL) 71 bb_perror_msg_and_die("can't access syslogd buffer"); 79 72 80 // attempt to redefine ^C signal 73 log_semid = semget(KEY_ID, 0, 0); 74 if (log_semid == -1) 75 error_exit("can't get access to semaphores for syslogd buffer"); 76 81 77 signal(SIGINT, interrupted); 82 78 83 if ( (log_shmid = shmget(KEY_ID, 0, 0)) == -1) 84 error_exit("Can't find circular buffer"); 79 /* Suppose atomic memory read */ 80 /* Max possible value for tail is shbuf->size - 1 */ 81 cur = shbuf->tail; 85 82 86 // Attach shared memory to our char* 87 if ( (buf = shmat(log_shmid, NULL, SHM_RDONLY)) == NULL) 88 error_exit("Can't get access to circular buffer from syslogd"); 83 /* Loop for logread -f, one pass if there was no -f */ 84 do { 85 unsigned shbuf_size; 86 unsigned shbuf_tail; 87 const char *shbuf_data; 88 #if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING 89 int i; 90 int len_first_part; 91 int len_total = len_total; /* for gcc */ 92 char *copy = copy; /* for gcc */ 93 #endif 94 if (semop(log_semid, SMrdn, 2) == -1) 95 error_exit("semop[SMrdn]"); 89 96 90 if ( (log_semid = semget(KEY_ID, 0, 0)) == -1) 91 error_exit("Can't get access to semaphone(s) for circular buffer from syslogd"); 97 /* Copy the info, helps gcc to realize that it doesn't change */ 98 shbuf_size = shbuf->size; 99 shbuf_tail = shbuf->tail; 100 shbuf_data = shbuf->data; /* pointer! */ 92 101 93 // Suppose atomic memory move 94 i = follow ? buf->tail : buf->head; 102 if (DEBUG) 103 printf("cur:%d tail:%i size:%i\n", 104 cur, shbuf_tail, shbuf_size); 95 105 96 do { 97 #ifdef CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING 98 char *buf_data; 99 int log_len,j; 100 #endif 101 102 sem_down(log_semid); 103 104 //printf("head: %i tail: %i size: %i\n",buf->head,buf->tail,buf->size); 105 if (buf->head == buf->tail || i==buf->tail) { 106 if (follow) { 106 if (!follow) { 107 /* advance to oldest complete message */ 108 /* find NUL */ 109 cur += strlen(shbuf_data + cur); 110 if (cur >= shbuf_size) { /* last byte in buffer? */ 111 cur = strnlen(shbuf_data, shbuf_tail); 112 if (cur == shbuf_tail) 113 goto unlock; /* no complete messages */ 114 } 115 /* advance to first byte of the message */ 116 cur++; 117 if (cur >= shbuf_size) /* last byte in buffer? */ 118 cur = 0; 119 } else { /* logread -f */ 120 if (cur == shbuf_tail) { 107 121 sem_up(log_semid); 108 sleep(1); /* TODO: replace me with a sleep_on */ 122 fflush(stdout); 123 sleep(1); /* TODO: replace me with a sleep_on */ 109 124 continue; 110 } else {111 printf("<empty syslog>\n");112 125 } 113 126 } 114 127 115 // Read Memory 116 #ifdef CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING 117 log_len = buf->tail - i; 118 if (log_len < 0) 119 log_len += buf->size; 120 buf_data = (char *)xmalloc(log_len); 121 122 if (buf->tail < i) { 123 memcpy(buf_data, buf->data+i, buf->size-i); 124 memcpy(buf_data+buf->size-i, buf->data, buf->tail); 125 } else { 126 memcpy(buf_data, buf->data+i, buf->tail-i); 128 /* Read from cur to tail */ 129 #if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING 130 len_first_part = len_total = shbuf_tail - cur; 131 if (len_total < 0) { 132 /* message wraps: */ 133 /* [SECOND PART.........FIRST PART] */ 134 /* ^data ^tail ^cur ^size */ 135 len_total += shbuf_size; 127 136 } 128 i = buf->tail; 129 137 copy = xmalloc(len_total + 1); 138 if (len_first_part < 0) { 139 /* message wraps (see above) */ 140 len_first_part = shbuf_size - cur; 141 memcpy(copy + len_first_part, shbuf_data, shbuf_tail); 142 } 143 memcpy(copy, shbuf_data + cur, len_first_part); 144 copy[len_total] = '\0'; 145 cur = shbuf_tail; 130 146 #else 131 while ( i != buf->tail) {132 printf("%s", buf->data+i);133 i+= strlen(buf->data+i) + 1;134 if ( i >= buf->size)135 i=0;147 while (cur != shbuf_tail) { 148 fputs(shbuf_data + cur, stdout); 149 cur += strlen(shbuf_data + cur) + 1; 150 if (cur >= shbuf_size) 151 cur = 0; 136 152 } 137 153 #endif 138 // release the lock on the log chain 154 unlock: 155 /* release the lock on the log chain */ 139 156 sem_up(log_semid); 140 157 141 #ifdef CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING 142 for (j=0; j < log_len; j+=strlen(buf_data+j)+1) { 143 printf("%s", buf_data+j); 144 if (follow) 145 fflush(stdout); 158 #if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING 159 for (i = 0; i < len_total; i += strlen(copy + i) + 1) { 160 fputs(copy + i, stdout); 146 161 } 147 free( buf_data);162 free(copy); 148 163 #endif 149 fflush(stdout);150 164 } while (follow); 151 165 152 output_end: 153 if (log_shmid != -1) 154 shmdt(buf); 166 shmdt(shbuf); 155 167 156 return EXIT_SUCCESS;168 fflush_stdout_and_exit(EXIT_SUCCESS); 157 169 } 158 159 static void interrupted(int sig){160 signal(SIGINT, SIG_IGN);161 longjmp(jmp_env, 1);162 }163 164 static void error_exit(const char *str){165 bb_perror_msg(str);166 //release all acquired resources167 if (log_shmid != -1)168 shmdt(buf);169 170 exit(1);171 }
Note:
See TracChangeset
for help on using the changeset viewer.