/src/common/err.c
https://code.google.com/ · C · 205 lines · 124 code · 25 blank · 56 comment · 47 complexity · ee9da4484c01ce5ef1a02c5fa6cc1e2a MD5 · raw file
- /*****************************************************************************\
- * $Id$
- *****************************************************************************
- * Copyright (C) 2001-2006 The Regents of the University of California.
- * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
- * Written by Jim Garlick <garlick@llnl.gov>.
- * UCRL-CODE-2003-005.
- *
- * This file is part of Pdsh, a parallel remote shell program.
- * For details, see <http://www.llnl.gov/linux/pdsh/>.
- *
- * Pdsh is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * Pdsh is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Pdsh; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- \*****************************************************************************/
- /*
- * Error printing routines with variable arguments.
- */
- #if HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include <stdarg.h>
- #include <netdb.h>
- #include <string.h>
- #include <assert.h>
- #if HAVE_UNISTD_H
- #include <unistd.h> /* gethostname */
- #endif
- #include <ctype.h>
- #include <stdlib.h> /* exit */
- #include "xstring.h"
- #include "xmalloc.h"
- #include "macros.h"
- static char *prog = NULL;
- static char *host = NULL;
- /*
- * Optionally leave domain on hostnames with _verr's %S
- */
- static bool keep_host_domain = false;
- /*
- * Call this before calling err() or errx(). Sets hostname and program name
- * for %H, %p, and %P.
- * str (IN) program name
- */
- void err_init(char *str)
- {
- char thishost[MAXHOSTNAMELEN];
- char *p;
- gethostname(thishost, MAXHOSTNAMELEN);
- if ((p = strchr(thishost, '.')) != NULL)
- *p = '\0';
- host = Strdup(thishost);
- prog = Strdup(str);
- }
- void err_no_strip_domain ()
- {
- keep_host_domain = true;
- }
- /*
- * Free heap storage allocated by err_init()
- */
- void err_cleanup(void)
- {
- Free((void **) &prog);
- Free((void **) &host);
- }
- /*
- * _verr() is like vfprintf, but handles (only) the following formats:
- * following formats:
- * %s string
- * %S string, but treat as hostname and truncate after dot
- * %c character
- * %m string (sys_errlist[errno])
- * %d int
- * %z equivalent to %.3d
- * %p program name with @host attached
- * %P program name
- * %H hostname for this host
- */
- static void _verr(FILE * stream, char *format, va_list ap)
- {
- char *buf = NULL;
- char *q;
- int percent = 0;
- char tmpstr[LINEBUFSIZE];
- /* Note: snprintf silently truncates if argument exceeds size of tmpstr */
- assert(prog != NULL && host != NULL);
- while (format && *format) { /* iterate thru chars */
- if (percent == 1) {
- percent = 0;
- if (*format == 's') { /* %s - string */
- xstrcat(&buf, va_arg(ap, char *));
- } else if (*format == 'S') { /* %S - string, trunc */
- snprintf(tmpstr, sizeof(tmpstr), "%s", va_arg(ap, char *));
- if ( !isdigit(*tmpstr)
- && !keep_host_domain
- && (q = strchr(tmpstr, '.')))
- *q = '\0';
- xstrcat(&buf, tmpstr);
- } else if (*format == 'z') { /* %z - same as %.3d */
- snprintf(tmpstr, sizeof(tmpstr), "%.3d", va_arg(ap, int));
- xstrcat(&buf, tmpstr);
- } else if (*format == 'c') { /* %c - character */
- xstrcatchar(&buf, va_arg(ap, int));
- } else if (*format == 'd') { /* %d - integer */
- snprintf(tmpstr, sizeof(tmpstr), "%d", va_arg(ap, int));
- xstrcat(&buf, tmpstr);
- } else if (*format == 'm') { /* %m - error code */
- xstrerrorcat(&buf);
- } else if (*format == 'P') { /* %P - prog name */
- assert(prog != NULL);
- xstrcat(&buf, prog);
- } else if (*format == 'H') { /* %H - this host */
- assert(host != NULL);
- xstrcat(&buf, host);
- } else if (*format == 'p') { /* %p - prog@host */
- assert(prog != NULL);
- assert(host != NULL);
- snprintf(tmpstr, sizeof(tmpstr), "%s@%s", prog, host);
- xstrcat(&buf, tmpstr);
- } else /* pass thru */
- xstrcatchar(&buf, *format);
- } else if (*format == '%')
- percent = 1; /* remember % */
- else
- xstrcatchar(&buf, *format); /* pass thru */
- format++;
- }
- fputs(buf, stream); /* print it */
- Free((void **) &buf); /* clean up */
- }
- void err(char *format, ...)
- {
- va_list ap;
- va_start(ap, format);
- _verr(stderr, format, ap);
- va_end(ap);
- }
- void errx(char *format, ...)
- {
- va_list ap;
- va_start(ap, format);
- _verr(stderr, format, ap);
- va_end(ap);
- exit(1);
- }
- void out(char *format, ...)
- {
- va_list ap;
- va_start(ap, format);
- _verr(stdout, format, ap);
- va_end(ap);
- }
- void errf(FILE *stream, char *format, va_list ap)
- {
- if (!stream)
- return;
- _verr(stream, format, ap);
- }
- void lsd_fatal_error(char *file, int line, char *mesg)
- {
- errx ("%p: %s:%d: %s\n", file, line, mesg);
- }
- void lsd_nomem_error(char *file, int line, char *mesg)
- {
- errx ("%p: %s:%d: %s: Out of memory\n", file, line, mesg);
- }
- /*
- * vi:tabstop=4 shiftwidth=4 expandtab
- */