summaryrefslogtreecommitdiff
path: root/sysklogd/logread.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysklogd/logread.c')
-rw-r--r--sysklogd/logread.c113
1 files changed, 69 insertions, 44 deletions
diff --git a/sysklogd/logread.c b/sysklogd/logread.c
index ac354b5c3..597e285a5 100644
--- a/sysklogd/logread.c
+++ b/sysklogd/logread.c
@@ -19,11 +19,10 @@
19enum { KEY_ID = 0x414e4547 }; /* "GENA" */ 19enum { KEY_ID = 0x414e4547 }; /* "GENA" */
20 20
21static struct shbuf_ds { 21static struct shbuf_ds {
22 int32_t size; // size of data written 22 int32_t size; // size of data - 1
23 int32_t head; // start of message list
24 int32_t tail; // end of message list 23 int32_t tail; // end of message list
25 char data[1]; // data/messages 24 char data[1]; // messages
26} *buf; // shared memory pointer 25} *shbuf;
27 26
28// Semaphore operation structures 27// Semaphore operation structures
29static struct sembuf SMrup[1] = {{0, -1, IPC_NOWAIT | SEM_UNDO}}; // set SMrup 28static struct sembuf SMrup[1] = {{0, -1, IPC_NOWAIT | SEM_UNDO}}; // set SMrup
@@ -34,7 +33,7 @@ static void error_exit(const char *str) ATTRIBUTE_NORETURN;
34static void error_exit(const char *str) 33static void error_exit(const char *str)
35{ 34{
36 //release all acquired resources 35 //release all acquired resources
37 shmdt(buf); 36 shmdt(shbuf);
38 bb_perror_msg_and_die(str); 37 bb_perror_msg_and_die(str);
39} 38}
40 39
@@ -50,7 +49,7 @@ static void sem_up(int semid)
50static void interrupted(int sig ATTRIBUTE_UNUSED) 49static void interrupted(int sig ATTRIBUTE_UNUSED)
51{ 50{
52 signal(SIGINT, SIG_IGN); 51 signal(SIGINT, SIG_IGN);
53 shmdt(buf); 52 shmdt(shbuf);
54 exit(0); 53 exit(0);
55} 54}
56 55
@@ -66,79 +65,105 @@ int logread_main(int argc, char **argv)
66 if (log_shmid == -1) 65 if (log_shmid == -1)
67 bb_perror_msg_and_die("can't find syslogd buffer"); 66 bb_perror_msg_and_die("can't find syslogd buffer");
68 67
69 // Attach shared memory to our char* 68 /* Attach shared memory to our char* */
70 buf = shmat(log_shmid, NULL, SHM_RDONLY); 69 shbuf = shmat(log_shmid, NULL, SHM_RDONLY);
71 if (buf == NULL) 70 if (shbuf == NULL)
72 bb_perror_msg_and_die("can't access syslogd buffer"); 71 bb_perror_msg_and_die("can't access syslogd buffer");
73 72
74 log_semid = semget(KEY_ID, 0, 0); 73 log_semid = semget(KEY_ID, 0, 0);
75 if (log_semid == -1) 74 if (log_semid == -1)
76 error_exit("can't get access to semaphores for syslogd buffer"); 75 error_exit("can't get access to semaphores for syslogd buffer");
77 76
78 // attempt to redefine ^C signal
79 signal(SIGINT, interrupted); 77 signal(SIGINT, interrupted);
80 78
81 // Suppose atomic memory move 79 /* Suppose atomic memory read */
82 cur = follow ? buf->tail : buf->head; 80 /* Max possible value for tail is shbuf->size - 1 */
81 cur = shbuf->tail;
83 82
83 /* Loop for logread -f, one pass if there was no -f */
84 do { 84 do {
85 unsigned shbuf_size;
86 unsigned shbuf_tail;
87 const char *shbuf_data;
85#if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING 88#if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING
86 char *buf_data; 89 int i;
87 int log_len, j; 90 int len_first_part;
91 int len_total = len_total; /* for gcc */
92 char *copy = copy; /* for gcc */
88#endif 93#endif
89 if (semop(log_semid, SMrdn, 2) == -1) 94 if (semop(log_semid, SMrdn, 2) == -1)
90 error_exit("semop[SMrdn]"); 95 error_exit("semop[SMrdn]");
91 96
92 if (DEBUG) 97 /* Copy the info, helps gcc to realize that it doesn't change */
93 printf("head:%i cur:%d tail:%i size:%i\n", 98 shbuf_size = shbuf->size;
94 buf->head, cur, buf->tail, buf->size); 99 shbuf_tail = shbuf->tail;
100 shbuf_data = shbuf->data; /* pointer! */
95 101
96 if (buf->head == buf->tail || cur == buf->tail) { 102 if (DEBUG)
97 if (follow) { 103 printf("cur:%d tail:%i size:%i\n",
104 cur, shbuf_tail, shbuf_size);
105
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) {
98 sem_up(log_semid); 121 sem_up(log_semid);
99 fflush(stdout); 122 fflush(stdout);
100 sleep(1); /* TODO: replace me with a sleep_on */ 123 sleep(1); /* TODO: replace me with a sleep_on */
101 continue; 124 continue;
102 } 125 }
103 puts("<empty syslog>");
104 } 126 }
105 127
106 // Read Memory 128 /* Read from cur to tail */
107#if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING 129#if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING
108 log_len = buf->tail - cur; 130 len_first_part = len_total = shbuf_tail - cur;
109 if (log_len < 0) 131 if (len_total < 0) {
110 log_len += buf->size; 132 /* message wraps: */
111 buf_data = xmalloc(log_len); 133 /* [SECOND PART.........FIRST PART] */
112 134 /* ^data ^tail ^cur ^size */
113 if (buf->tail >= cur) 135 len_total += shbuf_size;
114 j = log_len; 136 }
115 else 137 copy = xmalloc(len_total + 1);
116 j = buf->size - cur; 138 if (len_first_part < 0) {
117 memcpy(buf_data, buf->data + cur, j); 139 /* message wraps (see above) */
118 140 len_first_part = shbuf_size - cur;
119 if (buf->tail < cur) 141 memcpy(copy + len_first_part, shbuf_data, shbuf_tail);
120 memcpy(buf_data + buf->size - cur, buf->data, buf->tail); 142 }
121 cur = buf->tail; 143 memcpy(copy, shbuf_data + cur, len_first_part);
144 copy[len_total] = '\0';
145 cur = shbuf_tail;
122#else 146#else
123 while (cur != buf->tail) { 147 while (cur != shbuf_tail) {
124 fputs(buf->data + cur, stdout); 148 fputs(shbuf_data + cur, stdout);
125 cur += strlen(buf->data + cur) + 1; 149 cur += strlen(shbuf_data + cur) + 1;
126 if (cur >= buf->size) 150 if (cur >= shbuf_size)
127 cur = 0; 151 cur = 0;
128 } 152 }
129#endif 153#endif
130 // release the lock on the log chain 154 unlock:
155 /* release the lock on the log chain */
131 sem_up(log_semid); 156 sem_up(log_semid);
132 157
133#if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING 158#if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING
134 for (j = 0; j < log_len; j += strlen(buf_data+j) + 1) { 159 for (i = 0; i < len_total; i += strlen(copy + i) + 1) {
135 fputs(buf_data + j, stdout); 160 fputs(copy + i, stdout);
136 } 161 }
137 free(buf_data); 162 free(copy);
138#endif 163#endif
139 } while (follow); 164 } while (follow);
140 165
141 shmdt(buf); 166 shmdt(shbuf);
142 167
143 fflush_stdout_and_exit(EXIT_SUCCESS); 168 fflush_stdout_and_exit(EXIT_SUCCESS);
144} 169}