diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2008-01-10 09:25:00 +0000 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2008-01-10 09:25:00 +0000 |
commit | 8a861afefac51ab495e5ba7946fe4fd986f0dd3c (patch) | |
tree | 700f398351f1a7568f10411ef3c7a9ee96dcc1fa /stream.c | |
parent | 79040541b70e95f0f00add4c9cafa08e9c411d79 (diff) | |
download | rsyslog-8a861afefac51ab495e5ba7946fe4fd986f0dd3c.tar.gz rsyslog-8a861afefac51ab495e5ba7946fe4fd986f0dd3c.tar.bz2 rsyslog-8a861afefac51ab495e5ba7946fe4fd986f0dd3c.zip |
data record support added to stream output writer
Diffstat (limited to 'stream.c')
-rw-r--r-- | stream.c | 90 |
1 files changed, 71 insertions, 19 deletions
@@ -132,26 +132,24 @@ rsRetVal strmNextFile(strm_t *pThis) { DEFiRet; -dbgprintf("strmNextFile in\n"); assert(pThis != NULL); assert(pThis->iMaxFiles != 0); CHKiRet(strmCloseFile(pThis)); - /* we do modulo 1,000,000 so that the file number is always at most 6 digits. If we have a million - * or more strm files, something is awfully wrong and it is OK if we run into problems in that - * situation ;) -- rgerhards, 2008-01-09 + /* we do modulo operation to ensure we obej the iMaxFile property. This will always + * result in a file number lower than iMaxFile, so it if wraps, the name is back to + * 0, which results in the first file being overwritten. Not desired for queues, so + * make sure their iMaxFiles is large enough. But it is well-desired for other + * use cases, e.g. a circular output log file. -- rgerhards, 2008-01-10 */ pThis->iCurrFNum = (pThis->iCurrFNum + 1) % pThis->iMaxFiles; finalize_it: -dbgprintf("strmNextFile out %d\n", iRet); return iRet; } -/*** buffered read functions for strm files ***/ - /* logically "read" a character from a file. What actually happens is that * data is taken from the buffer. Only if the buffer is full, data is read * directly from file. In that case, a read is performed blockwise. @@ -225,8 +223,8 @@ rsRetVal strmUnreadChar(strm_t *pThis, uchar c) #if 0 /* we have commented out the code below because we would like to preserve it. It * is currently not needed, but may be useful if we implemented a bufferred file - * class. - * rgerhards, 2008-01-07 + * class. NOTE: YOU MUST REVIEW THIS CODE BEFORE ACTIVATION. It may be pretty + * outdated! -- rgerhards, 2008-01-10 */ /* read a line from a strm file. A line is terminated by LF. The LF is read, but it * is not returned in the buffer (it is discared). The caller is responsible for @@ -263,11 +261,6 @@ finalize_it: #endif /* #if 0 - saved code */ -/*** end buffered read functions for strm files ***/ - - -/* --------------- end type-specific handlers -------------------- */ - /* Standard-Constructor for the strm object */ @@ -321,6 +314,24 @@ rsRetVal strmDestruct(strm_t *pThis) return iRet; } + +/* check if we need to open a new file (in output mode only). + * The decision is based on file size AND record delimition state. + */ +static rsRetVal strmCheckNextOutputFile(strm_t *pThis) +{ + DEFiRet; + + if(pThis->iCurrOffs >= pThis->iMaxFileSize) { + dbgprintf("Stream 0x%lx: max file size %ld reached for %d, now %ld - starting new file\n", + (unsigned long) pThis, (long) pThis->iMaxFileSize, pThis->fd, (long) pThis->iCurrOffs); + CHKiRet(strmNextFile(pThis)); + } + +finalize_it: + return iRet; +} + /* write memory buffer to a stream object. */ static rsRetVal strmWriteInternal(strm_t *pThis, uchar *pBuf, size_t lenBuf) @@ -341,11 +352,7 @@ dbgprintf("strmWriteInternal()\n"); /* TODO: handle error case -- rgerhards, 2008-01-07 */ pThis->iCurrOffs += iWritten; - if(pThis->iCurrOffs >= pThis->iMaxFileSize) { - dbgprintf("Stream 0x%lx: max file size %ld reached for %d, now %ld - starting new file\n", - (unsigned long) pThis, (long) pThis->iMaxFileSize, pThis->fd, (long) pThis->iCurrOffs); - CHKiRet(strmNextFile(pThis)); - } + CHKiRet(strmCheckNextOutputFile(pThis)); finalize_it: return iRet; @@ -477,6 +484,51 @@ finalize_it: } +/* support for data records + * The stream class is able to write to multiple files. However, there are + * situation (actually quite common), where a single data record should not + * be split across files. This may be problematic if multiple stream write + * calls are used to create the record. To support that, we provide the + * bInRecord status variable. If it is set, no file spliting occurs. Once + * it is set to 0, a check is done if a split is necessary and it then + * happens. For a record-oriented caller, the proper sequence is: + * + * strmRecordBegin() + * strmWrite...() + * strmRecordEnd() + * + * Please note that records do not affect the writing of output buffers. They + * are always written when full. The only thing affected is circular files + * creation. So it is safe to write large records. + * + * IMPORTANT: RecordBegin() can not be nested! It is a programming error + * if RecordBegin() is called while already in a record! + * + * rgerhards, 2008-01-10 + */ +rsRetVal strmRecordBegin(strm_t *pThis) +{ + assert(pThis != NULL); + assert(pThis->bInRecord == 0); + pThis->bInRecord = 1; + return RS_RET_OK; +} + +rsRetVal strmRecordEnd(strm_t *pThis) +{ + DEFiRet; + assert(pThis != NULL); + assert(pThis->bInRecord == 1); + + pThis->bInRecord = 0; + iRet = strmCheckNextOutputFile(pThis); /* check if we need to switch files */ + + return iRet; +} +/* end stream record support functions */ + + + /* Initialize the stream class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-01-09 |