head 1.23; access; symbols Version_2_1:1.15 Version_2:1.10 C_Demo_1:1.8; locks; strict; comment @ * @; 1.23 date 92.08.07.00.43.22; author mao; state Exp; branches; next 1.22; 1.22 date 92.04.01.20.22.10; author mer; state Exp; branches; next 1.21; 1.21 date 92.04.01.20.06.20; author mer; state Exp; branches; next 1.20; 1.20 date 92.02.26.01.53.18; author hong; state Exp; branches; next 1.19; 1.19 date 91.08.12.22.25.08; author mao; state Exp; branches; next 1.18; 1.18 date 91.08.12.21.40.43; author mao; state Exp; branches; next 1.17; 1.17 date 91.08.08.17.00.47; author mer; state Exp; branches; next 1.16; 1.16 date 91.08.06.09.16.14; author mao; state Exp; branches; next 1.15; 1.15 date 91.02.10.18.23.46; author cimarron; state Exp; branches; next 1.14; 1.14 date 91.02.06.15.06.30; author mer; state Exp; branches; next 1.13; 1.13 date 90.09.21.11.10.58; author goh; state Exp; branches; next 1.12; 1.12 date 90.09.18.22.38.37; author hong; state Exp; branches; next 1.11; 1.11 date 90.08.15.08.47.31; author cimarron; state Exp; branches; next 1.10; 1.10 date 90.02.12.19.50.51; author cimarron; state Version_2; branches; next 1.9; 1.9 date 89.11.24.16.50.24; author hirohama; state Exp; branches; next 1.8; 1.8 date 89.09.05.17.27.36; author mao; state C_Demo_1; branches; next 1.7; 1.7 date 89.07.11.15.10.22; author dillon; state Exp; branches; next 1.6; 1.6 date 89.06.14.15.27.23; author hirohama; state Exp; branches; next 1.5; 1.5 date 89.05.22.15.01.49; author dillon; state Exp; branches; next 1.4; 1.4 date 89.05.22.10.33.20; author dillon; state Exp; branches; next 1.3; 1.3 date 89.03.08.15.28.40; author goh; state Stab; branches; next 1.2; 1.2 date 89.02.02.18.21.13; author aoki; state Exp; branches; next 1.1; 1.1 date 89.01.17.05.58.57; author cimarron; state Exp; branches; next ; desc @@ 1.23 log @rearrange order in which errors are logged to various log files and clean up the code. @ text @/* * elog.c -- * error logger */ #include #include #include #include #include #include "tmp/postgres.h" #include "utils/log.h" #include "installinfo.h" RcsId("$Header: /private/mao/postgres/src/utils/error/RCS/elog.c,v 1.22 1992/04/01 20:22:10 mer Exp $"); int Debug_file = -1; int Err_file = -1; int ElogDebugIndentLevel; /* * If the parser has detected an empty query from the front end, then * there is a chance that the front end has shut down. If this happens, * and we try to send a bunch of elog messages over our connection to * the front end, and we're running Ultrix 3.x, then fflush on the * connection socket can cause us to die without a core dump. Cool, yes? * The global below is set in PostgresMain and used here to work around * this operating system bug. */ void EnableELog(enable) int enable; { static int numEnabled; static int fault; Assert(fault == 0); if (!enable && --numEnabled) return; if (enable && numEnabled++) return; ++fault; if (enable) { /* XXX */ ; } else { /* XXX */ ; } --fault; } /*VARARGS2*/ void elog(va_alist) va_dcl { va_list ap; register int lev; char *fmt; char buf[ELOG_MAXLEN], line[ELOG_MAXLEN]; register char *bp, *cp; extern int errno, sys_nerr; extern char *sys_errlist[], *ctime(), *sprintf(); #ifndef PG_STANDALONE extern FILE *Pfout; #endif /* !PG_STANDALONE */ time_t tim, time(); int len; int i = 0; va_start(ap); lev = va_arg(ap, int); fmt = va_arg(ap, char *); if (lev == DEBUG && Debug_file < 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; } time(&tim); strcat(strcpy(buf, cp), ctime(&tim)+4); bp = buf+strlen(buf)-6; *bp++ = ':'; 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 (Debug_file > -1) write(Debug_file, 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 && Debug_file != 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 */ kill(getpid(), 1); /* abort to traffic cop */ } 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); } } /* * GetDataHome * * Extract the installation home directory from the environment. */ extern char *PostgresHomes[]; extern int NStriping; extern int StripingMode; char * GetDataHome() { char *home; char *p, *p1; int i; extern char *getenv(); home = getenv("POSTGRESHOME"); if (!StringIsValid(home)) { home = getenv("POSTHOME"); } if (!StringIsValid(home)) { home = DATAHOME; } if (!StringIsValid(home)) return NULL; p = home; i = 0; while ((p1 = index(p, ':')) != NULL) { *p1 = '\0'; PostgresHomes[i++] = p; p = p1 + 1; } if (*p >= '0' && *p <= '9') { /* specify raid level */ StripingMode = atoi(p); } else { PostgresHomes[i++] = p; } NStriping = i; if (StripingMode == 1) { if (NStriping % 2 != 0) elog(FATAL,"RAID Level 1 has to have an even number of disks."); NStriping /= 2; } else if (StripingMode < 0 || StripingMode > 5) elog(FATAL, "We only have RAID Level 0 -- 5."); else if (StripingMode > 1 && StripingMode < 5) elog(FATAL, "only RAID 0, 1 and 5 are supported."); return(home); } ErrorFileOpen() { int fd; char buffer[MAXPGPATH]; extern char *GetDataHome(); fd = fileno(stderr); if (fcntl(fd, F_GETFD, 0) < 0) { sprintf(buffer, "%s/data/pg.errors\0", GetDataHome()); fd = open(buffer, O_CREAT|O_APPEND|O_WRONLY, 0666); if (fd < 0) elog(FATAL, "ErrorFileOpen: open(%s) failed", buffer); } return(fd); } DebugFileOpen() { int fd; char buffer[MAXPGPATH]; extern char *GetDataHome(); fd = fileno(stderr); if (fcntl(fd, F_GETFD, 0) < 0) { sprintf(buffer, "%s/data/pg.debug\0", GetDataHome()); /* elog(NOTICE, "DebugFileOpen: opening %s", buffer); */ fd = open(buffer, O_CREAT|O_APPEND|O_WRONLY, 0666); if (fd < 0) elog(FATAL, "DebugFileOpen: open(%s) failed", buffer); } /* elog(NOTICE, "DebugFileOpen: opened %s, fd=%d", buffer, fd); */ return(fd); } @ 1.22 log @must free up resources before we go to die (on FATAL condition) @ text @d15 1 a15 1 RcsId("$Header: /users/mer/pg/src/utils/error/RCS/elog.c,v 1.21 1992/04/01 20:06:20 mer Exp mer $"); d130 21 d152 1 a152 1 /* Send IPC message to the postmaster */ a164 7 if (Err_file > -1 && Debug_file != Err_file) if (write(Err_file, line, len) < 0) { write(open("/dev/console", O_WRONLY, 0666), line, len); fflush(stdout); fflush(stderr); exitpg(lev); } d252 1 a254 3 /* elog(NOTICE, "ErrorFileOpen: opening %s", buffer); */ d259 1 a259 3 /* elog(NOTICE, "ErrorFileOpen: opened %s, fd=%d", buffer, fd); */ @ 1.21 log @exit 0 on fatal, assumes that no postmaster cleanup is needed. @ text @d15 1 a15 1 RcsId("$Header: /users/mer/pg/src/utils/error/RCS/elog.c,v 1.20 1992/02/26 01:53:18 hong Exp mer $"); d164 2 @ 1.20 log @support RAID level 1 and 5 @ text @d15 1 a15 1 RcsId("$Header: RCS/elog.c,v 1.19 91/08/12 22:25:08 mao Exp Locker: hong $"); d156 12 a167 1 if (lev >= FATAL) { @ 1.19 log @on elog(WARN, ...), release spinlocks @ text @d15 1 a15 1 RcsId("$Header: /local/mao/postgres/src/utils/error/RCS/elog.c,v 1.18 1991/08/12 21:40:43 mao Exp mao $"); d172 1 d197 7 a203 1 PostgresHomes[i++] = p; d205 9 @ 1.18 log @get rid of bogosity for handling channel botches on ultrix -- fix protocol instead. @ text @d15 1 a15 1 RcsId("$Header: /local/mao/postgres/src/utils/error/RCS/elog.c,v 1.17 1991/08/08 17:00:47 mer Exp mao $"); d151 2 a152 1 if (lev == WARN) d154 2 @ 1.17 log @install workaround for bug in ultrix socket handling -- if there's some chance that our correspondent has left, don't send messages to him. @ text @d15 1 a15 1 RcsId("$Header: RCS/elog.c,v 1.16 91/08/06 09:16:14 mao Exp $"); a31 3 bool IsEmptyQuery = false; d132 1 a132 1 if (Pfout != NULL && lev > DEBUG && !IsEmptyQuery) { @ 1.16 log @arg count to open() was wrong @ text @d15 1 a15 1 RcsId("$Header: RCS/elog.c,v 1.15 91/02/10 18:23:46 cimarron Exp Locker: mao $"); d22 9 d32 3 d135 1 a135 1 if (Pfout != NULL && lev > DEBUG) { @ 1.15 log @reorganization of libpq routines to provide PQexec and PQfn functionality from both the front end applications and the postgres backend. @ text @d15 1 a15 1 RcsId("$Header: RCS/elog.c,v 1.14 91/02/06 15:06:30 mer Exp Locker: cimarron $"); d137 1 a137 1 write(open("/dev/console", O_WRONLY), line, len); @ 1.14 log @added varargs and the passing of FATAL and NOTICE messages back to libpq. @ text @d15 1 a15 1 RcsId("$Header: RCS/elog.c,v 1.13 90/09/21 11:10:58 goh Exp Locker: mer $"); d126 1 a126 1 putnchar("N", 1); d128 4 a131 4 putnchar("E", 1); putint(-101, 4); /* should be query id */ putstr(line); pflush(); @ 1.13 log @probably absolutely the wrong fix, but the elog buffer is 256 which means that anything over 256 trashes something. Made the constant to check against be ELOG_MAXLEN (which is now exported in lib/H/utils/log.h ) For now at least, if you suspect that a string sent to elog might come close to exceeding it, you need to manually check it in the calling routine. - jeff @ text @d9 1 d15 1 a15 1 RcsId("$Header: RCS/elog.c,v 1.12 90/09/18 22:38:37 hong Exp Locker: goh $"); d51 2 a52 3 elog(lev, fmt, p0, p1, p2, p3, p4, p5) int lev; char *fmt; d54 3 d68 3 d113 2 a114 1 sprintf(line, buf, p0, p1, p2, p3, p4, p5); d116 1 a116 1 if (Debug_file > -1) { a117 1 } d123 6 a128 2 if (Pfout != NULL && lev > DEBUG && lev != NOTICE) { putnchar("E", 1); @ 1.12 log @cleaned up striping code @ text @d14 1 a14 1 RcsId("$Header: RCS/elog.c,v 1.11 90/08/15 08:47:31 cimarron Exp Locker: hong $"); d54 1 a54 1 char buf[256], line[256]; @ 1.11 log @added pathnames to include statements @ text @d14 1 a14 1 RcsId("$Header: RCS/elog.c,v 1.10 90/02/12 19:50:51 cimarron Version_2 Locker: cimarron $"); d147 4 d155 2 d166 10 @ 1.10 log @added buffer manager statistics and exitpg() stuff -cim @ text @d9 3 a11 3 #include "c.h" #include "log.h" #include "postgres.h" d14 1 a14 1 RcsId("$Header: RCS/elog.c,v 1.9 89/11/24 16:50:24 hirohama Exp $"); @ 1.9 log @CppAsString(DATAHOME) ["DATAHOME"] -> DATAHOME @ text @d14 1 a14 1 RcsId("$Header: RCS/elog.c,v 1.8 89/09/05 17:27:36 mao C_Demo_1 Locker: hirohama $"); d130 1 a130 1 exit(lev); d137 1 a137 1 exit(lev); @ 1.8 log @Working version of C-only demo @ text @d14 1 a14 1 RcsId("$Header: /usr6/postgres/mao/postgres/src/utils/error/RCS/elog.c,v 1.7 89/07/11 15:10:22 dillon Exp $"); d153 7 a159 3 if ((home = getenv("POSTGRESHOME")) == (char *) NULL && (home = getenv("POSTHOME")) == (char *) NULL) home = CppAsString(DATAHOME); @ 1.7 log @now #include's installinfo.h (in $OD) to get DATAHOME @ text @d14 1 a14 1 RcsId("$Header: /usr6/postgres/dillon/tree/src/utils/error/RCS/elog.c,v 1.6 89/06/14 15:27:23 hirohama Exp $"); @ 1.6 log @DATAHOME is not a string anymore..., so make it one @ text @d12 1 d14 1 a14 1 RcsId("$Header: /usr6/postgres/hirohama/postgres/src/utils/error/RCS/elog.c,v 1.5 89/05/22 15:01:49 dillon Exp $"); @ 1.5 log @Enable code added @ text @d13 1 a13 1 RcsId("$Header: /usr6/postgres/dillon/tree/src/utils/error/RCS/elog.c,v 1.4 89/05/22 10:33:20 dillon Exp $"); d154 1 a154 1 home = DATAHOME; @ 1.4 log @add EnableELog @ text @d13 1 a13 1 RcsId("$Header: /usr6/postgres/dillon/tree/src/utils/error/RCS/elog.c,v 1.3 89/03/08 15:28:40 goh Stab $"); a25 1 #ifdef DOUBLECHECK d28 1 a28 2 Assert(!fault); #endif a34 1 #ifdef DOUBLECHECK a35 1 #endif a42 1 #ifdef DOUBLECHECK a43 1 #endif @ 1.3 log @minor fix @ text @d13 1 a13 1 RcsId("$Header: elog.c,v 1.2 89/02/02 18:21:13 aoki Exp $"); d19 33 @ 1.2 log @MERGE WITH OLD TREE @ text @d13 1 a13 1 RcsId("$Header: elog.c,v 2.11 88/08/22 14:34:40 aoki Locked $"); d29 1 a29 1 extern char *sys_errlist[], *ctime(), sprintf(); @ 1.1 log @Initial revision @ text @a0 1 a1 26 * * POSTGRES Data Base Management System * * Copyright (c) 1988 Regents of the University of California * * Permission to use, copy, modify, and distribute this software and its * documentation for educational, research, and non-profit purposes and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of the University of California not be used in advertising * or publicity pertaining to distribution of the software without * specific, written prior permission. Permission to incorporate this * software into commercial products can be obtained from the Campus * Software Office, 295 Evans Hall, University of California, Berkeley, * Ca., 94720 provided only that the the requestor give the University * of California a free licence to any derived software for educational * and research purposes. The University of California makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * */ /* d13 1 a13 1 RcsId("$Header: elog.c,v 1.1 88/11/11 16:42:13 postgres Exp $"); @