home *** CD-ROM | disk | FTP | other *** search
- From: mjr@osiris.UUCP (Marcus J. Ranum)
- Newsgroups: comp.sources.misc
- Subject: v02i021: printerr() and fprinterr() - enhanced perror()s.
- Message-ID: <7132@ncoast.UUCP>
- Date: 26 Jan 88 04:22:07 GMT
- Approved: allbery@ncoast.UUCP
-
- Comp.sources.misc: Volume 2, Issue 21
- Submitted-By: Marcus J. Ranum <mjr@osiris.UUCP>
- Archive-Name: prterror
-
- [Not portable enough; all my systems have vfprintf, but no _doprnt. ++bsa]
-
- This is a possibly useful function in 'C'. It's essentially a stdio
- version of perror() that does printf() style formatting. The man page has
- the details.
-
- Portability should be high - the functions use varargs and assume
- errno and errlist are available. They may need some local hacking, but can
- come in useful.
-
- --mjr();
-
-
- -----cut here-----cut here-----cut here-----cut here-----
- #!/bin/sh
- # shar: Shell Archiver
- # Run the following text with /bin/sh to create:
- # README
- # printerr.c
- # printerr.l
- # This archive created: Wed Jan 20 20:20:45 1988
- echo shar: extracting README '(329 characters)'
- sed 's/^XX//' << \SHAR_EOF > README
- XX
- XX This is a possibly useful function in 'C'. It's essentially a stdio
- XXversion of perror() that does printf() style formatting. The man page has
- XXthe details.
- XX
- XX Portability should be high - the functions use varargs and assume
- XXerrno and errlist are available. They may need some local hacking, but can
- XXcome in useful.
- XX
- XX--mjr();
- SHAR_EOF
- if test 329 -ne "`wc -c README`"
- then
- echo shar: error transmitting README '(should have been 329 characters)'
- fi
- echo shar: extracting printerr.c '(2614 characters)'
- sed 's/^XX//' << \SHAR_EOF > printerr.c
- XX
- XX#ifndef lint
- XXstatic char *RCSid = "$Header: printerr.c,v 1.2 87/11/16 21:26:48 mjr Exp $";
- XX#endif
- XX
- XX/*
- XX * $Author: mjr $
- XX * $Log: printerr.c,v $
- XX * Revision 1.2 87/11/16 21:26:48 mjr
- XX * added (wow) comments
- XX *
- XX * Revision 1.1 87/11/16 21:22:29 mjr
- XX * Initial revision
- XX *
- XX*/
- XX
- XX#include <stdio.h>
- XX#include <varargs.h>
- XX
- XX/*
- XX * just like printf() and fprintf() - except that a format like
- XX * `%m' in the format string is replaced with the system error message.
- XX * This is an expansion upon from Chris Torek's more limited err.c
- XX */
- XX
- XX#ifdef lint
- XX/* VARARGS */
- XXprinterr(ffmt)
- XXchar *ffmt;
- XX#else
- XXprinterr(va_alist)
- XXva_dcl
- XX#endif lint
- XX{
- XX
- XX register char *fmt;
- XX register char *p, *s = NULL;
- XX register int n, c;
- XX char newfmt[BUFSIZ];
- XX char unknown[40];
- XX extern int errno;
- XX extern char *sys_errlist[];
- XX extern int sys_nerr;
- XX#ifndef lint
- XX va_list l;
- XX#endif
- XX
- XX#ifndef lint
- XX va_start(l);
- XX fmt = va_arg(l, char *);
- XX#else
- XX if(*ffmt == 0)
- XX fmt = ""; /* use it for lint(1) */
- XX#endif
- XX p = newfmt;
- XX n = sizeof (newfmt);
- XX for (;;) {
- XX if (s != NULL) {
- XX if ((c = *s++) == 0) {
- XX s = NULL;
- XX continue;
- XX }
- XX } else {
- XX if((c = *fmt++) == 0)
- XX break;
- XX if((c == '%') && (*fmt == 'm')) {
- XX fmt++;
- XX if((errno < 0) || (errno > sys_nerr)){
- XX (void) sprintf(unknown,"unknown error %d",errno);
- XX s = unknown;
- XX } else
- XX s = sys_errlist[errno];
- XX continue;
- XX }
- XX }
- XX if (--n <= 0)
- XX break;
- XX *p++ = c;
- XX }
- XX *p = 0;
- XX
- XX#ifdef lint
- XX (void)fputs(newfmt,stderr);
- XX#else
- XX _doprnt(newfmt,l,stderr);
- XX va_end(l);
- XX#endif
- XX}
- XX
- XX
- XX#ifdef lint
- XX/*VARARGS*/
- XXfprinterr(iop,ffmt)
- XXFILE *iop;
- XXchar *ffmt;
- XX#else
- XXfprinterr(iop,va_alist)
- XXFILE *iop;
- XXva_dcl
- XX#endif
- XX{
- XX register char *fmt;
- XX register char *p, *s = NULL;
- XX register int n, c;
- XX char newfmt[BUFSIZ];
- XX char unknown[40];
- XX extern int errno;
- XX extern char *sys_errlist[];
- XX extern int sys_nerr;
- XX
- XX#ifndef lint
- XX va_list l;
- XX
- XX va_start(l);
- XX#endif
- XX#ifdef lint
- XX fmt = ""; ffmt = ""; /* use them for lint (ick) */
- XX (void)fclose(iop); *ffmt == '1';
- XX#else
- XX fmt = va_arg(l, char *);
- XX#endif
- XX p = newfmt;
- XX n = sizeof (newfmt);
- XX for (;;) {
- XX if (s != NULL) {
- XX if ((c = *s++) == 0) {
- XX s = NULL;
- XX continue;
- XX }
- XX } else {
- XX if ((c = *fmt++) == 0)
- XX break;
- XX if ((c == '%') && (*fmt == 'm')) {
- XX fmt++;
- XX if ((errno < 0) || (errno > sys_nerr)) {
- XX (void)sprintf(unknown,"unknown error %d",errno);
- XX s = unknown;
- XX } else
- XX s = sys_errlist[errno];
- XX continue;
- XX }
- XX }
- XX if (--n<=0) /* out of format space */
- XX break; /* should complain, but where? */
- XX *p++ = c;
- XX }
- XX *p = 0;
- XX
- XX#ifdef lint
- XX (void)fputs(newfmt,stderr);
- XX#else
- XX _doprnt(newfmt,l,iop);
- XX va_end(l);
- XX#endif
- XX}
- SHAR_EOF
- if test 2614 -ne "`wc -c printerr.c`"
- then
- echo shar: error transmitting printerr.c '(should have been 2614 characters)'
- fi
- echo shar: extracting printerr.l '(1789 characters)'
- sed 's/^XX//' << \SHAR_EOF > printerr.l
- XX.TH PRINTERR 3 local
- XX.SH NAME
- XXfprinterr \- formatted output with system error message
- XX.SH ORIGIN
- XXmjr@osiris
- XX.\"$Author: mjr $
- XX.fi
- XX.ad
- XX.SH SYNOPSIS
- XX.B #include <stdio.h>
- XX.PP
- XX.B printerr(format
- XX.RB [ ,
- XXarg ] ...
- XX.B )
- XX.br
- XX.SM
- XX.br
- XX.B char *format;
- XX.PP
- XX.B fprinterr(stream,format
- XX.RB [ ,
- XXarg ] ...
- XX.B )
- XX.br
- XX.SM
- XX.br
- XX.B FILE *stream;
- XX.br
- XX.B char *format;
- XX.SH DESCRIPTION
- XX.I Printerr
- XXand
- XX.I Fprinterr
- XXplace output on the standard error or the named
- XX.IR stream
- XXas appropriate in the same manner as
- XX.I printf(3)
- XXand
- XX.I fprintf(3).
- XXIf the format string \fB%m\fP is encountered in the format string, the
- XXsystem error message is printed similarly to
- XX.I perror(3).
- XX.SH DIAGNOSTICS
- XXIf an error number is encountered that is not part of the error list,
- XX.I Printerr
- XXwill use the words:
- XX.br
- XX\fIunknown error #\fP
- XX.br
- XXand the error number, instead of the (nonexistent) system error message.
- XX.SH CONSIDERATIONS
- XXIf the \fB%m\fP format string is omitted from the error message, this
- XXroutine is functionally identical to the related
- XX.I Printf()
- XXfunction.
- XX.SH EXAMPLE
- XX.nf
- XX.na
- XX FILE *log;
- XX FILE *willfail;
- XX int num;
- XX
- XX /* open a log file */
- XX if((log = fopen("LOGFILE","a")) == NULL) {
- XX perror("LOGFILE");
- XX exit(1);
- XX }
- XX
- XX /* try to open stream that will fail */
- XX /* assuming BADFILE is unopenable by user */
- XX#define BADFILE "/dev/kmem"
- XX
- XX if((willfail = fopen(BADFILE,"a")) == NULL) {
- XX printerr("uid #%d can't open %s: %m\n",getuid(),BADFILE);
- XX fprinterr(log,"uid #%d can't open %s: %m\n",getuid(),BADFILE);
- XX exit(1);
- XX }
- XX
- XX /* this would put an error message to the standard error */
- XX /* as well as placing it in a file */
- XX
- XX.fi
- XX.ad
- XX.SH AUTHOR
- XXMarcus Ranum
- XX.SH "SEE ALSO"
- XXfprintf(3), printf(3)
- XX.SH BUGS
- XX.PP
- XXVery wide fields (>128 characters) fail as in printf, since
- XX.I printerr
- XXmakes use of stdio's _doprint().
- SHAR_EOF
- if test 1789 -ne "`wc -c printerr.l`"
- then
- echo shar: error transmitting printerr.l '(should have been 1789 characters)'
- fi
- # End of shell archive
- exit 0
-