home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume2 / prterror < prev    next >
Encoding:
Internet Message Format  |  1991-08-07  |  6.7 KB

  1. From: mjr@osiris.UUCP (Marcus J. Ranum)
  2. Newsgroups: comp.sources.misc
  3. Subject: v02i021: printerr() and fprinterr() - enhanced perror()s.
  4. Message-ID: <7132@ncoast.UUCP>
  5. Date: 26 Jan 88 04:22:07 GMT
  6. Approved: allbery@ncoast.UUCP
  7.  
  8. Comp.sources.misc: Volume 2, Issue 21
  9. Submitted-By: Marcus J. Ranum <mjr@osiris.UUCP>
  10. Archive-Name: prterror
  11.  
  12. [Not portable enough; all my systems have vfprintf, but no _doprnt.  ++bsa]
  13.  
  14.     This is a possibly useful function in 'C'. It's essentially a stdio
  15. version of perror() that does printf() style formatting. The man page has 
  16. the details. 
  17.  
  18.     Portability should be high - the functions use varargs and assume 
  19. errno and errlist are available. They may need some local hacking, but can
  20. come in useful.
  21.  
  22. --mjr();
  23.  
  24.  
  25. -----cut here-----cut here-----cut here-----cut here-----
  26. #!/bin/sh
  27. # shar:    Shell Archiver
  28. #    Run the following text with /bin/sh to create:
  29. #    README
  30. #    printerr.c
  31. #    printerr.l
  32. # This archive created: Wed Jan 20 20:20:45 1988
  33. echo shar: extracting README '(329 characters)'
  34. sed 's/^XX//' << \SHAR_EOF > README
  35. XX
  36. XX    This is a possibly useful function in 'C'. It's essentially a stdio
  37. XXversion of perror() that does printf() style formatting. The man page has 
  38. XXthe details. 
  39. XX
  40. XX    Portability should be high - the functions use varargs and assume 
  41. XXerrno and errlist are available. They may need some local hacking, but can
  42. XXcome in useful.
  43. XX
  44. XX--mjr();
  45. SHAR_EOF
  46. if test 329 -ne "`wc -c README`"
  47. then
  48. echo shar: error transmitting README '(should have been 329 characters)'
  49. fi
  50. echo shar: extracting printerr.c '(2614 characters)'
  51. sed 's/^XX//' << \SHAR_EOF > printerr.c
  52. XX
  53. XX#ifndef lint
  54. XXstatic char *RCSid = "$Header: printerr.c,v 1.2 87/11/16 21:26:48 mjr Exp $";
  55. XX#endif
  56. XX
  57. XX/*
  58. XX *    $Author: mjr $
  59. XX *    $Log:    printerr.c,v $
  60. XX * Revision 1.2  87/11/16  21:26:48  mjr
  61. XX * added (wow) comments
  62. XX * 
  63. XX * Revision 1.1  87/11/16  21:22:29  mjr
  64. XX * Initial revision
  65. XX * 
  66. XX*/
  67. XX
  68. XX#include <stdio.h>
  69. XX#include <varargs.h>
  70. XX
  71. XX/*
  72. XX * just like printf() and fprintf() - except that a format like
  73. XX * `%m' in the format string is replaced with the system error message.
  74. XX * This is an expansion upon from Chris Torek's more limited err.c 
  75. XX */
  76. XX
  77. XX#ifdef lint
  78. XX/* VARARGS */
  79. XXprinterr(ffmt)
  80. XXchar *ffmt;
  81. XX#else
  82. XXprinterr(va_alist)
  83. XXva_dcl
  84. XX#endif lint
  85. XX{
  86. XX
  87. XX    register char *fmt;
  88. XX    register char *p, *s = NULL;
  89. XX    register int n, c;
  90. XX    char newfmt[BUFSIZ];
  91. XX    char unknown[40];
  92. XX    extern int errno;
  93. XX    extern char *sys_errlist[];
  94. XX    extern int sys_nerr;
  95. XX#ifndef lint
  96. XX    va_list l;
  97. XX#endif
  98. XX
  99. XX#ifndef lint
  100. XX    va_start(l);
  101. XX    fmt = va_arg(l, char *);
  102. XX#else
  103. XX    if(*ffmt == 0)
  104. XX        fmt = "";        /* use it for lint(1) */
  105. XX#endif
  106. XX    p = newfmt;
  107. XX    n = sizeof (newfmt);
  108. XX    for (;;) {
  109. XX        if (s != NULL) {
  110. XX            if ((c = *s++) == 0) {
  111. XX                s = NULL;
  112. XX                continue;
  113. XX            }
  114. XX        } else {
  115. XX            if((c = *fmt++) == 0)
  116. XX                break;
  117. XX            if((c == '%') && (*fmt == 'm')) {
  118. XX                fmt++;
  119. XX                if((errno < 0) || (errno > sys_nerr)){
  120. XX                    (void) sprintf(unknown,"unknown error %d",errno);
  121. XX                    s = unknown;
  122. XX                } else
  123. XX                    s = sys_errlist[errno];
  124. XX                continue;
  125. XX            }
  126. XX        }
  127. XX        if (--n <= 0)
  128. XX            break;
  129. XX        *p++ = c;
  130. XX    }
  131. XX    *p = 0;
  132. XX
  133. XX#ifdef lint
  134. XX    (void)fputs(newfmt,stderr);
  135. XX#else
  136. XX    _doprnt(newfmt,l,stderr);
  137. XX    va_end(l);
  138. XX#endif
  139. XX}
  140. XX
  141. XX
  142. XX#ifdef lint
  143. XX/*VARARGS*/
  144. XXfprinterr(iop,ffmt)
  145. XXFILE    *iop;
  146. XXchar    *ffmt;
  147. XX#else
  148. XXfprinterr(iop,va_alist)
  149. XXFILE    *iop;
  150. XXva_dcl
  151. XX#endif
  152. XX{
  153. XX    register char *fmt;
  154. XX    register char *p, *s = NULL;
  155. XX    register int n, c;
  156. XX    char newfmt[BUFSIZ];
  157. XX    char unknown[40];
  158. XX    extern int errno;
  159. XX    extern char *sys_errlist[];
  160. XX    extern int sys_nerr;
  161. XX
  162. XX#ifndef lint
  163. XX    va_list l;
  164. XX
  165. XX    va_start(l);
  166. XX#endif
  167. XX#ifdef lint
  168. XX    fmt = ""; ffmt = "";     /* use them for lint  (ick) */
  169. XX    (void)fclose(iop); *ffmt == '1';
  170. XX#else
  171. XX    fmt = va_arg(l, char *);
  172. XX#endif
  173. XX    p = newfmt;
  174. XX    n = sizeof (newfmt);
  175. XX    for (;;) {
  176. XX        if (s != NULL) {
  177. XX            if ((c = *s++) == 0) {
  178. XX                s = NULL;
  179. XX                continue;
  180. XX            }
  181. XX        } else {
  182. XX            if ((c = *fmt++) == 0)
  183. XX                break;
  184. XX            if ((c == '%') && (*fmt == 'm')) {
  185. XX                fmt++;
  186. XX                if ((errno < 0) || (errno > sys_nerr)) {
  187. XX                    (void)sprintf(unknown,"unknown error %d",errno);
  188. XX                    s = unknown;
  189. XX                } else
  190. XX                    s = sys_errlist[errno];
  191. XX                continue;
  192. XX            }
  193. XX        }
  194. XX        if (--n<=0)    /* out of format space */
  195. XX            break;    /* should complain, but where? */
  196. XX        *p++ = c;
  197. XX    }
  198. XX    *p = 0;
  199. XX
  200. XX#ifdef lint
  201. XX    (void)fputs(newfmt,stderr);
  202. XX#else
  203. XX    _doprnt(newfmt,l,iop);
  204. XX    va_end(l);
  205. XX#endif
  206. XX}
  207. SHAR_EOF
  208. if test 2614 -ne "`wc -c printerr.c`"
  209. then
  210. echo shar: error transmitting printerr.c '(should have been 2614 characters)'
  211. fi
  212. echo shar: extracting printerr.l '(1789 characters)'
  213. sed 's/^XX//' << \SHAR_EOF > printerr.l
  214. XX.TH PRINTERR 3 local
  215. XX.SH NAME
  216. XXfprinterr \- formatted output with system error message
  217. XX.SH ORIGIN
  218. XXmjr@osiris
  219. XX.\"$Author: mjr $
  220. XX.fi
  221. XX.ad
  222. XX.SH SYNOPSIS
  223. XX.B #include <stdio.h>
  224. XX.PP
  225. XX.B printerr(format
  226. XX.RB [ ,
  227. XXarg ] ...
  228. XX.B )
  229. XX.br
  230. XX.SM
  231. XX.br
  232. XX.B char *format;
  233. XX.PP
  234. XX.B fprinterr(stream,format
  235. XX.RB [ ,
  236. XXarg ] ...
  237. XX.B )
  238. XX.br
  239. XX.SM
  240. XX.br
  241. XX.B FILE *stream;
  242. XX.br
  243. XX.B char *format;
  244. XX.SH DESCRIPTION
  245. XX.I Printerr
  246. XXand
  247. XX.I Fprinterr
  248. XXplace output on the standard error or the named
  249. XX.IR stream
  250. XXas appropriate in the same manner as
  251. XX.I printf(3)
  252. XXand
  253. XX.I fprintf(3).
  254. XXIf the format string \fB%m\fP is encountered in the format string, the
  255. XXsystem error message is printed similarly to
  256. XX.I perror(3).
  257. XX.SH DIAGNOSTICS
  258. XXIf an error number is encountered that is not part of the error list,
  259. XX.I Printerr
  260. XXwill use the words:
  261. XX.br
  262. XX\fIunknown error #\fP
  263. XX.br
  264. XXand the error number, instead of the (nonexistent) system error message.
  265. XX.SH CONSIDERATIONS
  266. XXIf the \fB%m\fP format string is omitted from the error message, this
  267. XXroutine is functionally identical to the related
  268. XX.I Printf()
  269. XXfunction.
  270. XX.SH EXAMPLE
  271. XX.nf
  272. XX.na
  273. XX    FILE    *log;
  274. XX    FILE    *willfail;
  275. XX    int    num;
  276. XX
  277. XX    /* open a log file */
  278. XX    if((log = fopen("LOGFILE","a")) == NULL) {
  279. XX        perror("LOGFILE");
  280. XX        exit(1);
  281. XX    }
  282. XX    
  283. XX    /* try to open stream that will fail */
  284. XX    /* assuming BADFILE is unopenable by user */
  285. XX#define BADFILE    "/dev/kmem"
  286. XX
  287. XX    if((willfail = fopen(BADFILE,"a")) == NULL) {
  288. XX        printerr("uid #%d can't open %s: %m\n",getuid(),BADFILE);
  289. XX        fprinterr(log,"uid #%d can't open %s: %m\n",getuid(),BADFILE);
  290. XX        exit(1);
  291. XX    }
  292. XX
  293. XX    /* this would put an error message to the standard error */
  294. XX    /* as well as placing it in a file */
  295. XX
  296. XX.fi
  297. XX.ad
  298. XX.SH AUTHOR
  299. XXMarcus Ranum
  300. XX.SH "SEE ALSO"
  301. XXfprintf(3), printf(3)
  302. XX.SH BUGS
  303. XX.PP
  304. XXVery wide fields (>128 characters) fail as in printf, since 
  305. XX.I printerr
  306. XXmakes use of stdio's _doprint(). 
  307. SHAR_EOF
  308. if test 1789 -ne "`wc -c printerr.l`"
  309. then
  310. echo shar: error transmitting printerr.l '(should have been 1789 characters)'
  311. fi
  312. #    End of shell archive
  313. exit 0
  314.