4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
24 * logadm/err.c -- some basic error routines
38 static const char *Myname
;
40 static FILE *Errorfile
;
43 * err_init -- initialize the error handling routine
47 err_init(const char *myname
)
51 if ((ptr
= strrchr(myname
, '/')) == NULL
)
57 static const char *File
;
61 * err_fileline -- record the filename/line number for err(EF_FILE, ...)
64 err_fileline(const char *file
, int line
)
71 * err -- print an error message and return, exit or longjmp based on flags
73 * this routine calls gettext() to translate the fmt string.
77 err(int flags
, const char *fmt
, ...)
80 int safe_errno
= errno
;
81 char *errno_msg
= NULL
;
86 char *prefix
= "Error: ";
90 intlfmt
= gettext(fmt
);
92 if (flags
& EF_WARN
) {
96 if (flags
& EF_FILE
) {
101 errno_msg
= strerror(safe_errno
);
107 /* print a copy to stderr */
109 if (Myname
!= NULL
) {
110 (void) fprintf(stderr
, "%s: ", Myname
);
112 (void) fprintf(Errorfile
, "%s: ", Myname
);
114 if (fileline
&& File
) {
115 (void) fprintf(stderr
, "%s line %d: ", File
, Line
);
117 (void) fprintf(Errorfile
,
118 "%s line %d: ", File
, Line
);
120 (void) fputs(gettext(prefix
), stderr
);
122 (void) fputs(gettext(prefix
), Errorfile
);
124 (void) vfprintf(stderr
, intlfmt
, ap
);
126 (void) vfprintf(Errorfile
, intlfmt
, ap
);
127 if (errno_msg
!= NULL
) {
128 (void) fprintf(stderr
, ": %s", errno_msg
);
130 (void) fprintf(Errorfile
, ": %s", errno_msg
);
133 (void) fprintf(stderr
, "\n");
135 (void) fprintf(Errorfile
, "\n");
137 (void) fflush(stderr
);
139 (void) fflush(Errorfile
);
144 longjmp(*Err_env_ptr
, 1);
146 if (!warning
&& !fileline
) {
153 * out -- print a message and return
155 * this routine calls gettext() to translate the fmt string.
159 out(const char *fmt
, ...)
165 (void) vfprintf(stdout
, gettext(fmt
), ap
);
170 #define CHUNKSIZE 8192 /* for copying stderr */
172 * err_fromfd -- copy data from fd to stderr
180 while ((count
= read(fd
, buf
, CHUNKSIZE
)) > 0) {
181 (void) fwrite(buf
, 1, count
, stderr
);
183 (void) fwrite(buf
, 1, count
, Errorfile
);
185 (void) fflush(stderr
);
187 (void) fflush(Errorfile
);
191 * err_done -- exit the program
194 err_done(int exitcode
)
196 /* send error mail if applicable */
206 #define MAXLINE 8192 /* for tmp file line buffer */
208 * err_mailto -- arrange for error output to be mailed to someone
211 err_mailto(const char *recipient
)
213 static const char *lastrecipient
;
214 static char mailcmd
[] = "/bin/mailx -s 'logadm error output'";
220 if (lastrecipient
!= NULL
) {
221 if (recipient
!= NULL
&&
222 strcmp(recipient
, lastrecipient
) == 0)
223 return; /* keep going, same recipient */
225 /* stop saving output for lastrecipient and send message */
226 if (ftell(Errorfile
)) {
228 len
= strlen(lastrecipient
) + strlen(mailcmd
) + 2;
230 (void) snprintf(cmd
, len
, "%s %s",
231 mailcmd
, lastrecipient
);
232 if ((pfp
= popen(cmd
, "w")) == NULL
)
233 err(EF_SYS
, "popen to mailx");
234 while (fgets(line
, MAXLINE
, Errorfile
) != NULL
)
235 (void) fputs(line
, pfp
);
238 (void) fclose(Errorfile
);
242 if (recipient
!= NULL
) {
243 /* start saving error output for this recipient */
244 if ((Errorfile
= tmpfile()) == NULL
)
245 err(EF_SYS
, "tmpfile");
247 lastrecipient
= recipient
;
251 * err_malloc -- a malloc() with checks
253 * this routine is typically called via the MALLOC() macro in err.h
256 err_malloc(int nbytes
, const char *fname
, int line
)
258 void *retval
= malloc(nbytes
);
261 err(0, "%s:%d: out of memory", fname
, line
);
267 * err_realloc -- a realloc() with checks
269 * this routine is typically called via the REALLOC() macro in err.h
272 err_realloc(void *ptr
, int nbytes
, const char *fname
, int line
)
274 void *retval
= realloc(ptr
, nbytes
);
277 err(0, "%s:%d: out of memory", fname
, line
);
283 * err_strdup -- a strdup() with checks
285 * this routine is typically called via the STRDUP() macro in err.h
288 err_strdup(const char *ptr
, const char *fname
, int line
)
293 retval
= strdup(ptr
);
295 err(0, "%s:%d: out of memory", fname
, line
);
297 err(0, "%s:%d: could not strdup", fname
, line
);
305 * err_free -- a free() with checks
307 * this routine is typically called via the FREE() macro in err.h
311 err_free(void *ptr
, const char *fname
, int line
)
313 /* nothing to check in this version */
318 * err_exitcode -- set an error exit code for when done(0) is called
321 err_exitcode(int exitcode
)