Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | /* vi: set sw=4 ts=4: */ /* * circular buffer syslog implementation for busybox * * Copyright (C) 2000 by Gennady Feldman <gfeldman@gena01.com> * * Maintainer: Gennady Feldman <gfeldman@gena01.com> as of Mar 12, 2001 * * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ #include "libbb.h" #include <sys/ipc.h> #include <sys/sem.h> #include <sys/shm.h> #define DEBUG 0 enum { KEY_ID = 0x414e4547 }; /* "GENA" */ static struct shbuf_ds { int32_t size; // size of data written int32_t head; // start of message list int32_t tail; // end of message list char data[1]; // data/messages } *buf; // shared memory pointer // Semaphore operation structures static struct sembuf SMrup[1] = {{0, -1, IPC_NOWAIT | SEM_UNDO}}; // set SMrup static struct sembuf SMrdn[2] = {{1, 0}, {0, +1, SEM_UNDO}}; // set SMrdn static void error_exit(const char *str) ATTRIBUTE_NORETURN; static void error_exit(const char *str) { //release all acquired resources shmdt(buf); bb_perror_msg_and_die(str); } /* * sem_up - up()'s a semaphore. */ static void sem_up(int semid) { if (semop(semid, SMrup, 1) == -1) error_exit("semop[SMrup]"); } static void interrupted(int sig ATTRIBUTE_UNUSED) { signal(SIGINT, SIG_IGN); shmdt(buf); exit(0); } int logread_main(int argc, char **argv); int logread_main(int argc, char **argv) { int cur; int log_semid; /* ipc semaphore id */ int log_shmid; /* ipc shared memory id */ smallint follow = getopt32(argc, argv, "f"); log_shmid = shmget(KEY_ID, 0, 0); if (log_shmid == -1) bb_perror_msg_and_die("can't find syslogd buffer"); // Attach shared memory to our char* buf = shmat(log_shmid, NULL, SHM_RDONLY); if (buf == NULL) bb_perror_msg_and_die("can't access syslogd buffer"); log_semid = semget(KEY_ID, 0, 0); if (log_semid == -1) error_exit("can't get access to semaphores for syslogd buffer"); // attempt to redefine ^C signal signal(SIGINT, interrupted); // Suppose atomic memory move cur = follow ? buf->tail : buf->head; do { #if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING char *buf_data; int log_len, j; #endif if (semop(log_semid, SMrdn, 2) == -1) error_exit("semop[SMrdn]"); if (DEBUG) printf("head:%i cur:%d tail:%i size:%i\n", buf->head, cur, buf->tail, buf->size); if (buf->head == buf->tail || cur == buf->tail) { if (follow) { sem_up(log_semid); fflush(stdout); sleep(1); /* TODO: replace me with a sleep_on */ continue; } puts("<empty syslog>"); } // Read Memory #if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING log_len = buf->tail - cur; if (log_len < 0) log_len += buf->size; buf_data = xmalloc(log_len); if (buf->tail >= cur) j = log_len; else j = buf->size - cur; memcpy(buf_data, buf->data + cur, j); if (buf->tail < cur) memcpy(buf_data + buf->size - cur, buf->data, buf->tail); cur = buf->tail; #else while (cur != buf->tail) { fputs(buf->data + cur, stdout); cur += strlen(buf->data + cur) + 1; if (cur >= buf->size) cur = 0; } #endif // release the lock on the log chain sem_up(log_semid); #if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING for (j = 0; j < log_len; j += strlen(buf_data+j) + 1) { fputs(buf_data + j, stdout); } free(buf_data); #endif } while (follow); shmdt(buf); fflush_stdout_and_exit(EXIT_SUCCESS); } |