diff options
author | Marc G. Fournier <scrappy@hub.org> | 1996-07-09 06:22:35 +0000 |
---|---|---|
committer | Marc G. Fournier <scrappy@hub.org> | 1996-07-09 06:22:35 +0000 |
commit | d31084e9d1118b25fd16580d9d8c2924b5740dff (patch) | |
tree | 3179e66307d54df9c7b966543550e601eb55e668 /src/backend/utils/error/elog.c | |
download | postgresql-PG95-1_01.tar.gz postgresql-PG95-1_01.zip |
Postgres95 1.01 Distribution - Virgin SourcesPG95-1_01
Diffstat (limited to 'src/backend/utils/error/elog.c')
-rw-r--r-- | src/backend/utils/error/elog.c | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c new file mode 100644 index 00000000000..d5bef1ab1ba --- /dev/null +++ b/src/backend/utils/error/elog.c @@ -0,0 +1,237 @@ +/*------------------------------------------------------------------------- + * + * elog.c-- + * error logger + * + * Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.1.1.1 1996/07/09 06:22:07 scrappy Exp $ + * + *------------------------------------------------------------------------- + */ +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <fcntl.h> +#ifndef O_RDONLY +#include <sys/file.h> +#endif /* O_RDONLY */ +#include <sys/types.h> +#include <stdarg.h> +#include <errno.h> + +#include "postgres.h" +#include "miscadmin.h" +#include "utils/elog.h" +#include "libpq/libpq.h" +#include "storage/proc.h" + +static int Debugfile = -1; +static int Err_file = -1; +static int ElogDebugIndentLevel = 0; + +extern char OutputFileName[]; +#ifdef WIN32 +extern jmp_buf Warn_restart; +#endif + +/* + * elog -- + * Old error logging function. + */ +void +elog(int lev, char *fmt, ... ) +{ + va_list ap; + char buf[ELOG_MAXLEN], line[ELOG_MAXLEN]; + register char *bp, *cp; + extern int errno, sys_nerr; +#if !defined(PORTNAME_BSD44_derived) && !defined(PORTNAME_bsdi) + extern char *sys_errlist[]; +#endif /* !PORTNAME_BSD44_derived */ +#ifndef PG_STANDALONE + extern FILE *Pfout; +#endif /* !PG_STANDALONE */ + time_t tim, time(); + int len; + int i = 0; + + va_start(ap, fmt); + if (lev == DEBUG && Debugfile < 0) { + return; + } + switch (lev) { + case NOIND: + i = ElogDebugIndentLevel-1; + if (i < 0) i = 0; + if (i > 30) i = i%30; + cp = "DEBUG:"; + break; + case DEBUG: + i = ElogDebugIndentLevel; + if (i < 0) i = 0; + if (i > 30) i = i%30; + cp = "DEBUG:"; + break; + case NOTICE: + cp = "NOTICE:"; + break; + case WARN: + cp = "WARN:"; + break; + default: + sprintf(line, "FATAL %d:", lev); + cp = line; + } +#ifdef ELOG_TIMESTAMPS + time(&tim); + strcat(strcpy(buf, cp), ctime(&tim)+4); + bp = buf+strlen(buf)-6; + *bp++ = ':'; +#else + strcpy(buf,cp); + bp = buf+strlen(buf); +#endif + while (i-- >0) *bp++ = ' '; + for (cp = fmt; *cp; cp++) + if (*cp == '%' && *(cp+1) == 'm') { + if (errno < sys_nerr && errno >= 0) + strcpy(bp, sys_errlist[errno]); + else + sprintf(bp, "error %d", errno); + bp += strlen(bp); + cp++; + } else + *bp++ = *cp; + *bp = '\0'; + vsprintf(line, buf, ap); + va_end(ap); + len = strlen(strcat(line, "\n")); + if (Debugfile > -1) + write(Debugfile, line, len); + if (lev == DEBUG || lev == NOIND) + return; + + /* + * If there's an error log file other than our channel to the + * front-end program, write to it first. This is important + * because there's a bug in the socket code on ultrix. If the + * front end has gone away (so the channel to it has been closed + * at the other end), then writing here can cause this backend + * to exit without warning -- that is, write() does an exit(). + * In this case, our only hope of finding out what's going on + * is if Err_file was set to some disk log. This is a major pain. + */ + + if (Err_file > -1 && Debugfile != Err_file) { + if (write(Err_file, line, len) < 0) { + write(open("/dev/console", O_WRONLY, 0666), line, len); + fflush(stdout); + fflush(stderr); + exitpg(lev); + } + fsync(Err_file); + } + +#ifndef PG_STANDALONE + /* Send IPC message to the front-end program */ + if (Pfout != NULL && lev > DEBUG) { + /* notices are not exactly errors, handle it differently */ + if (lev == NOTICE) + pq_putnchar("N", 1); + else + pq_putnchar("E", 1); + /* pq_putint(-101, 4);*/ /* should be query id */ + pq_putstr(line); + pq_flush(); + } +#endif /* !PG_STANDALONE */ + + if (lev == WARN) { + ProcReleaseSpins(NULL); /* get rid of spinlocks we hold */ +#ifndef WIN32 + kill(getpid(), 1); /* abort to traffic cop */ + pause(); +#else + longjmp(Warn_restart, 1); +#endif /* WIN32 */ + /* + * The pause(3) is just to avoid race conditions where the + * thread of control on an MP system gets past here (i.e., + * the signal is not received instantaneously). + */ + } + + if (lev == FATAL) { + /* + * Assume that if we have detected the failure we can + * exit with a normal exit status. This will prevent + * the postmaster from cleaning up when it's not needed. + */ + fflush(stdout); + fflush(stderr); + ProcReleaseSpins(NULL); /* get rid of spinlocks we hold */ + ProcReleaseLocks(); /* get rid of real locks we hold */ + exitpg(0); + } + + if (lev > FATAL) { + fflush(stdout); + fflush(stderr); + exitpg(lev); + } +} + +#ifndef PG_STANDALONE +int +DebugFileOpen() +{ + int fd, istty; + + Err_file = Debugfile = -1; + ElogDebugIndentLevel = 0; + + if (OutputFileName[0]) { + OutputFileName[MAXPGPATH-1] = '\0'; + if ((fd = open(OutputFileName, O_CREAT|O_APPEND|O_WRONLY, + 0666)) < 0) + elog(FATAL, "DebugFileOpen: open of %s: %m", + OutputFileName); + istty = isatty(fd); + (void) close(fd); + /* If the file is a tty and we're running under the + * postmaster, try to send stdout there as well (if it + * isn't a tty then stderr will block out stdout, so we + * may as well let stdout go wherever it was going before). + */ + if (istty && + IsUnderPostmaster && + !freopen(OutputFileName, "a", stdout)) + elog(FATAL, "DebugFileOpen: %s reopen as stdout: %m", + OutputFileName); + if (!freopen(OutputFileName, "a", stderr)) + elog(FATAL, "DebugFileOpen: %s reopen as stderr: %m", + OutputFileName); + Err_file = Debugfile = fileno(stderr); + return(Debugfile); + } +#ifndef WIN32 + /* If no filename was specified, send debugging output to stderr. + * If stderr has been hosed, try to open a file. + */ + fd = fileno(stderr); + if (fcntl(fd, F_GETFD, 0) < 0) { + sprintf(OutputFileName, "%s/pg.errors.%d", + GetPGData(), getpid()); + fd = open(OutputFileName, O_CREAT|O_APPEND|O_WRONLY, 0666); + } +#endif /* WIN32 */ + if (fd < 0) + elog(FATAL, "DebugFileOpen: could not open debugging file"); + + Err_file = Debugfile = fd; + return(Debugfile); +} +#endif |