summaryrefslogtreecommitdiffstats
path: root/tools/omfile.c
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2009-03-24 16:25:54 +0100
committerRainer Gerhards <rgerhards@adiscon.com>2009-03-24 16:25:54 +0100
commit7269efe60a2071e17f68f96b6416acaefeb7068d (patch)
tree6c9b53b253a19b785afa8f780650066aa9a5bbe4 /tools/omfile.c
parentde3341a64131092fabb3a1c60adb77e70bdb7fb6 (diff)
parent508a9e0cef064b082cd9e13aecd9d6c0f1f51977 (diff)
downloadrsyslog-7269efe60a2071e17f68f96b6416acaefeb7068d.tar.gz
rsyslog-7269efe60a2071e17f68f96b6416acaefeb7068d.tar.xz
rsyslog-7269efe60a2071e17f68f96b6416acaefeb7068d.zip
Merge branch 'omfile-errHandler'
Conflicts: ChangeLog
Diffstat (limited to 'tools/omfile.c')
-rw-r--r--tools/omfile.c81
1 files changed, 54 insertions, 27 deletions
diff --git a/tools/omfile.c b/tools/omfile.c
index ea91d6ef..65306846 100644
--- a/tools/omfile.c
+++ b/tools/omfile.c
@@ -387,9 +387,12 @@ static void dynaFileFreeCache(instanceData *pData)
* file access, which, among others, means the the file wil be opened
* and any directories in between will be created (based on config, of
* course). -- rgerhards, 2008-10-22
+ * changed to iRet interface - 2009-03-19
*/
-static void prepareFile(instanceData *pData, uchar *newFileName)
+static rsRetVal
+prepareFile(instanceData *pData, uchar *newFileName)
{
+ DEFiRet;
if(pData->fileType == eTypePIPE) {
pData->fd = open((char*) pData->f_fname, O_RDWR|O_NONBLOCK);
FINALIZE; /* we are done in this case */
@@ -403,14 +406,14 @@ static void prepareFile(instanceData *pData, uchar *newFileName)
pData->fd = -1;
/* file does not exist, create it (and eventually parent directories */
if(pData->bCreateDirs) {
- /* we fist need to create parent dirs if they are missing
+ /* We first need to create parent dirs if they are missing.
* We do not report any errors here ourselfs but let the code
* fall through to error handler below.
*/
if(makeFileParentDirs(newFileName, strlen((char*)newFileName),
pData->fDirCreateMode, pData->dirUID,
pData->dirGID, pData->bFailOnChown) != 0) {
- return; /* we give up */
+ ABORT_FINALIZE(RS_RET_ERR); /* we give up */
}
}
/* no matter if we needed to create directories or not, we now try to create
@@ -422,8 +425,7 @@ static void prepareFile(instanceData *pData, uchar *newFileName)
/* check and set uid/gid */
if(pData->fileUID != (uid_t)-1 || pData->fileGID != (gid_t) -1) {
/* we need to set owner/group */
- if(fchown(pData->fd, pData->fileUID,
- pData->fileGID) != 0) {
+ if(fchown(pData->fd, pData->fileUID, pData->fileGID) != 0) {
if(pData->bFailOnChown) {
int eSave = errno;
close(pData->fd);
@@ -438,11 +440,17 @@ static void prepareFile(instanceData *pData, uchar *newFileName)
}
}
finalize_it:
- if((pData->fd) != 0 && isatty(pData->fd)) {
+ /* this was "pData->fd != 0", which I think was a bug. I guess 0 was intended to mean
+ * non-open file descriptor. Anyhow, I leave this comment for the time being to that if
+ * problems surface, one at least knows what happened. -- rgerhards, 2009-03-19
+ */
+ if(pData->fd != -1 && isatty(pData->fd)) {
DBGPRINTF("file %d is a tty file\n", pData->fd);
pData->fileType = eTypeTTY;
untty();
}
+
+ RETiRet;
}
@@ -461,6 +469,8 @@ static int prepareDynFile(instanceData *pData, uchar *newFileName, unsigned iMsg
int i;
int iFirstFree;
dynaFileCacheEntry **pCache;
+
+ BEGINfunc
ASSERT(pData != NULL);
ASSERT(newFileName != NULL);
@@ -522,7 +532,7 @@ static int prepareDynFile(instanceData *pData, uchar *newFileName, unsigned iMsg
}
/* Ok, we finally can open the file */
- prepareFile(pData, newFileName);
+ prepareFile(pData, newFileName); /* ignore exact error, we check fd below */
/* file is either open now or an error state set */
if(pData->fd == -1) {
@@ -546,6 +556,8 @@ static int prepareDynFile(instanceData *pData, uchar *newFileName, unsigned iMsg
pData->iCurrElt = iFirstFree;
DBGPRINTF("Added new entry %d for file cache, file '%s'.\n", iFirstFree, newFileName);
+ ENDfunc
+
return 0;
}
@@ -557,6 +569,7 @@ static int prepareDynFile(instanceData *pData, uchar *newFileName, unsigned iMsg
static rsRetVal writeFile(uchar **ppString, unsigned iMsgOpts, instanceData *pData)
{
off_t actualFileSize;
+ int iLenWritten;
DEFiRet;
ASSERT(pData != NULL);
@@ -566,9 +579,14 @@ static rsRetVal writeFile(uchar **ppString, unsigned iMsgOpts, instanceData *pDa
*/
if(pData->bDynamicName) {
if(prepareDynFile(pData, ppString[1], iMsgOpts) != 0)
- ABORT_FINALIZE(RS_RET_ERR);
- } else if(pData->fd == -1) {
- prepareFile(pData, pData->f_fname);
+ ABORT_FINALIZE(RS_RET_SUSPENDED); /* whatever the failure was, we need to retry */
+ }
+
+ if(pData->fd == -1) {
+ rsRetVal iRetLocal;
+ iRetLocal = prepareFile(pData, pData->f_fname);
+ if((iRetLocal != RS_RET_OK) || (pData->fd == -1))
+ ABORT_FINALIZE(RS_RET_SUSPENDED); /* whatever the failure was, we need to retry */
}
/* create the message based on format specified */
@@ -604,41 +622,47 @@ again:
}
}
- if (write(pData->fd, ppString[0], strlen((char*)ppString[0])) < 0) {
+ iLenWritten = write(pData->fd, ppString[0], strlen((char*)ppString[0]));
+//dbgprintf("lenwritten: %d\n", iLenWritten);
+ if(iLenWritten < 0) {
int e = errno;
+ char errStr[1024];
+ rs_strerror_r(errno, errStr, sizeof(errStr));
+ DBGPRINTF("log file (%d) write error %d: %s\n", pData->fd, e, errStr);
- /* If a named pipe is full, just ignore it for now
- - mrn 24 May 96 */
- if (pData->fileType == eTypePIPE && e == EAGAIN)
- ABORT_FINALIZE(RS_RET_OK);
-
- /* If the filesystem is filled up, just ignore
- * it for now and continue writing when possible
- * based on patch for sysklogd by Martin Schulze on 2007-05-24
- */
- if (pData->fileType == eTypeFILE && e == ENOSPC)
- ABORT_FINALIZE(RS_RET_OK);
+ /* If a named pipe is full, we suspend this action for a while */
+ if(pData->fileType == eTypePIPE && e == EAGAIN)
+ ABORT_FINALIZE(RS_RET_SUSPENDED);
- (void) close(pData->fd);
+ close(pData->fd);
+ pData->fd = -1; /* tell that fd is no longer open! */
+ if(pData->bDynamicName && pData->iCurrElt != -1) {
+ /* in this case, we need to invalidate the name in the cache, too
+ * otherwise, an invalid fd may show up if we had a file name change.
+ * rgerhards, 2009-03-19
+ */
+ pData->dynCache[pData->iCurrElt]->fd = -1;
+ }
/* Check for EBADF on TTY's due to vhangup()
* Linux uses EIO instead (mrn 12 May 96)
*/
if((pData->fileType == eTypeTTY || pData->fileType == eTypeCONSOLE)
#ifdef linux
- && e == EIO) {
+ && e == EIO
#else
- && e == EBADF) {
+ && e == EBADF
#endif
+ ) {
pData->fd = open((char*) pData->f_fname, O_WRONLY|O_APPEND|O_NOCTTY);
if (pData->fd < 0) {
- iRet = RS_RET_DISABLE_ACTION;
+ iRet = RS_RET_SUSPENDED;
errmsg.LogError(0, NO_ERRCODE, "%s", pData->f_fname);
} else {
untty();
goto again;
}
} else {
- iRet = RS_RET_DISABLE_ACTION;
+ iRet = RS_RET_SUSPENDED;
errno = e;
errmsg.LogError(0, NO_ERRCODE, "%s", pData->f_fname);
}
@@ -790,6 +814,9 @@ CODESTARTparseSelectorAct
pData->dirUID = dirUID;
pData->dirGID = dirGID;
+ /* at this stage, we ignore the return value of prepareFile, this is taken
+ * care of in later steps. -- rgerhards, 2009-03-19
+ */
prepareFile(pData, pData->f_fname);
if(pData->fd < 0 ) {