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

Last change on this file since 821 was 821, checked in by Bruno Cornec, 14 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.