📄 loglib.c
字号:
/* logLib.c - message logging library *//* Copyright 1984-1995 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------03l,13may02,cyr fix SPR 32358 documentation clarification on logMsg03k,29oct01,cyr doc:doc: correct SPR 7113 logMsg03j,30oct95,ism added simsolaris support03i,09nov94,ms undid 03h. Bumped stack size for SIMSPARC.03h,17jul94,ms jacked up the stack size for VxSim/HPPA.03g,24aug93,dvs added reset of logFdFromRlogin.03f,23aug93,dvs fixed logFdSet() for rlogin sessions (SPR #2212).03e,15feb93,jdi fixed doc for logMsg() to mention fixed number of args.03d,21jan93,jdi documentation cleanup for 5.1.03c,13nov92,jcf added _func_logMsg initialization. added include semLibP.h.03b,17jul92,gae reverted to 02x -- eliminating stdargs change. Documentation sprs #600 and #1148 fixed. Checked for null format specifier.03a,18jul92,smb Changed errno.h to errnoLib.h.02z,26may92,rrr the tree shuffle02y,04mar92,gae Used stdargs for logMsg, no longer fixed at 6 parameters. Allowed messages to be dropped via global var. logMsgTimeout. Reduced stack size from 5000 to 3000. Checked for null format specifier. Fixed spr #600 (documentation of logMsg). Fixed spr #1138 (printing of floating point numbers). Fixed spr #1148 (document use of message queues)02x,10dec91,gae added includes for ANSI.02w,04oct91,rrr passed through the ansification filter -changed functions to ansi style -changed VOID to void -changed copyright notice02v,01aug91,yao changed to check for dead task in logTask(). added missing arg to lprintf() call.02u,10jun91,del changed MAX_ARGS to MAX_LOGARGS to silence redef warning.02t,05apr91,jdi documentation -- removed header parens and x-ref numbers; doc review by dnw.02s,11feb91,jaa documentation cleanup.02r,08oct90,dnw lint02q,05oct90,dnw changed to new msgQ interface.02p,10aug90,dnw changed declaration for logMsg from void to int. added include of logLib.h.02o,10aug90,kdl added forward declaration for lprintf.02n,19jul90,dnw changed to use message queue instead of pipe changed logTask stack from 10k to 5k spr 641: changed logMsg to return number of bytes written to msg q or EOF if error writing improved module and logMsg doc, esp about volitile args02m,10jul90,dnw logTask no longer dies with bus error when printing msg from interrupt level (fixed to not call taskName(-1)) changed to use INT_CONTEXT() instead of intContext()02l,26jun90,jcf changed logTask semaphore to mutex.02k,15apr90,jcf changed logTask name to tLogTask.02j,14mar90,jdi documentation cleanup.02i,16sep88,ecs bumped logTaskStackSize from 2000 to 10000. removed architectural assumption from logMsg.02h,14jun89,gae changed the format of the logMsg's to be more intelligible.02g,07jul88,jcf made logShow global but NOMANUAL, so lint would let up.02f,22jun88,dnw name tweaks.02e,06jun88,dnw changed taskSpawn/taskCreate args.02d,30may88,dnw changed to v4 names.02c,23apr88,jcf changed semaphores for new semLib.02b,05apr88,gae changed fprintf() to fdprintf(). Added debug rtn logShow().02a,26jan88,jcf made kernel independent.01q,14dec87,gae changed logMsg() to not have multiple argument decl's for parsing by the C interface generator.01p,16nov87,ecs documentation.01o,03nov87,dnw changed to let system pick logTask id; now available in logTaskId.01n,14oct87,gae added log{Add,Del}Fd(), allowing multiple logging fds. removed NOT_GENERIC stuff.01m,24mar87,jlf documentation01l,21dec86,dnw changed to not get include files from default directories.01k,31jul86,llk uses new spawn01j,09jul86,dnw restored NOT_GENERIC stuff that got lost in v01i.01i,01jul86,jlf minor documentation01h,09apr86,dnw added call to vxSetTaskBreakable to make logTask unbreakable. fixed documentation of logMsg().01g,07apr86,dnw increased logTsk stack from 1000 to 2000. corrected errors in documentation. added logSetFd().01f,11mar86,jlf changed GENERIC to NOT_GENERIC01e,20jul85,jlf documentation.01d,04jan85,ecs added an ARGSUSED to logMsg, got rid of 'housetime'.01c,19sep84,jlf cleaned up comments a little01b,07sep84,jlf added copyright notice and comments.01a,28aug84,dnw culled from fioLib and enhanced.*//*DESCRIPTIONThis library handles message logging. It is usually used to display errormessages on the system console, but such messages can also be sent to adisk file or printer.The routines logMsg() and logTask() are the basic components of thelogging system. The logMsg() routine has the same calling sequence asprintf(), but instead of formatting and outputting the message directly,it sends the format string and arguments to a message queue. The tasklogTask() waits for messages on this message queue. It formats eachmessage according to the format string and arguments in the message,prepends the ID of the sender, and writes it on one or more filedescriptors that have been specified as logging output streams (bylogInit() or subsequently set by logFdSet() or logFdAdd()).USE IN INTERRUPT SERVICE ROUTINESBecause logMsg() does not directly cause output to I/O devices, butinstead simply writes to a message queue, it can be called from aninterrupt service routine as well as from tasks. Normal I/O, such asprintf() output to a serial port, cannot be done from an interrupt serviceroutine.DEFERRED LOGGINGPrint formatting is performed within the context of logTask(), rather thanthe context of the task calling logMsg(). Since formatting can requireconsiderable stack space, this can reduce stack sizes for tasks that onlyneed to do I/O for error output.However, this also means that the arguments to logMsg() are not interpretedat the time of the call to logMsg(), but rather are interpreted at somelater time by logTask(). This means that the arguments to logMsg() shouldnot be pointers to volatile entities. For example, pointers to dynamic orchanging strings and buffers should not be passed as arguments to be formatted.Thus the following would not give the desired results:.ne 8.CS doLog (which) { char string [100]; strcpy (string, which ? "hello" : "goodbye"); ... logMsg (string); }.CEBy the time logTask() formats the message, the stack frame of the caller mayno longer exist and the pointer <string> may no longer be valid.On the other hand, the following is correct since the string pointer passedto the logTask() always points to a static string:.CS doLog (which) { char *string; string = which ? "hello" : "goodbye"; ... logMsg (string); }.CEINITIALIZATIONTo initialize the message logging facilities, the routine logInit() mustbe called before calling any other routine in this module. This is doneby the root task, usrRoot(), in usrConfig.c.INCLUDE FILES: logLib.hSEE ALSO: msgQLib,.pG "I/O System"*//* LINTLIBRARY */#include "vxWorks.h"#include "errnoLib.h"#include "logLib.h"#include "ioLib.h"#include "taskLib.h"#include "semLib.h"#include "intLib.h"#include "msgQLib.h"#include "stdio.h"#include "private/semLibP.h"#include "private/funcBindP.h"#define MAX_LOGARGS 6 /* max args to log message */#define MAX_LOGFDS 5 /* max log fds */typedef struct /* LOG_MSG */ { int id; /* ID of sending task */ char * fmt; /* pointer to format string */ int arg [MAX_LOGARGS]; /* args for format string */ } LOG_MSG;/* logTask parameters */int logTaskId = 0;int logTaskPriority = 0;int logTaskOptions = VX_UNBREAKABLE;#if CPU_FAMILY == SIMSPARCSUNOS || CPU_FAMILY == SIMSPARCSOLARISint logTaskStackSize = 8000;#else /* CPU_FAMILY != SIMSPARCSUNOS */int logTaskStackSize = 5000;#endif /* CPU_FAMILY == SIMSPARCSUNOS || CPU_FAMILY == SIMSPARCSOLARIS */int mutexOptionsLogLib = SEM_Q_FIFO | SEM_DELETE_SAFE; /* mutex options */int logFdFromRlogin = NONE; /* fd of pty for rlogin *//* local variables */LOCAL SEMAPHORE logFdSem; /* semaphore for accessing logFd's */LOCAL MSG_Q_ID logMsgQId = 0; /* ID of misg q to log task */LOCAL int logFd [MAX_LOGFDS]; /* output fd's used for logging */LOCAL int numLogFds = 0; /* number of active logging fd's */LOCAL int logMsgsLost = 0; /* count of log messages lost *//* forward static functions */static void lprintf (char *fmt, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6);/********************************************************************************* logInit - initialize message logging library** This routine specifies the file descriptor to be used as the logging* device and the number of messages that can be in the logging queue. If* more than <maxMsgs> are in the queue, they will be discarded. A message* is printed to indicate lost messages.** This routine spawns logTask(), the task-level portion of error logging.** This routine must be called before any other routine in logLib.* This is done by the root task, usrRoot(), in usrConfig.c.** RETURNS* OK, or ERROR if a message queue could not be created* or logTask() could not be spawned.*/STATUS logInit ( int fd, /* file descriptor to use as logging device */ int maxMsgs /* max. number of messages allowed in log queue */ ) { if (logTaskId != 0) return (ERROR); /* already called */ logMsgQId = msgQCreate (maxMsgs, sizeof (LOG_MSG), MSG_Q_FIFO); if (logMsgQId == NULL) return (ERROR); logTaskId = taskSpawn ("tLogTask", logTaskPriority, logTaskOptions, logTaskStackSize, (FUNCPTR)logTask, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); if (logTaskId == ERROR) { /* XXX free message q? */ return (ERROR); } _func_logMsg = (FUNCPTR) logMsg; semMInit (&logFdSem, mutexOptionsLogLib); logFdSet (fd); return (OK); }/********************************************************************************* logMsg - log a formatted error message** This routine logs a specified message via the logging task. This* routine's syntax is similar to printf() -- a format string is followed* by arguments to format. However, the logMsg() routine takes a char ** rather than a const char * and requires a fixed number of arguments* (6).** The task ID of the caller is prepended to the specified message.** SPECIAL CONSIDERATIONS* Because logMsg() does not actually perform the output directly to the* logging streams, but instead queues the message to the logging task,* logMsg() can be called from interrupt service routines.** However, since the arguments are interpreted by the logTask() at the* time of actual logging, instead of at the moment when logMsg() is called,* arguments to logMsg() should not be pointers to volatile entities* (e.g., dynamic strings on the caller stack).** logMsg() checks to see whether or not it is running in interupt context. * If it is, it will not block. However, if invoked from a task, it can * cause the task to block. *** For more detailed information about the use of logMsg(), see the manual* entry for logLib.*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -