diff options
Diffstat (limited to 'src/backend/utils/error/elog.c')
-rw-r--r-- | src/backend/utils/error/elog.c | 392 |
1 files changed, 212 insertions, 180 deletions
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index fae4c1adeef..e4cdc6d595b 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -1,13 +1,13 @@ /*------------------------------------------------------------------------- * * elog.c-- - * error logger + * error logger * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.17 1997/08/12 22:54:44 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.18 1997/09/07 04:53:15 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -17,7 +17,7 @@ #include <fcntl.h> #ifndef O_RDONLY #include <sys/file.h> -#endif /* O_RDONLY */ +#endif /* O_RDONLY */ #include <sys/types.h> #include <stdarg.h> #include <errno.h> @@ -29,204 +29,236 @@ #include "libpq/libpq.h" #include "storage/proc.h" -static int Debugfile = -1; -static int Err_file = -1; -static int ElogDebugIndentLevel = 0; +static int Debugfile = -1; +static int Err_file = -1; +static int ElogDebugIndentLevel = 0; -extern char OutputFileName[]; +extern char OutputFileName[]; /* * elog -- - * Old error logging function. + * Old error logging function. */ void -elog(int lev, const char *fmt, ... ) +elog(int lev, const char *fmt,...) { - va_list ap; - char buf[ELOG_MAXLEN], line[ELOG_MAXLEN]; - register char *bp; - register const char *cp; - extern int errno, sys_nerr; + va_list ap; + char buf[ELOG_MAXLEN], + line[ELOG_MAXLEN]; + register char *bp; + register const char *cp; + extern int errno, + sys_nerr; + #ifndef PG_STANDALONE - extern FILE *Pfout; -#endif /* !PG_STANDALONE */ + extern FILE *Pfout; + +#endif /* !PG_STANDALONE */ #ifdef ELOG_TIMESTAMPS - time_t tim; + time_t tim; + #endif - 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; - } + 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++ = ':'; + time(&tim); + strcat(strcpy(buf, cp), ctime(&tim) + 4); + bp = buf + strlen(buf) - 6; + *bp++ = ':'; #else - strcpy(buf,cp); - bp = buf+strlen(buf); + 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, strerror(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) { - extern int InWarn; - ProcReleaseSpins(NULL); /* get rid of spinlocks we hold */ - if (!InWarn) { - kill(getpid(), 1); /* abort to traffic cop */ - pause(); - } - /* - * 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) { + while (i-- > 0) + *bp++ = ' '; + for (cp = fmt; *cp; cp++) + if (*cp == '%' && *(cp + 1) == 'm') + { + if (errno < sys_nerr && errno >= 0) + strcpy(bp, strerror(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; + /* - * 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. + * 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. */ - 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); - } + + 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) + { + extern int InWarn; + + ProcReleaseSpins(NULL); /* get rid of spinlocks we hold */ + if (!InWarn) + { + kill(getpid(), 1); /* abort to traffic cop */ + pause(); + } + + /* + * 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(void) { - 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); - 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). + 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); + 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); + } + + /* + * If no filename was specified, send debugging output to stderr. If + * stderr has been hosed, try to open a file. */ - 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); - } - /* 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", - DataDir, (int)getpid()); - fd = open(OutputFileName, O_CREAT|O_APPEND|O_WRONLY, 0666); - } - if (fd < 0) - elog(FATAL, "DebugFileOpen: could not open debugging file"); - - Err_file = Debugfile = fd; - return(Debugfile); + fd = fileno(stderr); + if (fcntl(fd, F_GETFD, 0) < 0) + { + sprintf(OutputFileName, "%s/pg.errors.%d", + DataDir, (int) getpid()); + fd = open(OutputFileName, O_CREAT | O_APPEND | O_WRONLY, 0666); + } + if (fd < 0) + elog(FATAL, "DebugFileOpen: could not open debugging file"); + + Err_file = Debugfile = fd; + return (Debugfile); } + #endif |