source: MondoRescue/branches/stable/mindi-busybox/sysklogd/logread.c@ 821

Last change on this file since 821 was 821, checked in by Bruno Cornec, 18 years ago

Addition of busybox 1.2.1 as a mindi-busybox new package
This should avoid delivering binary files in mindi not built there (Fedora and Debian are quite serious about that)

File size: 3.7 KB
Line 
1/* vi: set sw=4 ts=4: */
2/*
3 * circular buffer syslog implementation for busybox
4 *
5 * Copyright (C) 2000 by Gennady Feldman <gfeldman@gena01.com>
6 *
7 * Maintainer: Gennady Feldman <gfeldman@gena01.com> as of Mar 12, 2001
8 *
9 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
10 */
11
12
13#include "busybox.h"
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17#include <sys/ipc.h>
18#include <sys/types.h>
19#include <sys/sem.h>
20#include <sys/shm.h>
21#include <signal.h>
22#include <setjmp.h>
23#include <unistd.h>
24
25static const long KEY_ID = 0x414e4547; /*"GENA"*/
26
27static 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
34
35// Semaphore operation structures
36static struct sembuf SMrup[1] = {{0, -1, IPC_NOWAIT | SEM_UNDO}}; // set SMrup
37static struct sembuf SMrdn[2] = {{1, 0}, {0, +1, SEM_UNDO}}; // set SMrdn
38
39static int log_shmid = -1; // ipc shared memory id
40static int log_semid = -1; // ipc semaphore id
41static jmp_buf jmp_env;
42
43static void error_exit(const char *str);
44static void interrupted(int sig);
45
46/*
47 * sem_up - up()'s a semaphore.
48 */
49static inline void sem_up(int semid)
50{
51 if ( semop(semid, SMrup, 1) == -1 )
52 error_exit("semop[SMrup]");
53}
54
55/*
56 * sem_down - down()'s a semaphore
57 */
58static inline void sem_down(int semid)
59{
60 if ( semop(semid, SMrdn, 2) == -1 )
61 error_exit("semop[SMrdn]");
62}
63
64int logread_main(int argc, char **argv)
65{
66 int i;
67 int follow=0;
68
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 }
76
77 // handle interrupt signal
78 if (setjmp(jmp_env)) goto output_end;
79
80 // attempt to redefine ^C signal
81 signal(SIGINT, interrupted);
82
83 if ( (log_shmid = shmget(KEY_ID, 0, 0)) == -1)
84 error_exit("Can't find circular buffer");
85
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");
89
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");
92
93 // Suppose atomic memory move
94 i = follow ? buf->tail : buf->head;
95
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) {
107 sem_up(log_semid);
108 sleep(1); /* TODO: replace me with a sleep_on */
109 continue;
110 } else {
111 printf("<empty syslog>\n");
112 }
113 }
114
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);
127 }
128 i = buf->tail;
129
130#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;
136 }
137#endif
138 // release the lock on the log chain
139 sem_up(log_semid);
140
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);
146 }
147 free(buf_data);
148#endif
149 fflush(stdout);
150 } while (follow);
151
152output_end:
153 if (log_shmid != -1)
154 shmdt(buf);
155
156 return EXIT_SUCCESS;
157}
158
159static void interrupted(int sig){
160 signal(SIGINT, SIG_IGN);
161 longjmp(jmp_env, 1);
162}
163
164static void error_exit(const char *str){
165 bb_perror_msg(str);
166 //release all acquired resources
167 if (log_shmid != -1)
168 shmdt(buf);
169
170 exit(1);
171}
Note: See TracBrowser for help on using the repository browser.