On systems which are based on System V messages of programs (especially the system tools) are printed in a strict form using the fmtmsg function. The uniformity sometimes helps the user to interpret messages and the strictness tests of the fmtmsg function ensure that the programmer follows some minimal requirements.
Messages can be printed to standard error and/or to the console. To select the destination the programmer can use the following two values, bitwise OR combined if wanted, for the classification parameter of fmtmsg:
Display the message in standard error.
Display the message on the system console.
The erroneous piece of the system can be signalled by exactly one of the following values which also is bitwise ORed with the classification parameter to fmtmsg:
The source of the condition is some hardware.
The source of the condition is some software.
The source of the condition is some firmware.
A third component of the classification parameter to fmtmsg can describe the part of the system which detects the problem. This is done by using exactly one of the following values:
The erroneous condition is detected by the application.
The erroneous condition is detected by a utility.
The erroneous condition is detected by the operating system.
A last component of classification can signal the results of this message. Exactly one of the following values can be used:
It is a recoverable error.
It is a non-recoverable error.
int function>fmtmsg/function> (long int classification, const char *label, int severity, const char *text, const char *action, const char *tag) Display a message described by its parameters on the device(s) specified in the classification parameter. The label parameter identifies the source of the message. The string should consist of two colon separated parts where the first part has not more than 10 and the second part not more than 14 characters. The text parameter describes the condition of the error, the action parameter possible steps to recover from the error and the tag parameter is a reference to the online documentation where more information can be found. It should contain the label value and a unique identification number.
Each of the parameters can be a special value which means this value is to be omitted. The symbolic names for these values are:
Ignore label parameter.
Ignore severity parameter.
Ignore classification parameter. This implies that nothing is actually printed.
Ignore text parameter.
Ignore action parameter.
Ignore tag parameter.
There is another way certain fields can be omitted from the output to standard error. This is described below in the description of environment variables influencing the behavior.
The severity parameter can have one of the values in the following table:
Nothing is printed, this value is the same as MM_NULLSEV.
This value is printed as HALT.
This value is printed as ERROR.
This value is printed as WARNING.
This value is printed as INFO.
The numeric value of these five macros are between 0 and 4. Using the environment variable SEV_LEVEL or using the addseverity function one can add more severity levels with their corresponding string to print. This is described below (the section called “Adding Severity Classes”).
If no parameter is ignored the output looks like this:
label: severity-string: text TO FIX: actiontag
The colons, new line characters and the TO FIX string are inserted if necessary, i.e., if the corresponding parameter is not ignored.
This function is specified in the X/Open Portability Guide. It is also available on all systems derived from System V.
The function returns the value MM_OK if no error occurred. If only the printing to standard error failed, it returns MM_NOMSG. If printing to the console fails, it returns MM_NOCON. If nothing is printed MM_NOTOK is returned. Among situations where all outputs fail this last value is also returned if a parameter value is incorrect.
There are two environment variables which influence the behavior of fmtmsg. The first is MSGVERB. It is used to control the output actually happening on standard error (not the console output). Each of the five fields can explicitly be enabled. To do this the user has to put the MSGVERB variable with a format like the following in the environment before calling the fmtmsg function the first time:
MSGVERB=keyword[:keyword[:...]]
Valid keywords are label, severity, text, action, and tag. If the environment variable is not given or is the empty string, a not supported keyword is given or the value is somehow else invalid, no part of the message is masked out.
The second environment variable which influences the behavior of fmtmsg is SEV_LEVEL. This variable and the change in the behavior of fmtmsg is not specified in the X/Open Portability Guide. It is available in System V systems, though. It can be used to introduce new severity levels. By default, only the five severity levels described above are available. Any other numeric value would make fmtmsg print nothing.
If the user puts SEV_LEVEL with a format like
SEV_LEVEL=[description[:description[:...]]]
in the environment of the process before the first call to fmtmsg, where description has a value of the form
severity-keyword,level,printstring
The severity-keyword part is not used by fmtmsg but it has to be present. The level part is a string representation of a number. The numeric value must be a number greater than 4. This value must be used in the severity parameter of fmtmsg to select this class. It is not possible to overwrite any of the predefined classes. The printstring is the string printed when a message of this class is processed by fmtmsg (see above, fmtsmg does not print the numeric value but instead the string representation).
There is another possibility to introduce severity classes besides using the environment variable SEV_LEVEL. This simplifies the task of introducing new classes in a running program. One could use the setenv or putenv function to set the environment variable, but this is toilsome.
int function>addseverity/function> (int severity, const char *string) This function allows the introduction of new severity classes which can be addressed by the severity parameter of the fmtmsg function. The severity parameter of addseverity must match the value for the parameter with the same name of fmtmsg, and string is the string printed in the actual messages instead of the numeric value.
If string is NULL the severity class with the numeric value according to severity is removed.
It is not possible to overwrite or remove one of the default severity classes. All calls to addseverity with severity set to one of the values for the default classes will fail.
The return value is MM_OK if the task was successfully performed. If the return value is MM_NOTOK something went wrong. This could mean that no more memory is available or a class is not available when it has to be removed.
This function is not specified in the X/Open Portability Guide although the fmtsmg function is. It is available on System V systems.
Here is a simple example program to illustrate the use of the both functions described in this section.
#include fmtmsg.h int main (void) { addseverity (5, "NOTE2"); fmtmsg (MM_PRINT, "only1field", MM_INFO, "text2", "action2", "tag2"); fmtmsg (MM_PRINT, "UX:cat", 5, "invalid syntax", "refer to manual", "UX:cat:001"); fmtmsg (MM_PRINT, "label:foo", 6, "text", "action", "tag"); return 0; }
The second call to fmtmsg illustrates a use of this function as it usually occurs on System V systems, which heavily use this function. It seems worthwhile to give a short explanation here of how this system works on System V. The value of the label field (UX:cat) says that the error occurred in the Unix program cat. The explanation of the error follows and the value for the action parameter is "refer to manual". One could be more specific here, if necessary. The tag field contains, as proposed above, the value of the string given for the label parameter, and additionally a unique ID (001 in this case). For a GNU environment this string could contain a reference to the corresponding node in the Info page for the program.
Running this program without specifying the MSGVERB and SEV_LEVEL function produces the following output:
UX:cat: NOTE2: invalid syntax TO FIX: refer to manual UX:cat:001
We see the different fields of the message and how the extra glue (the colons and the TO FIX string) are printed. But only one of the three calls to fmtmsg produced output. The first call does not print anything because the label parameter is not in the correct form. The string must contain two fields, separated by a colon (the section called “Printing Formatted Messages”). The third fmtmsg call produced no output since the class with the numeric value 6 is not defined. Although a class with numeric value 5 is also not defined by default, the call to addseverity introduces it and the second call to fmtmsg produces the above output.
When we change the environment of the program to contain SEV_LEVEL=XXX,6,NOTE when running it we get a different result:
UX:cat: NOTE2: invalid syntax TO FIX: refer to manual UX:cat:001 label:foo: NOTE: text TO FIX: action tag
Now the third call to fmtmsg produced some output and we see how the string NOTE from the environment variable appears in the message.
Now we can reduce the output by specifying which fields we are interested in. If we additionally set the environment variable MSGVERB to the value severity:label:action we get the following output:
UX:cat: NOTE2 TO FIX: refer to manual label:foo: NOTE TO FIX: action
I.e., the output produced by the text and the tag parameters to fmtmsg vanished. Please also note that now there is no colon after the NOTE and NOTE2 strings in the output. This is not necessary since there is no more output on this line because the text is missing.