1 /*
2  * Copyright 1987, 1988 by MIT Student Information Processing Board.
3  *
4  * Permission to use, copy, modify, and distribute this software and
5  * its documentation for any purpose is hereby granted, provided that
6  * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
7  * advertising or publicity pertaining to distribution of the software
8  * without specific, written prior permission.  M.I.T. and the
9  * M.I.T. S.I.P.B. make no representations about the suitability of
10  * this software for any purpose.  It is provided "as is" without
11  * express or implied warranty.
12  */
13 
14 #include <stdio.h>
15 #ifdef HAVE_TERMIOS_H
16 #include <termios.h>
17 #endif
18 #ifdef HAVE_UNISTD_H
19 #include <unistd.h>
20 #endif
21 #include "com_err.h"
22 #include "error_table.h"
23 #include "internal.h"
24 
25 static void
26 default_com_err_proc (const char *whoami, errcode_t code, const
27 		      char *fmt, va_list args)
28 	COM_ERR_ATTR((format(printf, 3, 0)));
29 
30 static void
default_com_err_proc(const char * whoami,errcode_t code,const char * fmt,va_list args)31 default_com_err_proc (const char *whoami, errcode_t code, const
32 		      char *fmt, va_list args)
33 {
34     int do_cr = 1, fd = fileno(stderr);
35 
36     if (whoami) {
37 	fputs(whoami, stderr);
38 	fputs(": ", stderr);
39     }
40     if (code) {
41 	fputs(error_message(code), stderr);
42 	fputs(" ", stderr);
43     }
44     if (fmt) {
45         vfprintf (stderr, fmt, args);
46     }
47     if (!isatty(fd))
48 	do_cr = 0;
49 #ifdef HAVE_TERMIOS_H
50     else {
51 	struct termios t;
52 
53 	if ((tcgetattr(fd, &t)) == 0 &&
54 	    (t.c_oflag & OPOST) && (t.c_oflag & ONLCR))
55 	do_cr = 0;
56     }
57 #endif
58     if (do_cr)
59 	fputc('\r', stderr);
60     fputc('\n', stderr);
61     fflush(stderr);
62 }
63 
64 typedef void (*errf) (const char *, errcode_t, const char *, va_list);
65 
66 errf com_err_hook = default_com_err_proc;
67 
com_err_va(const char * whoami,errcode_t code,const char * fmt,va_list args)68 void com_err_va (const char *whoami, errcode_t code, const char *fmt,
69 		 va_list args)
70 {
71     (*com_err_hook) (whoami, code, fmt, args);
72 }
73 
com_err(const char * whoami,errcode_t code,const char * fmt,...)74 void com_err (const char *whoami,
75 	      errcode_t code,
76 	      const char *fmt, ...)
77 {
78     va_list pvar;
79 
80     if (!com_err_hook)
81 	com_err_hook = default_com_err_proc;
82     va_start(pvar, fmt);
83     com_err_va (whoami, code, fmt, pvar);
84     va_end(pvar);
85 }
86 
set_com_err_hook(errf new_proc)87 errf set_com_err_hook(errf new_proc)
88 {
89     errf x = com_err_hook;
90 
91     if (new_proc)
92 	com_err_hook = new_proc;
93     else
94 	com_err_hook = default_com_err_proc;
95 
96     return x;
97 }
98 
reset_com_err_hook(void)99 errf reset_com_err_hook(void) {
100     errf x = com_err_hook;
101     com_err_hook = default_com_err_proc;
102     return x;
103 }
104