This is Unofficial EPICS BASE Doxygen Site
errlog.c File Reference
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include "adjustment.h"
#include "dbDefs.h"
#include "epicsThread.h"
#include "cantProceed.h"
#include "epicsMutex.h"
#include "epicsEvent.h"
#include "epicsInterrupt.h"
#include "errMdef.h"
#include "errSymTbl.h"
#include "ellLib.h"
#include "errlog.h"
#include "epicsStdio.h"
#include "epicsExit.h"
+ Include dependency graph for errlog.c:

Go to the source code of this file.

Classes

struct  listenerNode
 
struct  msgNode
 
struct  initArgs
 

Macros

#define ERRLOG_INIT
 
#define BUFFER_SIZE   1280
 
#define MAX_MESSAGE_SIZE   256
 

Typedefs

typedef struct listenerNode listenerNode
 
typedef struct msgNode msgNode
 

Functions

int errlogPrintf (const char *pFormat,...)
 
int errlogVprintf (const char *pFormat, va_list pvar)
 
int errlogMessage (const char *message)
 
int errlogPrintfNoConsole (const char *pFormat,...)
 
int errlogVprintfNoConsole (const char *pFormat, va_list pvar)
 
int errlogSevPrintf (errlogSevEnum severity, const char *pFormat,...)
 
int errlogSevVprintf (errlogSevEnum severity, const char *pFormat, va_list pvar)
 
const char * errlogGetSevEnumString (errlogSevEnum severity)
 
void errlogSetSevToLog (errlogSevEnum severity)
 
errlogSevEnum errlogGetSevToLog (void)
 
void errlogAddListener (errlogListener listener, void *pPrivate)
 
int errlogRemoveListeners (errlogListener listener, void *pPrivate)
 
int eltc (int yesno)
 
int errlogSetConsole (FILE *stream)
 
void errPrintf (long status, const char *pFileName, int lineno, const char *pformat,...)
 
int errlogInit2 (int bufsize, int maxMsgSize)
 
int errlogInit (int bufsize)
 
void errlogFlush (void)
 

Variables

int errVerbose = 0
 

Macro Definition Documentation

#define BUFFER_SIZE   1280

Definition at line 37 of file errlog.c.

#define ERRLOG_INIT

Definition at line 21 of file errlog.c.

#define MAX_MESSAGE_SIZE   256

Definition at line 38 of file errlog.c.

Typedef Documentation

typedef struct listenerNode listenerNode
typedef struct msgNode msgNode

Function Documentation

int eltc ( int  yesno)

Definition at line 368 of file errlog.c.

369 {
370  errlogInit(0);
371  errlogFlush();
372  pvtData.toConsole = yesno;
373  return 0;
374 }
void errlogFlush(void)
Definition: errlog.c:529
int errlogInit(int bufsize)
Definition: errlog.c:524
void errlogAddListener ( errlogListener  listener,
void *  pPrivate 
)

Definition at line 317 of file errlog.c.

318 {
319  listenerNode *plistenerNode;
320 
321  errlogInit(0);
322  if (pvtData.atExit)
323  return;
324 
325  plistenerNode = callocMustSucceed(1,sizeof(listenerNode),
326  "errlogAddListener");
327  epicsMutexMustLock(pvtData.listenerLock);
328  plistenerNode->listener = listener;
329  plistenerNode->pPrivate = pPrivate;
330  ellAdd(&pvtData.listenerList,&plistenerNode->node);
331  epicsMutexUnlock(pvtData.listenerLock);
332 }
ELLNODE node
Definition: errlog.c:52
void * pPrivate
Definition: errlog.c:54
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
Release the semaphore.
Definition: epicsMutex.cpp:140
int errlogInit(int bufsize)
Definition: errlog.c:524
struct listener listener
void ellAdd(ELLLIST *pList, ELLNODE *pNode)
Adds a node to the end of a list.
Definition: ellLib.c:24
LIBCOM_API void * callocMustSucceed(size_t count, size_t size, const char *msg)
A calloc() that never returns NULL.
Definition: cantProceed.c:22
errlogListener listener
Definition: errlog.c:53
#define epicsMutexMustLock(ID)
Claim a semaphore (see epicsMutexLock()).
Definition: epicsMutex.h:214
void errlogFlush ( void  )

Definition at line 529 of file errlog.c.

530 {
531  int count;
532 
533  errlogInit(0);
534  if (pvtData.atExit)
535  return;
536 
537  /*If nothing in queue dont wake up errlogThread*/
538  epicsMutexMustLock(pvtData.msgQueueLock);
539  count = ellCount(&pvtData.msgQueue);
540  epicsMutexUnlock(pvtData.msgQueueLock);
541  if (count <= 0)
542  return;
543 
544  /*must let errlogThread empty queue*/
545  epicsMutexMustLock(pvtData.flushLock);
546  epicsEventSignal(pvtData.flush);
547  epicsEventSignal(pvtData.waitForWork);
548  epicsEventMustWait(pvtData.waitForFlush);
549  epicsMutexUnlock(pvtData.flushLock);
550 }
#define ellCount(PLIST)
Report the number of nodes in a list.
Definition: ellLib.h:84
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
Release the semaphore.
Definition: epicsMutex.cpp:140
LIBCOM_API void epicsEventMustWait(epicsEventId id)
Wait for an event (see epicsEventWait()).
Definition: epicsEvent.cpp:123
int errlogInit(int bufsize)
Definition: errlog.c:524
#define epicsEventSignal(ID)
A synonym for epicsEventTrigger().
Definition: epicsEvent.h:172
#define epicsMutexMustLock(ID)
Claim a semaphore (see epicsMutexLock()).
Definition: epicsMutex.h:214
const char* errlogGetSevEnumString ( errlogSevEnum  severity)

Definition at line 297 of file errlog.c.

298 {
299  errlogInit(0);
300  if (severity > 3)
301  return "unknown";
302  return errlogSevEnumString[severity];
303 }
int errlogInit(int bufsize)
Definition: errlog.c:524
LIBCOM_API const char * errlogSevEnumString[]
errlogSevEnum errlogGetSevToLog ( void  )

Definition at line 311 of file errlog.c.

312 {
313  errlogInit(0);
314  return pvtData.sevToLog;
315 }
int errlogInit(int bufsize)
Definition: errlog.c:524
int errlogInit ( int  bufsize)

Definition at line 524 of file errlog.c.

525 {
526  return errlogInit2(bufsize, MAX_MESSAGE_SIZE);
527 }
int errlogInit2(int bufsize, int maxMsgSize)
Definition: errlog.c:500
#define MAX_MESSAGE_SIZE
Definition: errlog.c:38
int errlogInit2 ( int  bufsize,
int  maxMsgSize 
)

Definition at line 500 of file errlog.c.

501 {
502  static epicsThreadOnceId errlogOnceFlag = EPICS_THREAD_ONCE_INIT;
503  struct initArgs config;
504 
505  if (pvtData.atExit)
506  return 0;
507 
508  if (bufsize < BUFFER_SIZE)
510  config.bufsize = bufsize;
511 
514  config.maxMsgSize = maxMsgSize;
515 
516  epicsThreadOnce(&errlogOnceFlag, errlogInitPvt, &config);
517  if (pvtData.errlogInitFailed) {
518  fprintf(stderr,"errlogInit failed\n");
519  exit(1);
520  }
521  return 0;
522 }
int bufsize
Definition: errlog.c:461
#define MAX_MESSAGE_SIZE
Definition: errlog.c:38
#define BUFFER_SIZE
Definition: errlog.c:37
#define EPICS_THREAD_ONCE_INIT
Definition: epicsThread.h:109
int maxMsgSize
Definition: errlog.c:79
LIBCOM_API void epicsStdCall epicsThreadOnce(epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg)
#define stderr
Definition: epicsStdio.h:32
int errlogMessage ( const char *  message)

Definition at line 180 of file errlog.c.

181 {
182  errlogPrintf("%s", message);
183  return 0;
184 }
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
int errlogPrintf ( const char *  pFormat,
  ... 
)

Definition at line 105 of file errlog.c.

106 {
107  va_list pvar;
108  char *pbuffer;
109  int nchar;
110  int isOkToBlock;
111 
114  ("errlogPrintf called from interrupt level\n");
115  return 0;
116  }
117 
118  errlogInit(0);
119  isOkToBlock = epicsThreadIsOkToBlock();
120 
121  if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) {
122  FILE *console = pvtData.console ? pvtData.console : stderr;
123 
124  va_start(pvar, pFormat);
125  nchar = vfprintf(console, pFormat, pvar);
126  va_end (pvar);
127  fflush(console);
128  }
129 
130  if (pvtData.atExit)
131  return nchar;
132 
133  pbuffer = msgbufGetFree(isOkToBlock);
134  if (!pbuffer)
135  return 0;
136 
137  va_start(pvar, pFormat);
138  nchar = tvsnPrint(pbuffer, pvtData.maxMsgSize, pFormat?pFormat:"", pvar);
139  va_end(pvar);
140  msgbufSetSize(nchar);
141  return nchar;
142 }
int errlogInit(int bufsize)
Definition: errlog.c:524
LIBCOM_API int epicsInterruptIsInterruptContext(void)
Definition: osdInterrupt.c:48
FILE * console
Definition: errlog.c:83
LIBCOM_API void epicsInterruptContextMessage(const char *message)
Definition: osdInterrupt.c:53
char * pbuffer
Definition: errlog.c:85
int epicsStdCall epicsThreadIsOkToBlock(void)
#define stderr
Definition: epicsStdio.h:32
int errlogPrintfNoConsole ( const char *  pFormat,
  ... 
)

Definition at line 186 of file errlog.c.

187 {
188  va_list pvar;
189  int nchar;
190 
193  ("errlogPrintfNoConsole called from interrupt level\n");
194  return 0;
195  }
196 
197  errlogInit(0);
198  va_start(pvar, pFormat);
199  nchar = errlogVprintfNoConsole(pFormat, pvar);
200  va_end(pvar);
201  return nchar;
202 }
int errlogInit(int bufsize)
Definition: errlog.c:524
LIBCOM_API int epicsInterruptIsInterruptContext(void)
Definition: osdInterrupt.c:48
int errlogVprintfNoConsole(const char *pFormat, va_list pvar)
Definition: errlog.c:204
LIBCOM_API void epicsInterruptContextMessage(const char *message)
Definition: osdInterrupt.c:53
int errlogRemoveListeners ( errlogListener  listener,
void *  pPrivate 
)

Definition at line 334 of file errlog.c.

335 {
336  listenerNode *plistenerNode;
337  int count = 0;
338 
339  errlogInit(0);
340  if (!pvtData.atExit)
341  epicsMutexMustLock(pvtData.listenerLock);
342 
343  plistenerNode = (listenerNode *)ellFirst(&pvtData.listenerList);
344  while (plistenerNode) {
345  listenerNode *pnext = (listenerNode *)ellNext(&plistenerNode->node);
346 
347  if (plistenerNode->listener == listener &&
348  plistenerNode->pPrivate == pPrivate) {
349  ellDelete(&pvtData.listenerList, &plistenerNode->node);
350  free(plistenerNode);
351  ++count;
352  }
353  plistenerNode = pnext;
354  }
355 
356  if (!pvtData.atExit)
357  epicsMutexUnlock(pvtData.listenerLock);
358 
359  if (count == 0) {
360  FILE *console = pvtData.console ? pvtData.console : stderr;
361 
362  fprintf(console,
363  "errlogRemoveListeners: No listeners found\n");
364  }
365  return count;
366 }
ELLNODE node
Definition: errlog.c:52
void * pPrivate
Definition: errlog.c:54
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
Release the semaphore.
Definition: epicsMutex.cpp:140
int errlogInit(int bufsize)
Definition: errlog.c:524
#define ellNext(PNODE)
Find the next node in list.
Definition: ellLib.h:99
FILE * console
Definition: errlog.c:83
errlogListener listener
Definition: errlog.c:53
#define stderr
Definition: epicsStdio.h:32
#define epicsMutexMustLock(ID)
Claim a semaphore (see epicsMutexLock()).
Definition: epicsMutex.h:214
void ellDelete(ELLLIST *pList, ELLNODE *pNode)
Deletes a node from a list.
Definition: ellLib.c:75
#define ellFirst(PLIST)
Find the first node in list.
Definition: ellLib.h:89
int errlogSetConsole ( FILE *  stream)

Definition at line 376 of file errlog.c.

377 {
378  errlogInit(0);
379  pvtData.console = stream;
380  return 0;
381 }
int errlogInit(int bufsize)
Definition: errlog.c:524
void errlogSetSevToLog ( errlogSevEnum  severity)

Definition at line 305 of file errlog.c.

306 {
307  errlogInit(0);
308  pvtData.sevToLog = severity;
309 }
int errlogInit(int bufsize)
Definition: errlog.c:524
int errlogSevPrintf ( errlogSevEnum  severity,
const char *  pFormat,
  ... 
)

Definition at line 229 of file errlog.c.

230 {
231  va_list pvar;
232  int nchar;
233  int isOkToBlock;
234 
237  ("errlogSevPrintf called from interrupt level\n");
238  return 0;
239  }
240 
241  errlogInit(0);
242  if (pvtData.sevToLog > severity)
243  return 0;
244 
245  isOkToBlock = epicsThreadIsOkToBlock();
246  if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) {
247  FILE *console = pvtData.console ? pvtData.console : stderr;
248 
249  fprintf(console, "sevr=%s ", errlogGetSevEnumString(severity));
250  va_start(pvar, pFormat);
251  vfprintf(console, pFormat, pvar);
252  va_end(pvar);
253  fflush(console);
254  }
255 
256  va_start(pvar, pFormat);
257  nchar = errlogSevVprintf(severity, pFormat, pvar);
258  va_end(pvar);
259  return nchar;
260 }
int errlogInit(int bufsize)
Definition: errlog.c:524
LIBCOM_API int epicsInterruptIsInterruptContext(void)
Definition: osdInterrupt.c:48
int errlogSevVprintf(errlogSevEnum severity, const char *pFormat, va_list pvar)
Definition: errlog.c:262
FILE * console
Definition: errlog.c:83
LIBCOM_API void epicsInterruptContextMessage(const char *message)
Definition: osdInterrupt.c:53
int epicsStdCall epicsThreadIsOkToBlock(void)
#define stderr
Definition: epicsStdio.h:32
const char * errlogGetSevEnumString(errlogSevEnum severity)
Definition: errlog.c:297
int errlogSevVprintf ( errlogSevEnum  severity,
const char *  pFormat,
va_list  pvar 
)

Definition at line 262 of file errlog.c.

263 {
264  char *pnext;
265  int nchar;
266  int totalChar = 0;
267  int isOkToBlock;
268 
271  ("errlogSevVprintf called from interrupt level\n");
272  return 0;
273  }
274 
275  errlogInit(0);
276  if (pvtData.atExit)
277  return 0;
278 
279  isOkToBlock = epicsThreadIsOkToBlock();
280  pnext = msgbufGetFree(isOkToBlock);
281  if (!pnext)
282  return 0;
283 
284  nchar = sprintf(pnext, "sevr=%s ", errlogGetSevEnumString(severity));
285  pnext += nchar; totalChar += nchar;
286  nchar = tvsnPrint(pnext, pvtData.maxMsgSize - totalChar - 1, pFormat, pvar);
287  pnext += nchar; totalChar += nchar;
288  if (pnext[-1] != '\n') {
289  strcpy(pnext,"\n");
290  totalChar++;
291  }
292  msgbufSetSize(totalChar);
293  return nchar;
294 }
int errlogInit(int bufsize)
Definition: errlog.c:524
LIBCOM_API int epicsInterruptIsInterruptContext(void)
Definition: osdInterrupt.c:48
LIBCOM_API void epicsInterruptContextMessage(const char *message)
Definition: osdInterrupt.c:53
int epicsStdCall epicsThreadIsOkToBlock(void)
const char * errlogGetSevEnumString(errlogSevEnum severity)
Definition: errlog.c:297
int errlogVprintf ( const char *  pFormat,
va_list  pvar 
)

Definition at line 144 of file errlog.c.

145 {
146  int nchar;
147  char *pbuffer;
148  int isOkToBlock;
149  FILE *console;
150 
153  ("errlogVprintf called from interrupt level\n");
154  return 0;
155  }
156 
157  errlogInit(0);
158  if (pvtData.atExit)
159  return 0;
160  isOkToBlock = epicsThreadIsOkToBlock();
161 
162  pbuffer = msgbufGetFree(isOkToBlock);
163  if (!pbuffer) {
164  console = pvtData.console ? pvtData.console : stderr;
165  vfprintf(console, pFormat, pvar);
166  fflush(console);
167  return 0;
168  }
169 
170  nchar = tvsnPrint(pbuffer, pvtData.maxMsgSize, pFormat?pFormat:"", pvar);
171  if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) {
172  console = pvtData.console ? pvtData.console : stderr;
173  fprintf(console, "%s", pbuffer);
174  fflush(console);
175  }
176  msgbufSetSize(nchar);
177  return nchar;
178 }
int errlogInit(int bufsize)
Definition: errlog.c:524
LIBCOM_API int epicsInterruptIsInterruptContext(void)
Definition: osdInterrupt.c:48
FILE * console
Definition: errlog.c:83
LIBCOM_API void epicsInterruptContextMessage(const char *message)
Definition: osdInterrupt.c:53
char * pbuffer
Definition: errlog.c:85
int epicsStdCall epicsThreadIsOkToBlock(void)
#define stderr
Definition: epicsStdio.h:32
int errlogVprintfNoConsole ( const char *  pFormat,
va_list  pvar 
)

Definition at line 204 of file errlog.c.

205 {
206  int nchar;
207  char *pbuffer;
208 
211  ("errlogVprintfNoConsole called from interrupt level\n");
212  return 0;
213  }
214 
215  errlogInit(0);
216  if (pvtData.atExit)
217  return 0;
218 
219  pbuffer = msgbufGetFree(1);
220  if (!pbuffer)
221  return 0;
222 
223  nchar = tvsnPrint(pbuffer, pvtData.maxMsgSize, pFormat?pFormat:"", pvar);
224  msgbufSetSize(nchar);
225  return nchar;
226 }
int errlogInit(int bufsize)
Definition: errlog.c:524
LIBCOM_API int epicsInterruptIsInterruptContext(void)
Definition: osdInterrupt.c:48
LIBCOM_API void epicsInterruptContextMessage(const char *message)
Definition: osdInterrupt.c:53
char * pbuffer
Definition: errlog.c:85
void errPrintf ( long  status,
const char *  pFileName,
int  lineno,
const char *  pformat,
  ... 
)

Definition at line 383 of file errlog.c.

385 {
386  va_list pvar;
387  char *pnext;
388  int nchar;
389  int totalChar=0;
390  int isOkToBlock;
391  char name[256];
392 
394  epicsInterruptContextMessage("errPrintf called from interrupt level\n");
395  return;
396  }
397 
398  errlogInit(0);
399  isOkToBlock = epicsThreadIsOkToBlock();
400  if (status == 0)
401  status = errno;
402 
403  if (status > 0) {
404  errSymLookup(status, name, sizeof(name));
405  }
406 
407  if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) {
408  FILE *console = pvtData.console ? pvtData.console : stderr;
409 
410  if (pFileName)
411  fprintf(console, "filename=\"%s\" line number=%d\n",
412  pFileName, lineno);
413  if (status > 0)
414  fprintf(console, "%s ", name);
415 
416  va_start(pvar, pformat);
417  vfprintf(console, pformat, pvar);
418  va_end(pvar);
419  fputc('\n', console);
420  fflush(console);
421  }
422 
423  if (pvtData.atExit)
424  return;
425 
426  pnext = msgbufGetFree(isOkToBlock);
427  if (!pnext)
428  return;
429 
430  if (pFileName) {
431  nchar = sprintf(pnext,"filename=\"%s\" line number=%d\n",
432  pFileName, lineno);
433  pnext += nchar; totalChar += nchar;
434  }
435 
436  if (status > 0) {
437  nchar = sprintf(pnext,"%s ",name);
438  pnext += nchar; totalChar += nchar;
439  }
440  va_start(pvar, pformat);
441  nchar = tvsnPrint(pnext, pvtData.maxMsgSize - totalChar - 1, pformat, pvar);
442  va_end(pvar);
443  if (nchar>0) {
444  pnext += nchar;
445  totalChar += nchar;
446  }
447  strcpy(pnext, "\n");
448  totalChar++ ; /*include the \n */
449  msgbufSetSize(totalChar);
450 }
pvd::Status status
int lineno
Definition: antelope.c:33
int errlogInit(int bufsize)
Definition: errlog.c:524
LIBCOM_API int epicsInterruptIsInterruptContext(void)
Definition: osdInterrupt.c:48
LIBCOM_API void errSymLookup(long status, char *pBuf, size_t bufLength)
Definition: errSymLib.c:190
FILE * console
Definition: errlog.c:83
LIBCOM_API void epicsInterruptContextMessage(const char *message)
Definition: osdInterrupt.c:53
int epicsStdCall epicsThreadIsOkToBlock(void)
#define stderr
Definition: epicsStdio.h:32

Variable Documentation

int atExit

Definition at line 73 of file errlog.c.

int buffersize

Definition at line 78 of file errlog.c.

FILE* console

Definition at line 83 of file errlog.c.

int errlogInitFailed

Definition at line 77 of file errlog.c.

int errVerbose = 0

Definition at line 41 of file errlog.c.

epicsEventId flush

Definition at line 70 of file errlog.c.

epicsMutexId flushLock

Definition at line 71 of file errlog.c.

ELLLIST listenerList

Definition at line 74 of file errlog.c.

epicsMutexId listenerLock

Definition at line 68 of file errlog.c.

int maxMsgSize

Definition at line 79 of file errlog.c.

int missedMessages

Definition at line 84 of file errlog.c.

int msgNeeded

Definition at line 80 of file errlog.c.

ELLLIST msgQueue

Definition at line 75 of file errlog.c.

epicsMutexId msgQueueLock

Definition at line 67 of file errlog.c.

char* pbuffer

Definition at line 85 of file errlog.c.

msgNode* pnextSend

Definition at line 76 of file errlog.c.

int sevToLog

Definition at line 81 of file errlog.c.

int toConsole

Definition at line 82 of file errlog.c.

epicsEventId waitForExit

Definition at line 72 of file errlog.c.

epicsEventId waitForFlush

Definition at line 69 of file errlog.c.

epicsEventId waitForWork

Definition at line 66 of file errlog.c.