diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2012-11-15 10:08:26 +0100 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2012-11-15 10:08:26 +0100 |
commit | 3475caa394c4d50baa34b407b7bdea0c37f2b83c (patch) | |
tree | 307cdc36d14b17403c84ce6a2ecc2feb44fbffde | |
parent | 46dbd8dda97947713d76e814b3053760a106d63f (diff) | |
download | rsyslog-3475caa394c4d50baa34b407b7bdea0c37f2b83c.tar.gz rsyslog-3475caa394c4d50baa34b407b7bdea0c37f2b83c.tar.bz2 rsyslog-3475caa394c4d50baa34b407b7bdea0c37f2b83c.zip |
refactor stream.h; fix some issues with last patch
Most importantly, the last patch for imfile contained a number
of glitches, which are fixed by this commit (a memory leak under
unusual conditions, partial message loss when rsyslog was
terminated in the interim & mixing file data to the wrong files
when multiple monitors were used [due to static variable]). The
commit is actually a re-write of the patch, based on its core
idea.
Also some other minor cleanup was done.
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | runtime/stream.c | 41 | ||||
-rw-r--r-- | runtime/stream.h | 1 |
3 files changed, 18 insertions, 26 deletions
@@ -48,7 +48,7 @@ Version 7.2.2 [v7-stable] 2012-10-?? the next polling cycle. This is now changed so that the partial content is saved until the complete line is read. Note that the patch affects only read mode 0. - Thanks to Milan Bartos for providing the patch. + Thanks to Milan Bartos for providing the base idea for the solution. ---------------------------------------------------------------------------- Version 7.2.1 [v7-stable] 2012-10-29 - bugfix: ruleset()-object did only support a single statement diff --git a/runtime/stream.c b/runtime/stream.c index 52d143de..193d14db 100644 --- a/runtime/stream.c +++ b/runtime/stream.c @@ -585,46 +585,33 @@ strmReadLine(strm_t *pThis, cstr_t **ppCStr, int mode) * mode = 2 LF <not whitespace> mode, a log line starts at the beginning of a line, but following lines that are indented are part of the same log entry * This modal interface is not nearly as flexible as being able to define a regex for when a new record starts, but it's also not nearly as hard (or as slow) to implement */ - DEFiRet; uchar c; uchar finished; - rsRetVal readCharRet; - - static cstr_t *prevCStr = NULL; + DEFiRet; ASSERT(pThis != NULL); ASSERT(ppCStr != NULL); CHKiRet(cstrConstruct(ppCStr)); + CHKiRet(strmReadChar(pThis, &c)); + if(mode == 0) { /* append previous message to current message if necessary */ - if (prevCStr != NULL) { - CHKiRet(cstrAppendCStr(*ppCStr, prevCStr)); + if(pThis->prevLineSegment != NULL) { + CHKiRet(cstrAppendCStr(*ppCStr, pThis->prevLineSegment)); + cstrDestruct(&pThis->prevLineSegment); } - - CHKiRet(strmReadChar(pThis, &c)); - if (mode == 0){ - while(c != '\n') { + while(c != '\n') { CHKiRet(cstrAppendChar(*ppCStr, c)); - readCharRet = strmReadChar(pThis, &c); - - /* end of file has been reached without \n */ - if (readCharRet == RS_RET_EOF) { - CHKiRet(rsCStrConstructFromCStr(&prevCStr, *ppCStr)); + if(readCharRet == RS_RET_EOF) {/* end of file reached without \n? */ + CHKiRet(rsCStrConstructFromCStr(&pThis->prevLineSegment, *ppCStr)); } - CHKiRet(readCharRet); } CHKiRet(cstrFinalize(*ppCStr)); - /* message has been finalized, destruct message from previous */ - if (prevCStr) { - cstrDestruct(&prevCStr); - prevCStr = NULL; - } - } - if (mode == 1){ + } else if(mode == 1) { finished=0; while(finished == 0){ if(c != '\n') { @@ -645,8 +632,7 @@ strmReadLine(strm_t *pThis, cstr_t **ppCStr, int mode) } } CHKiRet(cstrFinalize(*ppCStr)); - } - if (mode == 2){ + } else if(mode == 2) { /* indented follow-up lines */ finished=0; while(finished == 0){ @@ -699,6 +685,7 @@ BEGINobjConstruct(strm) /* be sure to specify the object type also in END macro! pThis->sType = STREAMTYPE_FILE_SINGLE; pThis->sIOBufSize = glblGetIOBufSize(); pThis->tOpenMode = 0600; + pThis->prevLineSegment = NULL; ENDobjConstruct(strm) @@ -1606,6 +1593,8 @@ static rsRetVal strmSerialize(strm_t *pThis, strm_t *pStrm) l = pThis->iCurrOffs; objSerializeSCALAR_VAR(pStrm, iCurrOffs, INT64, l); + objSerializePTR(pStrm, prevLineSegment, PSZ); + CHKiRet(obj.EndSerialize(pStrm)); finalize_it: @@ -1711,6 +1700,8 @@ static rsRetVal strmSetProperty(strm_t *pThis, var_t *pProp) CHKiRet(strmSetiFileNumDigits(pThis, pProp->val.num)); } else if(isProp("bDeleteOnClose")) { CHKiRet(strmSetbDeleteOnClose(pThis, pProp->val.num)); + } else if(isProp("prevLineSegment")) { + CHKiRet(rsCStrConstructFromCStr(&pThis->prevLineSegment, pProp->val.pStr)); } finalize_it: diff --git a/runtime/stream.h b/runtime/stream.h index a01929f2..78dbc0d6 100644 --- a/runtime/stream.h +++ b/runtime/stream.h @@ -141,6 +141,7 @@ typedef struct strm_s { off_t iSizeLimit; /* file size limit, 0 = no limit */ uchar *pszSizeLimitCmd; /* command to carry out when size limit is reached */ sbool bIsTTY; /* is this a tty file? */ + cstr_t *prevLineSegment; /* for ReadLine, previous, unwritten part of file */ } strm_t; |