int size; // size of data written
int head; // start of message list
int tail; // end of message list
- int pre_tail; //added by echo for pre-end message
char data[1]; // data/messages
} *buf = NULL; // shared memory pointer
buf->size = shm_size - sizeof(*buf);
buf->head = buf->tail = 0;
- buf->pre_tail = 0; //added by echo
// we'll trust the OS to set initial semval to 0 (let's hope)
if ((s_semid = semget(KEY_ID, 2, IPC_CREAT | IPC_EXCL | 1023)) == -1) {
}
}
-int find_last_zero(char* ptr,int len){
- int i=0;
- int target = 0;
- for(;i<len;i++){
- if(!ptr[i])
- target = i;
- }
- return target;
-}
-
-/* write message to buffer */
-void circ_message(const char *msg){
- int l=strlen(msg)+1; /* count the whole message w/ '\0' included */
-
- sem_down(s_semid);
- if(buf->tail){
- /*
- * Circular Buffer Algorithm:
- * --------------------------
- *
- * Start-off w/ empty buffer of specific size SHM_SIZ
- * Start filling it up w/ messages. I use '\0' as separator to break up mess
-ages.
- * This is also very handy since we can do printf on message.
- *
- * Once the buffer is full we need to get rid of the first message in buffer
- and
- * insert the new message. (Note: if the message being added is >1 message t
-hen
- * we will need to "remove" >1 old message from the buffer). The way this is
- done
- * is the following:
- * When we reach the end of the buffer we set a mark and start from the
- beginning.
- * Now what about the beginning and end of the buffer? Well we have the
- "head"
- * index/pointer which is the starting point for the messages and we ha
-ve "tail"
- * index/pointer which is the ending point for the messages. When we "d
-isplay" the
- * messages we start from the beginning and continue until we reach "tail". If we
- * reach end of buffer, then we just start from the beginning (offset 0). "head" and
- * "tail" are actually offsets from the beginning of the buffer.
- *
- * Note: This algorithm uses Linux IPC mechanism w/ shared memory and semaphores to provide
- * a threasafe way of handling shared memory operations.
- */
- if(buf->tail + l >buf->size){
- memmove(buf->data+l,buf->data,buf->size-l);
- memcpy(buf->data,msg,l);
- buf->tail = buf->pre_tail;
- buf->pre_tail = find_last_zero(buf->data+l,buf->size-l);
- buf->pre_tail += l;
- buf->tail += l;
- }
- else{
- memmove(buf->data+l,buf->data,buf->tail);
- memcpy(buf->data,msg,l);
- buf->pre_tail += l;
- buf->tail += l;
- }
- }
- else{
- memcpy(buf->data,msg,l);
- buf->pre_tail = 0;
- buf->tail += l;
- }
-
- sem_up(s_semid);
-}
-
-#if 0
-
/* write message to buffer */
void circ_message(const char *msg)
{
sem_down(s_semid);
- if(buf->tail){
/*
* Circular Buffer Algorithm:
* --------------------------
} else { /* show an error message to know we messed up? */
printf("Weird! Can't find the terminator token??? \n");
buf->head = 0;
- if(buf->tail + l >buf->size){
- memmove(buf->data+l,buf->data,buf->size-l);
- memcpy(buf->data,msg,l);
- buf->tail = buf->pre_tail;
- buf->pre_tail = find_last_zero(buf->data+l,buf->size-l);
- buf->pre_tail += l;
- buf->tail += l;
- }
- else{
- memmove(buf->data+l,buf->data,buf->tail);
- memcpy(buf->data,msg,l);
- buf->pre_tail += l;
- buf->tail += l;
}
}
- else{
- memcpy(buf->data,msg,l);
- buf->pre_tail = 0;
- buf->tail += l;
}
-
+ /* in other cases no overflows have been done yet, so we don't care! */
+ /* we should be ok to append the message now */
+ strncpy(buf->data + buf->tail, msg, l); /* append our message */
+ buf->tail += l; /* count full message w/ '\0' terminating char */
+ } else {
+ /* we need to break up the message and "circle" it around */
+ char *c;
+ int k = buf->tail + l - buf->size; /* count # of bytes we don't fit */
+
+ /* We need to move HEAD! This is always the case since we are going
+ * to "circle" the message.
+ */
+ c = memchr(buf->data + k, '\0', buf->size - k);
+
+ if (c != NULL) { /* if we don't have '\0'??? weird!!! */
+ /* move head pointer */
+ buf->head = c - buf->data + 1;
+
+ /* now write the first part of the message */
+ strncpy(buf->data + buf->tail, msg, l - k - 1);
+
+ /* ALWAYS terminate end of buffer w/ '\0' */
+ buf->data[buf->size - 1] = '\0';
+
+ /* now write out the rest of the string to the beginning of the buffer */
+ strcpy(buf->data, &msg[l - k - 1]);
+
+ /* we need to place the TAIL at the end of the message */
+ buf->tail = k + 1;
+ } else {
+ printf
+ ("Weird! Can't find the terminator token from the beginning??? \n");
+ buf->head = buf->tail = 0; /* reset buffer, since it's probably corrupted */
+ }
+
+ }
sem_up(s_semid);
}
-#endif
#endif /* CONFIG_FEATURE_IPC_SYSLOG */
/* Note: There is also a function called "message()" in init.c */