From 8dc6b3e9475f8298d3b7c3e549b1c75dae4ec021 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Mon, 21 Aug 2023 13:59:21 +0200 Subject: [PATCH] On Vxworks clone std* file handles because they are thread specific --- modules/libcom/src/error/errlog.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/modules/libcom/src/error/errlog.c b/modules/libcom/src/error/errlog.c index 6ae2673232..30cf1a8575 100644 --- a/modules/libcom/src/error/errlog.c +++ b/modules/libcom/src/error/errlog.c @@ -92,10 +92,11 @@ static struct { epicsMutexId msgQueueLock; /* guarded by msgQueueLock */ - int atExit; int sevToLog; - int toConsole; - int ttyConsole; + int atExit:1; + int toConsole:1; + int ttyConsole:1; + int closeConsole:1; FILE *console; /* A loop counter maintained by errlogThread. */ @@ -466,7 +467,7 @@ int eltc(int yesno) { errlogInit(0); epicsMutexMustLock(pvt.msgQueueLock); - pvt.toConsole = yesno; + pvt.toConsole = yesno ? 1 : 0; epicsMutexUnlock(pvt.msgQueueLock); errlogFlush(); return 0; @@ -476,8 +477,22 @@ int errlogSetConsole(FILE *stream) { errlogInit(0); epicsMutexMustLock(pvt.msgQueueLock); + if (pvt.closeConsole) { + fclose(pvt.console); + } pvt.console = stream ? stream : stderr; pvt.ttyConsole = isATTY(pvt.console); +#ifdef vxWorks + /* The stderr/stdout we get may become invalid as they are thread specific. + * Also, the FDs are actually maps to some "real" FDs. + * Thus, we clone the pvt.console and link it with a dup of the "real" FD. + * The dup'ed FD will be closed when the FILE handle is fclosed. */ + if (fileno(pvt.console) <= 2) { + pvt.console = fdopen(dup(ioTaskStdGet(0, fileno(pvt.console))),"w"); + pvt.closeConsole = 1; + } else + pvt.closeConsole = 0; +#endif epicsMutexUnlock(pvt.msgQueueLock); /* make sure worker has stopped writing to the previous stream */ errlogSequence(); @@ -551,7 +566,13 @@ static void errlogInitPvt(void *arg) pvt.maxMsgSize = pconfig->maxMsgSize; ellInit(&pvt.listenerList); pvt.toConsole = TRUE; +#ifdef vxWorks + pvt.console = fdopen(dup(ioTaskStdGet(0, 2)),"w"); + pvt.closeConsole = 1; +#else pvt.console = stderr; + pvt.closeConsole = 0; +#endif pvt.ttyConsole = isATTY(stderr); pvt.waitForWork = epicsEventCreate(epicsEventEmpty); pvt.listenerLock = epicsMutexCreate();