summaryrefslogtreecommitdiffstats
path: root/iminternal.c
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2007-08-03 14:58:24 +0000
committerRainer Gerhards <rgerhards@adiscon.com>2007-08-03 14:58:24 +0000
commit51971302280a9789b794e6c0c534a6e02767a39e (patch)
tree39234fe7dab5a0ac5ff51f0d55b5e1a19e159c43 /iminternal.c
parentadbf55ece666c71e882c370a74efa0bbf3239226 (diff)
downloadrsyslog-51971302280a9789b794e6c0c534a6e02767a39e.tar.gz
rsyslog-51971302280a9789b794e6c0c534a6e02767a39e.tar.xz
rsyslog-51971302280a9789b794e6c0c534a6e02767a39e.zip
- I found out that we finally have problems with the (somewhat recursive)
call to logerror() that many of the modules do. I have not tried it, but I think things will become wild when we compile without pthread support. Threading prevents full recursion, so we have not seen any bad effects so far. However, the problems that I experienced in ommysl (that caused me to re-structure startWorker()) are actually rooted in this issue. I first thought to fix it via a module interace, but I now came to the conclusion that it is not more effort and much cleaner to do an internal error buffering class. This is implemented in errbuf.c/h. - I just noticed that this is not actually an error buf, but the core of an input module for all internal messages. As such, I implement it now as iminternal.c/h. Of course, there is no input module interface yet designed, but that doesn't matter. Worst-case, I need to re-write the im, best case I can use the im (at least partly) to define the interface. - added a few functions to the linkedlist class - error messages during startup are now buffered - so we do no longer need to think about how emergency logging might work. Actually, these are logged to whatever is instatiated in the log file. This enhances the chance that we will be able to drop the error message somewhere it is seen.
Diffstat (limited to 'iminternal.c')
-rw-r--r--iminternal.c189
1 files changed, 189 insertions, 0 deletions
diff --git a/iminternal.c b/iminternal.c
new file mode 100644
index 00000000..2f898e46
--- /dev/null
+++ b/iminternal.c
@@ -0,0 +1,189 @@
+/* iminternal.c
+ * This file set implements the internal messages input module for rsyslog.
+ * Note: we currently do not have an input module spec, but
+ * we will have one in the future. This module needs then to be
+ * adapted.
+ *
+ * File begun on 2007-08-03 by RGerhards
+ *
+ * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ */
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "rsyslog.h"
+#include "syslogd.h"
+#include "linkedlist.h"
+#include "iminternal.h"
+
+static linkedList_t llMsgs;
+
+
+/* destructs an iminternal object
+ */
+static rsRetVal iminternalDestruct(iminternal_t *pThis)
+{
+ DEFiRet;
+
+ assert(pThis != NULL);
+
+ if(pThis->pMsg != NULL)
+ MsgDestruct(pThis->pMsg);
+
+ free(pThis);
+
+ return iRet;
+}
+
+
+/* Construct an iminternal object
+ */
+static rsRetVal iminternalConstruct(iminternal_t **ppThis)
+{
+ DEFiRet;
+ iminternal_t *pThis;
+
+ assert(ppThis != NULL);
+
+ if((pThis = (iminternal_t*) calloc(1, sizeof(iminternal_t))) == NULL) {
+ ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
+ }
+
+finalize_it:
+ if(iRet != RS_RET_OK) {
+ if(pThis != NULL)
+ iminternalDestruct(pThis);
+ }
+
+ *ppThis = pThis;
+
+ return iRet;
+};
+
+
+/* add a message to the linked list
+ * Note: the pMsg reference counter is not incremented. Consequently,
+ * the caller must NOT decrement it. The caller actually hands over
+ * full ownership of the pMsg object.
+ * The interface of this function is modelled after syslogd/logmsg(),
+ * for which it is an "replacement".
+ */
+rsRetVal iminternalAddMsg(int pri, msg_t *pMsg, int flags)
+{
+ DEFiRet;
+ iminternal_t *pThis;
+
+ assert(pMsg != NULL);
+
+ CHKiRet(iminternalConstruct(&pThis));
+
+ pThis->pri = pri;
+ pThis->pMsg = pMsg;
+ pThis->flags = flags;
+
+ CHKiRet(llAppend(&llMsgs, NULL, (void*) pThis));
+
+finalize_it:
+ if(iRet != RS_RET_OK) {
+ dprintf("iminternalAddMsg() error %d - can not otherwise report this error, message lost\n", iRet);
+ if(pThis != NULL)
+ iminternalDestruct(pThis);
+ }
+
+ return iRet;
+}
+
+
+/* pull the first error message from the linked list, remove it
+ * from the list and return it to the caller. The caller is
+ * responsible for freeing the message!
+ */
+rsRetVal iminternalRemoveMsg(int *pPri, msg_t **ppMsg, int *pFlags)
+{
+ DEFiRet;
+ iminternal_t *pThis;
+ linkedListCookie_t llCookie = NULL;
+
+ assert(pPri != NULL);
+ assert(ppMsg != NULL);
+ assert(pFlags != NULL);
+
+ CHKiRet(llGetNextElt(&llMsgs, &llCookie, (void**) &pThis));
+ *pPri = pThis->pri;
+ *pFlags = pThis->flags;
+ *ppMsg = pThis->pMsg;
+ pThis->pMsg = NULL; /* we do no longer own it - important for destructor */
+
+ if(llDestroyRootElt(&llMsgs) != RS_RET_OK) {
+ dprintf("Root element of iminternal linked list could not be destroyed - there is "
+ "nothing we can do against it, we ignore it for now. Things may go wild "
+ "from here on. This is most probably a program logic error.\n");
+ }
+
+finalize_it:
+ return iRet;
+}
+
+/* tell the caller if we have any messages ready for processing.
+ * 0 means we have none, everything else means there is at least
+ * one message ready.
+ */
+rsRetVal iminternalHaveMsgReady(int* pbHaveOne)
+{
+ assert(pbHaveOne != NULL);
+
+ return llGetNumElts(&llMsgs, pbHaveOne);
+}
+
+
+/* initialize the iminternal subsystem
+ * must be called once at the start of the program
+ */
+rsRetVal modInitIminternal(void)
+{
+ DEFiRet;
+
+ iRet = llInit(&llMsgs, iminternalDestruct, NULL, NULL);
+
+ return iRet;
+}
+
+
+/* de-initialize the iminternal subsystem
+ * must be called once at the end of the program
+ * Note: the error list must have been pulled first. We do
+ * NOT care if there are any errors left - we simply destroy
+ * them.
+ */
+rsRetVal modExitIminternal(void)
+{
+ DEFiRet;
+
+ iRet = llDestroy(&llMsgs);
+
+ return iRet;
+}
+
+/*
+ * vi:set ai:
+ */