diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index 7f219634c6..0287de35b1 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -7,7 +7,7 @@ * Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.10 1996/11/10 01:37:48 bryanh Exp $ + * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.11 1996/11/14 10:23:34 bryanh Exp $ * *------------------------------------------------------------------------- */ @@ -17,7 +17,7 @@ #include #include -#define BOOTSTRAP_INCLUDE /* mask out stuff in tcop/tcopprot.h */ +#define BOOTSTRAP_INCLUDE /* mask out stuff in tcop/tcopprot.h */ #include "postgres.h" @@ -99,13 +99,13 @@ #include "utils/palloc.h" -#define ALLOC(t, c) (t *)calloc((unsigned)(c), sizeof(t)) -#define FIRST_TYPE_OID 16 /* OID of the first type */ +#define ALLOC(t, c) (t *)calloc((unsigned)(c), sizeof(t)) +#define FIRST_TYPE_OID 16 /* OID of the first type */ extern int Int_yyparse (void); /* ---------------- - * global variables + * global variables * ---------------- */ /* @@ -118,34 +118,34 @@ * position of its string pointer in the array of string pointers. */ -#define STRTABLESIZE 10000 -#define HASHTABLESIZE 503 +#define STRTABLESIZE 10000 +#define HASHTABLESIZE 503 /* Hash function numbers */ -#define NUM 23 -#define NUMSQR 529 -#define NUMCUBE 12167 +#define NUM 23 +#define NUMSQR 529 +#define NUMCUBE 12167 char *strtable [STRTABLESIZE]; -hashnode *hashtable [HASHTABLESIZE]; +hashnode *hashtable [HASHTABLESIZE]; -static int strtable_end = -1; /* Tells us last occupied string space */ +static int strtable_end = -1; /* Tells us last occupied string space */ /*- * Basic information associated with each type. This is used before * pg_type is created. * - * XXX several of these input/output functions do catalog scans - * (e.g., F_REGPROCIN scans pg_proc). this obviously creates some - * order dependencies in the catalog creation process. + * XXX several of these input/output functions do catalog scans + * (e.g., F_REGPROCIN scans pg_proc). this obviously creates some + * order dependencies in the catalog creation process. */ struct typinfo { - char name[NAMEDATALEN]; - Oid oid; - Oid elem; - int16 len; - Oid inproc; - Oid outproc; + char name[NAMEDATALEN]; + Oid oid; + Oid elem; + int16 len; + Oid inproc; + Oid outproc; }; static struct typinfo Procid[] = { @@ -154,7 +154,7 @@ static struct typinfo Procid[] = { { "char", 18, 0, 1, F_CHARIN, F_CHAROUT }, { "name", 19, 0, NAMEDATALEN, F_NAMEIN, F_NAMEOUT }, { "char16", 20, 0, 16, F_CHAR16IN, F_CHAR16OUT}, -/* { "dt", 20, 0, 4, F_DTIN, F_DTOUT}, */ +/* { "dt", 20, 0, 4, F_DTIN, F_DTOUT}, */ { "int2", 21, 0, 2, F_INT2IN, F_INT2OUT }, { "int28", 22, 0, 16, F_INT28IN, F_INT28OUT }, { "int4", 23, 0, 4, F_INT4IN, F_INT4OUT }, @@ -172,23 +172,23 @@ static struct typinfo Procid[] = { static int n_types = sizeof(Procid) / sizeof(struct typinfo); -struct typmap { /* a hack */ - Oid am_oid; - TypeTupleFormData am_typ; +struct typmap { /* a hack */ + Oid am_oid; + TypeTupleFormData am_typ; }; -static struct typmap **Typ = (struct typmap **)NULL; -static struct typmap *Ap = (struct typmap *)NULL; +static struct typmap **Typ = (struct typmap **)NULL; +static struct typmap *Ap = (struct typmap *)NULL; -static int Warnings = 0; -static char Blanks[MAXATTR]; +static int Warnings = 0; +static char Blanks[MAXATTR]; -Relation reldesc; /* current relation descriptor */ +Relation reldesc; /* current relation descriptor */ static char *relname; /* current relation name */ AttributeTupleForm attrtypes[MAXATTR]; /* points to attribute info */ -static char *values[MAXATTR]; /* cooresponding attribute values */ -int numattr; /* number of attributes for cur. rel */ +static char *values[MAXATTR]; /* cooresponding attribute values */ +int numattr; /* number of attributes for cur. rel */ extern int fsyncOff; /* do not fsync the database */ #ifdef NEED_SIG_JMP @@ -199,11 +199,11 @@ static jmp_buf Warn_restart; static sigjmp_buf Warn_restart; #endif -int DebugMode; -static GlobalMemory nogc = (GlobalMemory) NULL; /* special no-gc mem context */ +int DebugMode; +static GlobalMemory nogc = (GlobalMemory) NULL; /* special no-gc mem context */ -extern int optind; -extern char *optarg; +extern int optind; +extern char *optarg; /* * At bootstrap time, we first declare all the indices to be built, and @@ -212,15 +212,15 @@ extern char *optarg; */ typedef struct _IndexList { - char* il_heap; - char* il_ind; - int il_natts; - AttrNumber *il_attnos; - uint16 il_nparams; - Datum * il_params; - FuncIndexInfo *il_finfo; - PredInfo *il_predInfo; - struct _IndexList *il_next; + char* il_heap; + char* il_ind; + int il_natts; + AttrNumber *il_attnos; + uint16 il_nparams; + Datum * il_params; + FuncIndexInfo *il_finfo; + PredInfo *il_predInfo; + struct _IndexList *il_next; } IndexList; static IndexList *ILHead = (IndexList *) NULL; @@ -230,12 +230,12 @@ typedef void (*sig_func)(); /* ---------------------------------------------------------------- - * misc functions + * misc functions * ---------------------------------------------------------------- */ /* ---------------- - * error handling / abort routines + * error handling / abort routines * ---------------- */ void @@ -262,33 +262,33 @@ usage(void) exitpg(1); } + + +int +BootstrapMain(int argc, char *argv[]) /* ---------------------------------------------------------------- - * BootstrapMain - * the main loop for handling the backend in bootstrap mode + * The main loop for handling the backend in bootstrap mode * the bootstrap mode is used to initialize the template database * the bootstrap backend doesn't speak SQL, but instead expects * commands in a special bootstrap language. - * they are a special bootstrap language. * - * the arguments passed in to BootstrapMain are the run-time arguments - * without the argument '-boot', the caller is required to have - * removed -boot from the run-time args + * The arguments passed in to BootstrapMain are the run-time arguments + * without the argument '-boot', the caller is required to have + * removed -boot from the run-time args * ---------------------------------------------------------------- */ -int -BootstrapMain(int argc, char *argv[]) { - int i; - int portFd = -1; + int i; + int portFd = -1; char *dbName; int flag; int override = 1; /* use BootstrapProcessing or InitProcessing mode */ - extern int optind; - extern char *optarg; + extern int optind; + extern char *optarg; /* ---------------- - * initialize signal handlers + * initialize signal handlers * ---------------- */ signal(SIGINT, (sig_func) die); @@ -298,69 +298,83 @@ BootstrapMain(int argc, char *argv[]) #endif /* win32 */ /* -------------------- - * initialize globals + * initialize globals * ------------------- */ - InitGlobals(); + MasterPid = getpid(); /* ---------------- - * process command arguments + * process command arguments * ---------------- */ + + /* Set defaults, to be overriden by explicit options below */ Quiet = 0; Noversion = 0; dbName = NULL; + DataDir = getenv("PGDATA"); /* Null if no PGDATA variable */ - while ((flag = getopt(argc, argv, "dCOQP:F")) != EOF) { - switch (flag) { - case 'd': - DebugMode = 1; /* print out debuggin info while parsing */ - break; - case 'C': - Noversion = 1; - break; + while ((flag = getopt(argc, argv, "D:dCOQP:F")) != EOF) { + switch (flag) { + case 'D': + DataDir = optarg; + case 'd': + DebugMode = 1; /* print out debugging info while parsing */ + break; + case 'C': + Noversion = 1; + break; case 'F': fsyncOff = 1; break; - case 'O': - override = true; - break; - case 'Q': - Quiet = 1; - break; - case 'P':/* specify port */ - portFd = atoi(optarg); - break; - default: - usage(); - break; - } + case 'O': + override = true; + break; + case 'Q': + Quiet = 1; + break; + case 'P':/* specify port */ + portFd = atoi(optarg); + break; + default: + usage(); + break; + } } /* while */ if (argc - optind > 1) { - usage(); + usage(); } else if (argc - optind == 1) { - dbName = argv[optind]; + dbName = argv[optind]; } + if (!DataDir) { + fprintf(stderr, "%s does not know where to find the database system " + "data. You must specify the directory that contains the " + "database system either by specifying the -D invocation " + "option or by setting the PGDATA environment variable.\n\n", + argv[0]); + exitpg(1); + } + if (dbName == NULL) { - dbName = getenv("USER"); - if (dbName == NULL) { - fputs("bootstrap backend: failed, no db name specified\n", stderr); - fputs(" and no USER enviroment variable\n", stderr); - exitpg(1); - } + dbName = getenv("USER"); + if (dbName == NULL) { + fputs("bootstrap backend: failed, no db name specified\n", stderr); + fputs(" and no USER enviroment variable\n", stderr); + exitpg(1); + } } /* ---------------- - * initialize input fd + * initialize input fd * ---------------- */ if (IsUnderPostmaster == true && portFd < 0) { - fputs("backend: failed, no -P option with -postmaster opt.\n", stderr); - exitpg(1); + fputs("backend: failed, no -P option with -postmaster opt.\n", stderr); + exitpg(1); } #ifdef win32 @@ -370,7 +384,7 @@ BootstrapMain(int argc, char *argv[]) /* ---------------- - * backend initialization + * backend initialization * ---------------- */ SetProcessingMode((override) ? BootstrapProcessing : InitProcessing); @@ -378,16 +392,16 @@ BootstrapMain(int argc, char *argv[]) LockDisable(true); for (i = 0 ; i < MAXATTR; i++) { - attrtypes[i]=(AttributeTupleForm )NULL; - Blanks[i] = ' '; + attrtypes[i]=(AttributeTupleForm )NULL; + Blanks[i] = ' '; } for(i = 0; i < STRTABLESIZE; ++i) - strtable[i] = NULL; + strtable[i] = NULL; for(i = 0; i < HASHTABLESIZE; ++i) - hashtable[i] = NULL; + hashtable[i] = NULL; /* ---------------- - * abort processing resumes here - What to do in WIN32? + * abort processing resumes here - What to do in WIN32? * ---------------- */ #ifndef win32 @@ -397,12 +411,12 @@ BootstrapMain(int argc, char *argv[]) #else if (setjmp(Warn_restart) != 0) { #endif /* win32 */ - Warnings++; - AbortCurrentTransaction(); + Warnings++; + AbortCurrentTransaction(); } /* ---------------- - * process input. + * process input. * ---------------- */ @@ -421,113 +435,113 @@ BootstrapMain(int argc, char *argv[]) } /* ---------------------------------------------------------------- - * MANUAL BACKEND INTERACTIVE INTERFACE COMMANDS + * MANUAL BACKEND INTERACTIVE INTERFACE COMMANDS * ---------------------------------------------------------------- */ /* ---------------- - * boot_openrel + * boot_openrel * ---------------- */ void boot_openrel(char *relname) { - int i; - struct typmap **app; - Relation rdesc; - HeapScanDesc sdesc; - HeapTuple tup; + int i; + struct typmap **app; + Relation rdesc; + HeapScanDesc sdesc; + HeapTuple tup; if (strlen(relname) > 15) - relname[15] ='\000'; + relname[15] ='\000'; if (Typ == (struct typmap **)NULL) { - StartPortalAllocMode(DefaultAllocMode, 0); - rdesc = heap_openr(TypeRelationName); - sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey)NULL); - for (i=0; PointerIsValid(tup=heap_getnext(sdesc,0,(Buffer *)NULL)); ++i); - heap_endscan(sdesc); - app = Typ = ALLOC(struct typmap *, i + 1); - while (i-- > 0) - *app++ = ALLOC(struct typmap, 1); - *app = (struct typmap *)NULL; - sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey)NULL); - app = Typ; - while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *)NULL))) { - (*app)->am_oid = tup->t_oid; - memmove((char *)&(*app++)->am_typ, - (char *)GETSTRUCT(tup), - sizeof ((*app)->am_typ)); - } - heap_endscan(sdesc); - heap_close(rdesc); - EndPortalAllocMode(); + StartPortalAllocMode(DefaultAllocMode, 0); + rdesc = heap_openr(TypeRelationName); + sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey)NULL); + for (i=0; PointerIsValid(tup=heap_getnext(sdesc,0,(Buffer *)NULL)); ++i); + heap_endscan(sdesc); + app = Typ = ALLOC(struct typmap *, i + 1); + while (i-- > 0) + *app++ = ALLOC(struct typmap, 1); + *app = (struct typmap *)NULL; + sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey)NULL); + app = Typ; + while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *)NULL))) { + (*app)->am_oid = tup->t_oid; + memmove((char *)&(*app++)->am_typ, + (char *)GETSTRUCT(tup), + sizeof ((*app)->am_typ)); + } + heap_endscan(sdesc); + heap_close(rdesc); + EndPortalAllocMode(); } if (reldesc != NULL) { - closerel(NULL); + closerel(NULL); } if (!Quiet) - printf("Amopen: relation %s. attrsize %d\n", relname, - ATTRIBUTE_TUPLE_SIZE); + printf("Amopen: relation %s. attrsize %d\n", relname, + ATTRIBUTE_TUPLE_SIZE); reldesc = heap_openr(relname); Assert(reldesc); numattr = reldesc->rd_rel->relnatts; for (i = 0; i < numattr; i++) { - if (attrtypes[i] == NULL) { - attrtypes[i] = AllocateAttribute(); - } - memmove((char *)attrtypes[i], - (char *)reldesc->rd_att->attrs[i], - ATTRIBUTE_TUPLE_SIZE); - - /* Some old pg_attribute tuples might not have attisset. */ - /* If the attname is attisset, don't look for it - it may - not be defined yet. - */ - if (namestrcmp(&attrtypes[i]->attname, "attisset") == 0) - attrtypes[i]->attisset = get_attisset(reldesc->rd_id, - attrtypes[i]->attname.data); - else - attrtypes[i]->attisset = false; - - if (DebugMode) { - AttributeTupleForm at = attrtypes[i]; - printf("create attribute %d name %.*s len %d num %d type %d\n", - i, NAMEDATALEN, at->attname.data, at->attlen, at->attnum, - at->atttypid - ); - fflush(stdout); - } + if (attrtypes[i] == NULL) { + attrtypes[i] = AllocateAttribute(); + } + memmove((char *)attrtypes[i], + (char *)reldesc->rd_att->attrs[i], + ATTRIBUTE_TUPLE_SIZE); + + /* Some old pg_attribute tuples might not have attisset. */ + /* If the attname is attisset, don't look for it - it may + not be defined yet. + */ + if (namestrcmp(&attrtypes[i]->attname, "attisset") == 0) + attrtypes[i]->attisset = get_attisset(reldesc->rd_id, + attrtypes[i]->attname.data); + else + attrtypes[i]->attisset = false; + + if (DebugMode) { + AttributeTupleForm at = attrtypes[i]; + printf("create attribute %d name %.*s len %d num %d type %d\n", + i, NAMEDATALEN, at->attname.data, at->attlen, at->attnum, + at->atttypid + ); + fflush(stdout); + } } } /* ---------------- - * closerel + * closerel * ---------------- */ void closerel(char *name) { if (name) { - if (reldesc) { - if (namestrcmp(RelationGetRelationName(reldesc), name) != 0) - elog(WARN,"closerel: close of '%s' when '%s' was expected", - name, relname); - } else - elog(WARN,"closerel: close of '%s' before any relation was opened", - name); - + if (reldesc) { + if (namestrcmp(RelationGetRelationName(reldesc), name) != 0) + elog(WARN,"closerel: close of '%s' when '%s' was expected", + name, relname); + } else + elog(WARN,"closerel: close of '%s' before any relation was opened", + name); + } if (reldesc == NULL) { - elog(WARN,"Warning: no opened relation to close.\n"); + elog(WARN,"Warning: no opened relation to close.\n"); } else { - if (!Quiet) printf("Amclose: relation %s.\n", relname); - heap_close(reldesc); - reldesc = (Relation)NULL; + if (!Quiet) printf("Amclose: relation %s.\n", relname); + heap_close(reldesc); + reldesc = (Relation)NULL; } } @@ -547,36 +561,36 @@ DefineAttr(char *name, char *type, int attnum) int t; if (reldesc != NULL) { - fputs("Warning: no open relations allowed with 't' command.\n",stderr); - closerel(relname); + fputs("Warning: no open relations allowed with 't' command.\n",stderr); + closerel(relname); } t = gettype(type); if (attrtypes[attnum] == (AttributeTupleForm )NULL) - attrtypes[attnum] = AllocateAttribute(); + attrtypes[attnum] = AllocateAttribute(); if (Typ != (struct typmap **)NULL) { - attrtypes[attnum]->atttypid = Ap->am_oid; - namestrcpy(&attrtypes[attnum]->attname, name); - if (!Quiet) printf("<%.*s %s> ", NAMEDATALEN, - attrtypes[attnum]->attname.data, type); - attrtypes[attnum]->attnum = 1 + attnum; /* fillatt */ - attlen = attrtypes[attnum]->attlen = Ap->am_typ.typlen; - attrtypes[attnum]->attbyval = Ap->am_typ.typbyval; + attrtypes[attnum]->atttypid = Ap->am_oid; + namestrcpy(&attrtypes[attnum]->attname, name); + if (!Quiet) printf("<%.*s %s> ", NAMEDATALEN, + attrtypes[attnum]->attname.data, type); + attrtypes[attnum]->attnum = 1 + attnum; /* fillatt */ + attlen = attrtypes[attnum]->attlen = Ap->am_typ.typlen; + attrtypes[attnum]->attbyval = Ap->am_typ.typbyval; } else { - attrtypes[attnum]->atttypid = Procid[t].oid; - namestrcpy(&attrtypes[attnum]->attname,name); - if (!Quiet) printf("<%.*s %s> ", NAMEDATALEN, - attrtypes[attnum]->attname.data, type); - attrtypes[attnum]->attnum = 1 + attnum; /* fillatt */ - attlen = attrtypes[attnum]->attlen = Procid[t].len; - attrtypes[attnum]->attbyval = (attlen==1) || (attlen==2)||(attlen==4); + attrtypes[attnum]->atttypid = Procid[t].oid; + namestrcpy(&attrtypes[attnum]->attname,name); + if (!Quiet) printf("<%.*s %s> ", NAMEDATALEN, + attrtypes[attnum]->attname.data, type); + attrtypes[attnum]->attnum = 1 + attnum; /* fillatt */ + attlen = attrtypes[attnum]->attlen = Procid[t].len; + attrtypes[attnum]->attbyval = (attlen==1) || (attlen==2)||(attlen==4); } } /* ---------------- - * InsertOneTuple - * assumes that 'oid' will not be zero. + * InsertOneTuple + * assumes that 'oid' will not be zero. * ---------------- */ void @@ -588,8 +602,8 @@ InsertOneTuple(Oid objectid) int i; if (DebugMode) { - printf("InsertOneTuple oid %d, %d attrs\n", objectid, numattr); - fflush(stdout); + printf("InsertOneTuple oid %d, %d attrs\n", objectid, numattr); + fflush(stdout); } tupDesc = CreateTupleDesc(numattr,attrtypes); @@ -597,90 +611,90 @@ InsertOneTuple(Oid objectid) pfree(tupDesc); /* just free's tupDesc, not the attrtypes */ if(objectid !=(Oid)0) { - tuple->t_oid=objectid; + tuple->t_oid=objectid; } heap_insert(reldesc, tuple); pfree(tuple); if (DebugMode) { - printf("End InsertOneTuple, objectid=%d\n", objectid); - fflush(stdout); + printf("End InsertOneTuple, objectid=%d\n", objectid); + fflush(stdout); } /* * Reset blanks for next tuple */ for (i = 0; i= MAXATTR) { - printf("i out of range: %d\n", i); - Assert(0); + printf("i out of range: %d\n", i); + Assert(0); } if (Typ != (struct typmap **)NULL) { - struct typmap *ap; - if (DebugMode) - puts("Typ != NULL"); - app = Typ; - while (*app && (*app)->am_oid != reldesc->rd_att->attrs[i]->atttypid) - ++app; - ap = *app; - if (ap == NULL) { - printf("Unable to find atttypid in Typ list! %d\n", - reldesc->rd_att->attrs[i]->atttypid - ); - Assert(0); - } - values[i] = fmgr(ap->am_typ.typinput, - value, - ap->am_typ.typelem, - -1); /* shouldn't have char() or varchar() types - during boostrapping but just to be safe */ - prt = fmgr(ap->am_typ.typoutput, values[i], - ap->am_typ.typelem); - if (!Quiet) printf("%s ", prt); - pfree(prt); + struct typmap *ap; + if (DebugMode) + puts("Typ != NULL"); + app = Typ; + while (*app && (*app)->am_oid != reldesc->rd_att->attrs[i]->atttypid) + ++app; + ap = *app; + if (ap == NULL) { + printf("Unable to find atttypid in Typ list! %d\n", + reldesc->rd_att->attrs[i]->atttypid + ); + Assert(0); + } + values[i] = fmgr(ap->am_typ.typinput, + value, + ap->am_typ.typelem, + -1); /* shouldn't have char() or varchar() types + during boostrapping but just to be safe */ + prt = fmgr(ap->am_typ.typoutput, values[i], + ap->am_typ.typelem); + if (!Quiet) printf("%s ", prt); + pfree(prt); } else { - typeindex = attrtypes[i]->atttypid - FIRST_TYPE_OID; - if (DebugMode) - printf("Typ == NULL, typeindex = %d idx = %d\n", typeindex, i); - values[i] = fmgr(Procid[typeindex].inproc, value, - Procid[typeindex].elem, -1); - prt = fmgr(Procid[typeindex].outproc, values[i], - Procid[typeindex].elem); - if (!Quiet) printf("%s ", prt); - pfree(prt); + typeindex = attrtypes[i]->atttypid - FIRST_TYPE_OID; + if (DebugMode) + printf("Typ == NULL, typeindex = %d idx = %d\n", typeindex, i); + values[i] = fmgr(Procid[typeindex].inproc, value, + Procid[typeindex].elem, -1); + prt = fmgr(Procid[typeindex].outproc, values[i], + Procid[typeindex].elem); + if (!Quiet) printf("%s ", prt); + pfree(prt); } if (DebugMode) { - puts("End InsertValue"); - fflush(stdout); + puts("End InsertValue"); + fflush(stdout); } } /* ---------------- - * InsertOneNull + * InsertOneNull * ---------------- */ void InsertOneNull(int i) { if (DebugMode) - printf("Inserting null\n"); + printf("Inserting null\n"); if (i < 0 || i >= MAXATTR) { - elog(FATAL, "i out of range (too many attrs): %d\n", i); + elog(FATAL, "i out of range (too many attrs): %d\n", i); } values[i] = (char *)NULL; Blanks[i] = 'n'; @@ -699,85 +713,85 @@ BootstrapAlreadySeen(Oid id) seenthis = false; for (i=0; i < nseen; i++) { - if (seenArray[i] == id) { - seenthis = true; - break; - } + if (seenArray[i] == id) { + seenthis = true; + break; + } } if (!seenthis) { - seenArray[nseen] = id; - nseen++; + seenArray[nseen] = id; + nseen++; } return (seenthis); } /* ---------------- - * cleanup + * cleanup * ---------------- */ void cleanup() { - static int beenhere = 0; + static int beenhere = 0; if (!beenhere) - beenhere = 1; + beenhere = 1; else { - elog(FATAL,"Memory manager fault: cleanup called twice.\n", stderr); - exitpg(1); + elog(FATAL,"Memory manager fault: cleanup called twice.\n", stderr); + exitpg(1); } if (reldesc != (Relation)NULL) { - heap_close(reldesc); + heap_close(reldesc); } CommitTransactionCommand(); exitpg(Warnings); } /* ---------------- - * gettype + * gettype * ---------------- */ int gettype(char *type) { - int i; - Relation rdesc; - HeapScanDesc sdesc; - HeapTuple tup; - struct typmap **app; + int i; + Relation rdesc; + HeapScanDesc sdesc; + HeapTuple tup; + struct typmap **app; if (Typ != (struct typmap **)NULL) { - for (app = Typ; *app != (struct typmap *)NULL; app++) { - if (strncmp((*app)->am_typ.typname.data, type, NAMEDATALEN) == 0) { - Ap = *app; - return((*app)->am_oid); - } - } + for (app = Typ; *app != (struct typmap *)NULL; app++) { + if (strncmp((*app)->am_typ.typname.data, type, NAMEDATALEN) == 0) { + Ap = *app; + return((*app)->am_oid); + } + } } else { - for (i = 0; i <= n_types; i++) { - if (strncmp(type, Procid[i].name, NAMEDATALEN) == 0) { - return(i); - } - } - if (DebugMode) - printf("bootstrap.c: External Type: %.*s\n", NAMEDATALEN, type); + for (i = 0; i <= n_types; i++) { + if (strncmp(type, Procid[i].name, NAMEDATALEN) == 0) { + return(i); + } + } + if (DebugMode) + printf("bootstrap.c: External Type: %.*s\n", NAMEDATALEN, type); rdesc = heap_openr(TypeRelationName); sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey)NULL); - i = 0; - while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *)NULL))) - ++i; - heap_endscan(sdesc); - app = Typ = ALLOC(struct typmap *, i + 1); - while (i-- > 0) - *app++ = ALLOC(struct typmap, 1); - *app = (struct typmap *)NULL; - sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey)NULL); - app = Typ; - while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *)NULL))) { - (*app)->am_oid = tup->t_oid; - memmove((char *)&(*app++)->am_typ, - (char *)GETSTRUCT(tup), - sizeof ((*app)->am_typ)); + i = 0; + while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *)NULL))) + ++i; + heap_endscan(sdesc); + app = Typ = ALLOC(struct typmap *, i + 1); + while (i-- > 0) + *app++ = ALLOC(struct typmap, 1); + *app = (struct typmap *)NULL; + sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey)NULL); + app = Typ; + while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *)NULL))) { + (*app)->am_oid = tup->t_oid; + memmove((char *)&(*app++)->am_typ, + (char *)GETSTRUCT(tup), + sizeof ((*app)->am_typ)); } heap_endscan(sdesc); heap_close(rdesc); @@ -790,17 +804,17 @@ gettype(char *type) } /* ---------------- - * AllocateAttribute + * AllocateAttribute * ---------------- */ AttributeTupleForm /* XXX */ AllocateAttribute() { AttributeTupleForm attribute = - (AttributeTupleForm)malloc(ATTRIBUTE_TUPLE_SIZE); + (AttributeTupleForm)malloc(ATTRIBUTE_TUPLE_SIZE); if (!PointerIsValid(attribute)) { - elog(FATAL, "AllocateAttribute: malloc failed"); + elog(FATAL, "AllocateAttribute: malloc failed"); } memset(attribute, 0, ATTRIBUTE_TUPLE_SIZE); @@ -808,7 +822,7 @@ AllocateAttribute() } /* ---------------- - * MapArrayTypeName + * MapArrayTypeName * XXX arrays of "basetype" are always "_basetype". * this is an evil hack inherited from rel. 3.1. * XXX array dimension is thrown away because we @@ -828,12 +842,12 @@ MapArrayTypeName(char *s) static char newStr[NAMEDATALEN]; /* array type names < NAMEDATALEN long */ if (s == NULL || s[0] == '\0') - return s; + return s; j = 1; newStr[0] = '_'; for (i=0; istrnum); + return (node->strnum); } else { - node = AddStr(str, len, 0); - return (node->strnum); + node = AddStr(str, len, 0); + return (node->strnum); } } /* ---------------- - * LexIDStr - * when given an idnum into the 'string-table' return the string - * associated with the idnum + * LexIDStr + * when given an idnum into the 'string-table' return the string + * associated with the idnum * ---------------- */ char * @@ -877,12 +891,12 @@ LexIDStr(int ident_num) /* ---------------- - * CompHash + * CompHash * - * Compute a hash function for a given string. We look at the first, - * the last, and the middle character of a string to try to get spread - * the strings out. The function is rather arbitrary, except that we - * are mod'ing by a prime number. + * Compute a hash function for a given string. We look at the first, + * the last, and the middle character of a string to try to get spread + * the strings out. The function is rather arbitrary, except that we + * are mod'ing by a prime number. * ---------------- */ int @@ -897,54 +911,54 @@ CompHash(char *str, int len) } /* ---------------- - * FindStr + * FindStr * - * This routine looks for the specified string in the hash - * table. It returns a pointer to the hash node found, - * or NULL if the string is not in the table. + * This routine looks for the specified string in the hash + * table. It returns a pointer to the hash node found, + * or NULL if the string is not in the table. * ---------------- */ hashnode * FindStr(char *str, int length, hashnode *mderef) { - hashnode *node; + hashnode *node; node = hashtable [CompHash (str, length)]; while (node != NULL) { - /* - * We must differentiate between string constants that - * might have the same value as a identifier - * and the identifier itself. - */ - if (!strcmp(str, strtable[node->strnum])) { - return(node); /* no need to check */ - } else { - node = node->next; - } + /* + * We must differentiate between string constants that + * might have the same value as a identifier + * and the identifier itself. + */ + if (!strcmp(str, strtable[node->strnum])) { + return(node); /* no need to check */ + } else { + node = node->next; + } } /* Couldn't find it in the list */ return (NULL); } /* ---------------- - * AddStr + * AddStr * - * This function adds the specified string, along with its associated - * data, to the hash table and the string table. We return the node - * so that the calling routine can find out the unique id that AddStr - * has assigned to this string. + * This function adds the specified string, along with its associated + * data, to the hash table and the string table. We return the node + * so that the calling routine can find out the unique id that AddStr + * has assigned to this string. * ---------------- */ hashnode * AddStr(char *str, int strlength, int mderef) { - hashnode *temp, *trail, *newnode; - int hashresult; - int len; + hashnode *temp, *trail, *newnode; + int hashresult; + int len; if (++strtable_end == STRTABLESIZE) { - /* Error, string table overflow, so we Punt */ - elog(FATAL, - "There are too many string constants and identifiers for the compiler to handle."); + /* Error, string table overflow, so we Punt */ + elog(FATAL, + "There are too many string constants and identifiers for the compiler to handle."); } @@ -958,7 +972,7 @@ AddStr(char *str, int strlength, int mderef) */ if ((len = strlength + 1) < NAMEDATALEN) - len = NAMEDATALEN; + len = NAMEDATALEN; strtable [strtable_end] = malloc((unsigned) len); strcpy (strtable[strtable_end], str); @@ -973,15 +987,15 @@ AddStr(char *str, int strlength, int mderef) hashresult = CompHash (str, strlength); if (hashtable [hashresult] == NULL) { - hashtable [hashresult] = newnode; - } else { /* There is something in the list */ - trail = hashtable [hashresult]; - temp = trail->next; - while (temp != NULL) { - trail = temp; - temp = temp->next; - } - trail->next = newnode; + hashtable [hashresult] = newnode; + } else { /* There is something in the list */ + trail = hashtable [hashresult]; + temp = trail->next; + while (temp != NULL) { + trail = temp; + temp = temp->next; + } + trail->next = newnode; } return (newnode); } @@ -990,23 +1004,23 @@ AddStr(char *str, int strlength, int mderef) /* * index_register() -- record an index that has been set up for building - * later. + * later. * - * At bootstrap time, we define a bunch of indices on system catalogs. - * We postpone actually building the indices until just before we're - * finished with initialization, however. This is because more classes - * and indices may be defined, and we want to be sure that all of them - * are present in the index. + * At bootstrap time, we define a bunch of indices on system catalogs. + * We postpone actually building the indices until just before we're + * finished with initialization, however. This is because more classes + * and indices may be defined, and we want to be sure that all of them + * are present in the index. */ void index_register(char *heap, - char *ind, - int natts, - AttrNumber *attnos, - uint16 nparams, - Datum *params, - FuncIndexInfo *finfo, - PredInfo *predInfo) + char *ind, + int natts, + AttrNumber *attnos, + uint16 nparams, + Datum *params, + FuncIndexInfo *finfo, + PredInfo *predInfo) { Datum *v; IndexList *newind; @@ -1020,7 +1034,7 @@ index_register(char *heap, */ if (nogc == (GlobalMemory) NULL) - nogc = CreateGlobalMemory("BootstrapNoGC"); + nogc = CreateGlobalMemory("BootstrapNoGC"); oldcxt = MemoryContextSwitchTo((MemoryContext) nogc); @@ -1030,37 +1044,37 @@ index_register(char *heap, newind->il_natts = natts; if (PointerIsValid(finfo)) - len = FIgetnArgs(finfo) * sizeof(AttrNumber); + len = FIgetnArgs(finfo) * sizeof(AttrNumber); else - len = natts * sizeof(AttrNumber); + len = natts * sizeof(AttrNumber); newind->il_attnos = (AttrNumber *) palloc(len); memmove(newind->il_attnos, attnos, len); if ((newind->il_nparams = nparams) > 0) { - v = newind->il_params = (Datum *) palloc(2 * nparams * sizeof(Datum)); - nparams *= 2; - while (nparams-- > 0) { - *v = (Datum) palloc(strlen((char *)(*params)) + 1); - strcpy((char *) *v++, (char *) *params++); - } + v = newind->il_params = (Datum *) palloc(2 * nparams * sizeof(Datum)); + nparams *= 2; + while (nparams-- > 0) { + *v = (Datum) palloc(strlen((char *)(*params)) + 1); + strcpy((char *) *v++, (char *) *params++); + } } else { - newind->il_params = (Datum *) NULL; + newind->il_params = (Datum *) NULL; } if (finfo != (FuncIndexInfo *) NULL) { - newind->il_finfo = (FuncIndexInfo *) palloc(sizeof(FuncIndexInfo)); - memmove(newind->il_finfo, finfo, sizeof(FuncIndexInfo)); + newind->il_finfo = (FuncIndexInfo *) palloc(sizeof(FuncIndexInfo)); + memmove(newind->il_finfo, finfo, sizeof(FuncIndexInfo)); } else { - newind->il_finfo = (FuncIndexInfo *) NULL; + newind->il_finfo = (FuncIndexInfo *) NULL; } if (predInfo != NULL) { - newind->il_predInfo = (PredInfo*)palloc(sizeof(PredInfo)); - newind->il_predInfo->pred = predInfo->pred; - newind->il_predInfo->oldPred = predInfo->oldPred; + newind->il_predInfo = (PredInfo*)palloc(sizeof(PredInfo)); + newind->il_predInfo->pred = predInfo->pred; + newind->il_predInfo->oldPred = predInfo->oldPred; } else { - newind->il_predInfo = NULL; + newind->il_predInfo = NULL; } newind->il_next = ILHead; @@ -1077,31 +1091,31 @@ build_indices() Relation ind; for ( ; ILHead != (IndexList *) NULL; ILHead = ILHead->il_next) { - heap = heap_openr(ILHead->il_heap); - ind = index_openr(ILHead->il_ind); - index_build(heap, ind, ILHead->il_natts, ILHead->il_attnos, - ILHead->il_nparams, ILHead->il_params, ILHead->il_finfo, - ILHead->il_predInfo); - - /* - * All of the rest of this routine is needed only because in bootstrap - * processing we don't increment xact id's. The normal DefineIndex - * code replaces a pg_class tuple with updated info including the - * relhasindex flag (which we need to have updated). Unfortunately, - * there are always two indices defined on each catalog causing us to - * update the same pg_class tuple twice for each catalog getting an - * index during bootstrap resulting in the ghost tuple problem (see - * heap_replace). To get around this we change the relhasindex - * field ourselves in this routine keeping track of what catalogs we - * already changed so that we don't modify those tuples twice. The - * normal mechanism for updating pg_class is disabled during bootstrap. - * - * -mer - */ - heap = heap_openr(ILHead->il_heap); - - if (!BootstrapAlreadySeen(heap->rd_id)) - UpdateStats(heap->rd_id, 0, true); + heap = heap_openr(ILHead->il_heap); + ind = index_openr(ILHead->il_ind); + index_build(heap, ind, ILHead->il_natts, ILHead->il_attnos, + ILHead->il_nparams, ILHead->il_params, ILHead->il_finfo, + ILHead->il_predInfo); + + /* + * All of the rest of this routine is needed only because in bootstrap + * processing we don't increment xact id's. The normal DefineIndex + * code replaces a pg_class tuple with updated info including the + * relhasindex flag (which we need to have updated). Unfortunately, + * there are always two indices defined on each catalog causing us to + * update the same pg_class tuple twice for each catalog getting an + * index during bootstrap resulting in the ghost tuple problem (see + * heap_replace). To get around this we change the relhasindex + * field ourselves in this routine keeping track of what catalogs we + * already changed so that we don't modify those tuples twice. The + * normal mechanism for updating pg_class is disabled during bootstrap. + * + * -mer + */ + heap = heap_openr(ILHead->il_heap); + + if (!BootstrapAlreadySeen(heap->rd_id)) + UpdateStats(heap->rd_id, 0, true); } } diff --git a/src/backend/libpq/Makefile b/src/backend/libpq/Makefile index 0dbf2fb134..c8a0533a2b 100644 --- a/src/backend/libpq/Makefile +++ b/src/backend/libpq/Makefile @@ -4,7 +4,7 @@ # Makefile for libpq subsystem (backend half of libpq interface) # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.3 1996/11/06 08:48:21 scrappy Exp $ +# $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.4 1996/11/14 10:23:51 bryanh Exp $ # #------------------------------------------------------------------------- @@ -16,7 +16,6 @@ INCLUDE_OPT = -I.. \ -I../../include CFLAGS+=$(INCLUDE_OPT) -CFLAGS+= -DPOSTPORT='"$(POSTPORT)"' # kerberos flags ifdef KRBVERS diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index 76707512c5..9cb6998d03 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.6 1996/11/08 05:56:21 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.7 1996/11/14 10:23:53 bryanh Exp $ * *------------------------------------------------------------------------- */ @@ -140,7 +140,7 @@ pq_getport() if (envport) return(atoi(envport)); - return(atoi(POSTPORT)); + return(atoi(DEF_PGPORT)); } /* -------------------------------- diff --git a/src/backend/port/win32/nt.h b/src/backend/port/win32/nt.h index a879e37f16..6dc54ae651 100644 --- a/src/backend/port/win32/nt.h +++ b/src/backend/port/win32/nt.h @@ -30,7 +30,6 @@ struct sembuf #define MAXHOSTNAMELEN 12 /* where is the official definition of this? */ #define MAXPATHLEN _MAX_PATH /* in winsock.h */ -#define POSTPORT "5432" /* NT has stricmp not strcasecmp. Which is ANSI? */ #define strcasecmp(a,b) _stricmp(a,b) @@ -46,5 +45,3 @@ struct sembuf #define GETNCNT 5 #define GETVAL 6 -#define POSTGRESDIR "d:\\pglite" -#define PGDATADIR "d:\\pglite\\data" diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 7ef3ea4bd7..9726a92fd0 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -10,38 +10,38 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.24 1996/11/12 06:46:36 bryanh Exp $ + * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.25 1996/11/14 10:24:01 bryanh Exp $ * * NOTES * * Initialization: - * The Postmaster sets up a few shared memory data structures - * for the backends. It should at the very least initialize the - * lock manager. + * The Postmaster sets up a few shared memory data structures + * for the backends. It should at the very least initialize the + * lock manager. * * Synchronization: - * The Postmaster shares memory with the backends and will have to lock - * the shared memory it accesses. The Postmaster should never block - * on messages from clients. - * + * The Postmaster shares memory with the backends and will have to lock + * the shared memory it accesses. The Postmaster should never block + * on messages from clients. + * * Garbage Collection: - * The Postmaster cleans up after backends if they have an emergency - * exit and/or core dump. + * The Postmaster cleans up after backends if they have an emergency + * exit and/or core dump. * * Communication: * *------------------------------------------------------------------------- */ - /* moved here to prevent double define */ -#include /* for MAXHOSTNAMELEN on most */ + /* moved here to prevent double define */ +#include /* for MAXHOSTNAMELEN on most */ #ifndef MAXHOSTNAMELEN -#include /* for MAXHOSTNAMELEN on some */ +#include /* for MAXHOSTNAMELEN on some */ #endif #include "postgres.h" -#include /* for other stuff */ -#include "libpq/pqsignal.h" /* substitute for */ +#include /* for other stuff */ +#include "libpq/pqsignal.h" /* substitute for */ #include #include @@ -50,13 +50,13 @@ #endif /* !NO_UNISTD_H */ #include -#include /* for fd_set stuff */ -#include /* for umask */ +#include /* for fd_set stuff */ +#include /* for umask */ #include #include #if defined(USE_LIMITS_H) # include -# define MAXINT INT_MAX +# define MAXINT INT_MAX #else # include #endif /* !USE_LIMITS_H */ @@ -103,7 +103,7 @@ * but I left this structure around in case that changed. */ typedef struct bkend { - int pid; /* process id of backend */ + int pid; /* process id of backend */ } Backend; /* list of active backends. For garbage collection only now. */ @@ -113,24 +113,27 @@ static Dllist* BackendList; /* list of ports associated with still open, but incomplete connections */ static Dllist* PortList; -static short PostPortName = -1; -static short ActiveBackends = FALSE; -static int NextBackendId = MAXINT; /* XXX why? */ -static char *progname = (char *) NULL; +static short PostPortName = -1; +static short ActiveBackends = FALSE; +static int NextBackendId = MAXINT; /* XXX why? */ +static char *progname = (char *) NULL; -char *DataDir = (char *) NULL; +char *DataDir; + /* The PGDATA directory user says to use, or defaults to via environment + variable. NULL if no option given and no environment variable set + */ /* * Default Values */ -static char Execfile[MAXPATHLEN] = ""; +static char Execfile[MAXPATHLEN] = ""; -static int ServerSock = INVALID_SOCK; /* stream socket server */ +static int ServerSock = INVALID_SOCK; /* stream socket server */ /* * Set by the -o option */ -static char ExtraOptions[ARGV_SIZE] = ""; +static char ExtraOptions[ARGV_SIZE] = ""; /* * These globals control the behavior of the postmaster in case some @@ -139,8 +142,8 @@ static char ExtraOptions[ARGV_SIZE] = ""; * the postmaster stop (rather than kill) peers and not reinitialize * shared data structures. */ -static int Reinit = 1; -static int SendStop = 0; +static int Reinit = 1; +static int SendStop = 0; static int MultiplexedBackends = 0; static int MultiplexedBackendPort; @@ -160,7 +163,6 @@ static void CleanupProc(int pid, int exitstatus); static int DoExec(StartupInfo *packet, int portFd); static void ExitPostmaster(int status); static void usage(const char *); -static void checkDataDir(void); int ServerLoop(void); int BackendStartup(StartupInfo *packet, Port *port, int *pidPtr); static void send_error_reply(Port *port, const char *errormsg); @@ -168,142 +170,194 @@ static void send_error_reply(Port *port, const char *errormsg); extern char *optarg; extern int optind, opterr; + + +static void +checkDataDir(const char *DataDir, bool *DataDirOK) +{ + if (DataDir == NULL) { + fprintf(stderr, "%s does not know where to find the database system " + "data. You must specify the directory that contains the " + "database system either by specifying the -D invocation " + "option or by setting the PGDATA environment variable.\n\n", + progname); + *DataDirOK = false; + } else { + char path[MAXPATHLEN]; + FILE *fp; + + sprintf(path, "%s%cbase%ctemplate1%cpg_class", + DataDir, SEP_CHAR, SEP_CHAR, SEP_CHAR); + fp = fopen(path, "r"); + if (fp == NULL) { + fprintf(stderr, "%s does not find the database system. " + "Expected to find it " + "in the PGDATA directory \"%s\", but unable to open file " + "with pathname \"%s\".\n\n", + progname, DataDir, path); + *DataDirOK = false; + } else { + char *reason; + /* reason ValidatePgVersion failed. NULL if didn't */ + + fclose(fp); + +#ifndef WIN32 + ValidatePgVersion(DataDir, &reason); +#else + reason = NULL; +#endif /* WIN32 */ + if (reason) { + fprintf(stderr, + "Database system in directory %s " + "is not compatible with this version of " + "Postgres, or we are unable to read the " + "PG_VERSION file. " + "Explanation from ValidatePgVersion: %s\n\n", + DataDir, reason); + free(reason); + *DataDirOK = false; + } else *DataDirOK = true; + } + } +} + + + int PostmasterMain(int argc, char *argv[]) { - extern int NBuffers; /* from buffer/bufmgr.c */ - extern bool IsPostmaster; /* from smgr/mm.c */ - int opt; - char *hostName; - int status; - int silentflag = 0; - char hostbuf[MAXHOSTNAMELEN]; + extern int NBuffers; /* from buffer/bufmgr.c */ + extern bool IsPostmaster; /* from smgr/mm.c */ + int opt; + char *hostName; + int status; + int silentflag = 0; + char hostbuf[MAXHOSTNAMELEN]; + bool DataDirOK; /* We have a usable PGDATA value */ #if defined(WIN32) WSADATA WSAData; #endif /* WIN32 */ progname = argv[0]; + IsPostmaster = true; + /* for security, no dir or file created can be group or other accessible */ (void) umask((mode_t) 0077); if (!(hostName = getenv("PGHOST"))) { - if (gethostname(hostbuf, MAXHOSTNAMELEN) < 0) - (void) strcpy(hostbuf, "localhost"); - hostName = hostbuf; + if (gethostname(hostbuf, MAXHOSTNAMELEN) < 0) + (void) strcpy(hostbuf, "localhost"); + hostName = hostbuf; } + + DataDir = getenv("PGDATA"); /* default value */ opterr = 0; while ((opt = getopt(argc, argv, "a:B:b:D:dmM:no:p:Ss")) != EOF) { - switch (opt) { - case 'a': - /* Set the authentication system. */ - be_setauthsvc(optarg); - break; - case 'B': - /* - * The number of buffers to create. Setting this - * option means we have to start each backend with - * a -B # to make sure they know how many buffers - * were allocated. - */ - NBuffers = atol(optarg); - (void) strcat(ExtraOptions, " -B "); - (void) strcat(ExtraOptions, optarg); - break; - case 'b': - /* Set the backend executable file to use. */ - if (!ValidateBackend(optarg)) - strcpy(Execfile, optarg); - else { - fprintf(stderr, "%s: invalid backend \"%s\"\n", - progname, optarg); - exit(2); - } - break; - case 'D': - /* Set PGDATA from the command line. */ - DataDir = optarg; - break; - case 'd': - /* - * Turn on debugging for the postmaster and the backend - * servers descended from it. - */ - if ((optind < argc) && *argv[optind] != '-') { - DebugLvl = atoi(argv[optind]); - optind++; - } - else - DebugLvl = 1; - break; - case 'm': - MultiplexedBackends = 1; - MultiplexedBackendPort = atoi(optarg); - break; - case 'M': - /* ignore this flag. This may be passed in because the - program was run as 'postgres -M' instead of 'postmaster' */ - break; - case 'n': - /* Don't reinit shared mem after abnormal exit */ - Reinit = 0; - break; - case 'o': - /* - * Other options to pass to the backend on the - * command line -- useful only for debugging. - */ - (void) strcat(ExtraOptions, " "); - (void) strcat(ExtraOptions, optarg); - break; - case 'p': - /* Set PGPORT by hand. */ - PostPortName = (short) atoi(optarg); - break; - case 'S': - /* - * Start in 'S'ilent mode (disassociate from controlling tty). - * You may also think of this as 'S'ysV mode since it's most - * badly needed on SysV-derived systems like SVR4 and HP-UX. - */ - silentflag = 1; - break; - case 's': - /* - * In the event that some backend dumps core, - * send SIGSTOP, rather than SIGUSR1, to all - * its peers. This lets the wily post_hacker - * collect core dumps from everyone. - */ - SendStop = 1; - break; - default: - /* usage() never returns */ - usage(progname); - break; - } + switch (opt) { + case 'a': + /* Set the authentication system. */ + be_setauthsvc(optarg); + break; + case 'B': + /* + * The number of buffers to create. Setting this + * option means we have to start each backend with + * a -B # to make sure they know how many buffers + * were allocated. + */ + NBuffers = atol(optarg); + (void) strcat(ExtraOptions, " -B "); + (void) strcat(ExtraOptions, optarg); + break; + case 'b': + /* Set the backend executable file to use. */ + if (!ValidateBackend(optarg)) + strcpy(Execfile, optarg); + else { + fprintf(stderr, "%s: invalid backend \"%s\"\n", + progname, optarg); + exit(2); + } + break; + case 'D': + /* Set PGDATA from the command line. */ + DataDir = optarg; + break; + case 'd': + /* + * Turn on debugging for the postmaster and the backend + * servers descended from it. + */ + if ((optind < argc) && *argv[optind] != '-') { + DebugLvl = atoi(argv[optind]); + optind++; + } + else + DebugLvl = 1; + break; + case 'm': + MultiplexedBackends = 1; + MultiplexedBackendPort = atoi(optarg); + break; + case 'M': + /* ignore this flag. This may be passed in because the + program was run as 'postgres -M' instead of 'postmaster' */ + break; + case 'n': + /* Don't reinit shared mem after abnormal exit */ + Reinit = 0; + break; + case 'o': + /* + * Other options to pass to the backend on the + * command line -- useful only for debugging. + */ + (void) strcat(ExtraOptions, " "); + (void) strcat(ExtraOptions, optarg); + break; + case 'p': + /* Set PGPORT by hand. */ + PostPortName = (short) atoi(optarg); + break; + case 'S': + /* + * Start in 'S'ilent mode (disassociate from controlling tty). + * You may also think of this as 'S'ysV mode since it's most + * badly needed on SysV-derived systems like SVR4 and HP-UX. + */ + silentflag = 1; + break; + case 's': + /* + * In the event that some backend dumps core, + * send SIGSTOP, rather than SIGUSR1, to all + * its peers. This lets the wily post_hacker + * collect core dumps from everyone. + */ + SendStop = 1; + break; + default: + /* usage() never returns */ + usage(progname); + break; + } } if (PostPortName == -1) - PostPortName = pq_getport(); + PostPortName = pq_getport(); - IsPostmaster = true; - - if (!DataDir) - DataDir = GetPGData(); + checkDataDir(DataDir, &DataDirOK); /* issues error messages */ + if (!DataDirOK) { + fprintf(stderr, "No data directory -- can't proceed.\n"); + exit(2); + } - /* - * check whether the data directory exists. Passing this test doesn't - * gaurantee we are accessing the right data base but is a first barrier - * to site administrators who starts up the postmaster without realizing - * it cannot access the data base. - */ - checkDataDir(); - if (!Execfile[0] && FindBackend(Execfile, argv[0]) < 0) { - fprintf(stderr, "%s: could not find backend to execute...\n", - argv[0]); - exit(1); + fprintf(stderr, "%s: could not find backend to execute...\n", + argv[0]); + exit(1); } @@ -321,9 +375,9 @@ PostmasterMain(int argc, char *argv[]) status = StreamServerPort(hostName, PostPortName, &ServerSock); if (status != STATUS_OK) { - fprintf(stderr, "%s: cannot create stream port\n", - progname); - exit(1); + fprintf(stderr, "%s: cannot create stream port\n", + progname); + exit(1); } /* set up shared memory and semaphores */ @@ -338,7 +392,7 @@ PostmasterMain(int argc, char *argv[]) PortList = DLNewList(); if (silentflag) - pmdaemonize(); + pmdaemonize(); signal(SIGINT, pmdie); #ifndef WIN32 @@ -363,12 +417,12 @@ pmdaemonize(void) int i; if (fork()) - exit(0); + exit(0); if (setsid() < 0) { - fprintf(stderr, "%s: ", progname); - perror("cannot disassociate from controlling TTY"); - exit(1); + fprintf(stderr, "%s: ", progname); + perror("cannot disassociate from controlling TTY"); + exit(1); } i = open(NULL_DEV, O_RDWR); (void) dup2(i, 0); @@ -398,9 +452,9 @@ usage(const char *progname) int ServerLoop(void) { - int serverFd = ServerSock; - fd_set rmask, basemask; - int nSockets, nSelected, status, newFd; + int serverFd = ServerSock; + fd_set rmask, basemask; + int nSockets, nSelected, status, newFd; Dlelem *next, *curr; /* int orgsigmask = sigblock(0); */ sigset_t oldsigmask, newsigmask; @@ -413,104 +467,104 @@ ServerLoop(void) sigemptyset(&newsigmask); sigaddset(&newsigmask,SIGCHLD); for (;;) { -/* sigsetmask(orgsigmask); */ - sigprocmask(SIG_SETMASK,&oldsigmask,0); - newFd = -1; - memmove((char *) &rmask, (char *) &basemask, sizeof(fd_set)); - if ((nSelected = select(nSockets, &rmask, - (fd_set *) NULL, - (fd_set *) NULL, - (struct timeval *) NULL)) < 0) { - if (errno == EINTR) - continue; - fprintf(stderr, "%s: ServerLoop: select failed\n", - progname); - return(STATUS_ERROR); +/* sigsetmask(orgsigmask); */ + sigprocmask(SIG_SETMASK,&oldsigmask,0); + newFd = -1; + memmove((char *) &rmask, (char *) &basemask, sizeof(fd_set)); + if ((nSelected = select(nSockets, &rmask, + (fd_set *) NULL, + (fd_set *) NULL, + (struct timeval *) NULL)) < 0) { + if (errno == EINTR) + continue; + fprintf(stderr, "%s: ServerLoop: select failed\n", + progname); + return(STATUS_ERROR); } - /* [TRH] - * To avoid race conditions, block SIGCHLD signals while we are - * handling the request. (both reaper() and ConnCreate() - * manipulate the BackEnd list, and reaper() calls free() which is - * usually non-reentrant.) - */ - sigprocmask(SIG_BLOCK, &newsigmask, &oldsigmask); -/* sigblock(sigmask(SIGCHLD)); */ /* XXX[TRH] portability */ - if (DebugLvl > 1) { - fprintf(stderr, "%s: ServerLoop: %d sockets pending\n", - progname, nSelected); - } - - /* new connection pending on our well-known port's socket */ - if (FD_ISSET(ServerSock, &rmask)) { - /* - * connect and make an addition to PortList. If - * the connection dies and we notice it, just forget - * about the whole thing. - */ - if (ConnCreate(serverFd, &newFd) == STATUS_OK) { - if (newFd >= nSockets) - nSockets = newFd + 1; - FD_SET(newFd, &rmask); - FD_SET(newFd, &basemask); - if (DebugLvl) - fprintf(stderr, "%s: ServerLoop: connect on %d\n", - progname, newFd); - } - --nSelected; - FD_CLR(ServerSock, &rmask); - } + /* [TRH] + * To avoid race conditions, block SIGCHLD signals while we are + * handling the request. (both reaper() and ConnCreate() + * manipulate the BackEnd list, and reaper() calls free() which is + * usually non-reentrant.) + */ + sigprocmask(SIG_BLOCK, &newsigmask, &oldsigmask); +/* sigblock(sigmask(SIGCHLD)); */ /* XXX[TRH] portability */ + if (DebugLvl > 1) { + fprintf(stderr, "%s: ServerLoop: %d sockets pending\n", + progname, nSelected); + } + + /* new connection pending on our well-known port's socket */ + if (FD_ISSET(ServerSock, &rmask)) { + /* + * connect and make an addition to PortList. If + * the connection dies and we notice it, just forget + * about the whole thing. + */ + if (ConnCreate(serverFd, &newFd) == STATUS_OK) { + if (newFd >= nSockets) + nSockets = newFd + 1; + FD_SET(newFd, &rmask); + FD_SET(newFd, &basemask); + if (DebugLvl) + fprintf(stderr, "%s: ServerLoop: connect on %d\n", + progname, newFd); + } + --nSelected; + FD_CLR(ServerSock, &rmask); + } - if (DebugLvl > 1) { - fprintf(stderr, "%s: ServerLoop:\tnSelected=%d\n", - progname, nSelected); - curr = DLGetHead(PortList); - while (curr) { - Port *port = DLE_VAL(curr); - - fprintf(stderr, "%s: ServerLoop:\t\tport %d%s pending\n", - progname, port->sock, - FD_ISSET(port->sock, &rmask) - ? "" : - " not"); - curr = DLGetSucc(curr); - } - } - - curr = DLGetHead(PortList); + if (DebugLvl > 1) { + fprintf(stderr, "%s: ServerLoop:\tnSelected=%d\n", + progname, nSelected); + curr = DLGetHead(PortList); + while (curr) { + Port *port = DLE_VAL(curr); + + fprintf(stderr, "%s: ServerLoop:\t\tport %d%s pending\n", + progname, port->sock, + FD_ISSET(port->sock, &rmask) + ? "" : + " not"); + curr = DLGetSucc(curr); + } + } + + curr = DLGetHead(PortList); - while (curr) { - Port *port = (Port*)DLE_VAL(curr); - int lastbytes = port->nBytes; - - if (FD_ISSET(port->sock, &rmask) && port->sock != newFd) { - if (DebugLvl > 1) - fprintf(stderr, "%s: ServerLoop:\t\thandling %d\n", - progname, port->sock); - --nSelected; - - /* - * Read the incoming packet into its packet buffer. - * Read the connection id out of the packet so we - * know who the packet is from. - */ - status = PacketReceive(port, &port->buf, NON_BLOCKING); - switch (status) { - case STATUS_OK: { + while (curr) { + Port *port = (Port*)DLE_VAL(curr); + int lastbytes = port->nBytes; + + if (FD_ISSET(port->sock, &rmask) && port->sock != newFd) { + if (DebugLvl > 1) + fprintf(stderr, "%s: ServerLoop:\t\thandling %d\n", + progname, port->sock); + --nSelected; + + /* + * Read the incoming packet into its packet buffer. + * Read the connection id out of the packet so we + * know who the packet is from. + */ + status = PacketReceive(port, &port->buf, NON_BLOCKING); + switch (status) { + case STATUS_OK: { int CSstatus; /* Completion status of ConnStartup */ char errormsg[200]; /* error msg from ConnStartup */ - ConnStartup(port, &CSstatus, errormsg, sizeof(errormsg)); + ConnStartup(port, &CSstatus, errormsg, sizeof(errormsg)); if (CSstatus == STATUS_ERROR) send_error_reply(port, errormsg); - ActiveBackends = TRUE; + ActiveBackends = TRUE; } - /*FALLTHROUGH*/ - case STATUS_INVALID: - if (DebugLvl) - fprintf(stderr, "%s: ServerLoop:\t\tdone with %d\n", - progname, port->sock); - break; + /*FALLTHROUGH*/ + case STATUS_INVALID: + if (DebugLvl) + fprintf(stderr, "%s: ServerLoop:\t\tdone with %d\n", + progname, port->sock); + break; case STATUS_BAD_PACKET: /* * This is a bogus client, kill the connection @@ -519,41 +573,41 @@ ServerLoop(void) if (DebugLvl) fprintf(stderr, "%s: ServerLoop:\t\tbad packet format (reported packet size of %d read on port %d\n", progname, port->nBytes, port->sock); break; - case STATUS_NOT_DONE: - if (DebugLvl) - fprintf(stderr, "%s: ServerLoop:\t\tpartial packet (%d bytes actually read) on %d\n", - progname, port->nBytes, port->sock); - /* - * If we've received at least a PacketHdr's worth of data - * and we're still receiving data each time we read, we're - * ok. If the client gives us less than a PacketHdr at - * the beginning, just kill the connection and forget - * about the whole thing. - */ - if (lastbytes < port->nBytes) { - if (DebugLvl) - fprintf(stderr, "%s: ServerLoop:\t\tpartial packet on %d ok\n", - progname, port->sock); - curr = DLGetSucc(curr); - continue; - } - break; - case STATUS_ERROR: /* system call error - die */ - fprintf(stderr, "%s: ServerLoop:\t\terror receiving packet\n", - progname); - return(STATUS_ERROR); - } - FD_CLR(port->sock, &basemask); - StreamClose(port->sock); - next = DLGetSucc(curr); - DLRemove(curr); - DLFreeElem(curr); - curr = next; + case STATUS_NOT_DONE: + if (DebugLvl) + fprintf(stderr, "%s: ServerLoop:\t\tpartial packet (%d bytes actually read) on %d\n", + progname, port->nBytes, port->sock); + /* + * If we've received at least a PacketHdr's worth of data + * and we're still receiving data each time we read, we're + * ok. If the client gives us less than a PacketHdr at + * the beginning, just kill the connection and forget + * about the whole thing. + */ + if (lastbytes < port->nBytes) { + if (DebugLvl) + fprintf(stderr, "%s: ServerLoop:\t\tpartial packet on %d ok\n", + progname, port->sock); + curr = DLGetSucc(curr); + continue; + } + break; + case STATUS_ERROR: /* system call error - die */ + fprintf(stderr, "%s: ServerLoop:\t\terror receiving packet\n", + progname); + return(STATUS_ERROR); + } + FD_CLR(port->sock, &basemask); + StreamClose(port->sock); + next = DLGetSucc(curr); + DLRemove(curr); + DLFreeElem(curr); + curr = next; continue; - } - curr = DLGetSucc(curr); - } - Assert(nSelected == 0); + } + curr = DLGetSucc(curr); + } + Assert(nSelected == 0); } } @@ -574,7 +628,7 @@ ConnStartup(Port *port, int *status, { MsgType msgType; char namebuf[NAMEDATALEN + 1]; - int pid; + int pid; PacketBuf *p; StartupInfo sp; char *tmp; @@ -708,23 +762,23 @@ send_error_reply(Port *port, const char *errormsg) static int ConnCreate(int serverFd, int *newFdP) { - int status; - Port *port; + int status; + Port *port; if (!(port = (Port *) calloc(1, sizeof(Port)))) { - fprintf(stderr, "%s: ConnCreate: malloc failed\n", - progname); - ExitPostmaster(1); + fprintf(stderr, "%s: ConnCreate: malloc failed\n", + progname); + ExitPostmaster(1); } if ((status = StreamConnection(serverFd, port)) != STATUS_OK) { - StreamClose(port->sock); - free(port); + StreamClose(port->sock); + free(port); } else { - DLAddHead(PortList, DLNewElem(port)); - *newFdP = port->sock; + DLAddHead(PortList, DLNewElem(port)); + *newFdP = port->sock; } return (status); @@ -736,7 +790,7 @@ ConnCreate(int serverFd, int *newFdP) static void reset_shared(short port) { - IPCKey key; + IPCKey key; key = SystemPortAddressCreateIPCKey((SystemPortAddress) port); CreateSharedMemoryAndSemaphores(key); @@ -758,15 +812,15 @@ pmdie(SIGNAL_ARGS) static void reaper(SIGNAL_ARGS) { - int status; /* backend exit status */ - int pid; /* process id of dead backend */ + int status; /* backend exit status */ + int pid; /* process id of dead backend */ if (DebugLvl) - fprintf(stderr, "%s: reaping dead processes...\n", - progname); + fprintf(stderr, "%s: reaping dead processes...\n", + progname); #ifndef WIN32 while((pid = waitpid(-1, &status, WNOHANG)) > 0) - CleanupProc(pid, status); + CleanupProc(pid, status); #endif /* WIN32 */ } @@ -779,15 +833,15 @@ reaper(SIGNAL_ARGS) */ static void CleanupProc(int pid, - int exitstatus) /* child's exit status. */ + int exitstatus) /* child's exit status. */ { Dlelem *prev, *curr; - Backend *bp; - int sig; + Backend *bp; + int sig; if (DebugLvl) { - fprintf(stderr, "%s: CleanupProc: pid %d exited with status %d\n", - progname, pid, exitstatus); + fprintf(stderr, "%s: CleanupProc: pid %d exited with status %d\n", + progname, pid, exitstatus); } /* * ------------------------- @@ -798,57 +852,57 @@ CleanupProc(int pid, * ------------------------- */ if (!exitstatus) { - curr = DLGetHead(BackendList); - while (curr) { - bp = (Backend*)DLE_VAL(curr); - if (bp->pid == pid) { - DLRemove(curr); - DLFreeElem(curr); - break; - } - curr = DLGetSucc(curr); - } + curr = DLGetHead(BackendList); + while (curr) { + bp = (Backend*)DLE_VAL(curr); + if (bp->pid == pid) { + DLRemove(curr); + DLFreeElem(curr); + break; + } + curr = DLGetSucc(curr); + } - ProcRemove(pid); + ProcRemove(pid); - return; + return; } curr = DLGetHead(BackendList); while (curr) { - bp = (Backend*)DLE_VAL(curr); - - /* - * ----------------- - * SIGUSR1 is the special signal that sez exit without exitpg - * and let the user know what's going on. ProcSemaphoreKill() - * cleans up the backends semaphore. If SendStop is set (-s on - * the command line), then we send a SIGSTOP so that we can - * collect core dumps from all backends by hand. - * ----------------- - */ + bp = (Backend*)DLE_VAL(curr); + + /* + * ----------------- + * SIGUSR1 is the special signal that sez exit without exitpg + * and let the user know what's going on. ProcSemaphoreKill() + * cleans up the backends semaphore. If SendStop is set (-s on + * the command line), then we send a SIGSTOP so that we can + * collect core dumps from all backends by hand. + * ----------------- + */ #ifndef WIN32 - sig = (SendStop) ? SIGSTOP : SIGUSR1; - if (bp->pid != pid) { - if (DebugLvl) - fprintf(stderr, "%s: CleanupProc: sending %s to process %d\n", - progname, - (sig == SIGUSR1) - ? "SIGUSR1" : "SIGSTOP", - bp->pid); - (void) kill(bp->pid, sig); - } + sig = (SendStop) ? SIGSTOP : SIGUSR1; + if (bp->pid != pid) { + if (DebugLvl) + fprintf(stderr, "%s: CleanupProc: sending %s to process %d\n", + progname, + (sig == SIGUSR1) + ? "SIGUSR1" : "SIGSTOP", + bp->pid); + (void) kill(bp->pid, sig); + } #endif /* WIN32 */ - ProcRemove(bp->pid); - - prev = DLGetPred(curr); - DLRemove(curr); - DLFreeElem(curr); - if (!prev) { /* removed head */ - curr = DLGetHead(BackendList); - continue; - } - curr = DLGetSucc(curr); + ProcRemove(bp->pid); + + prev = DLGetPred(curr); + DLRemove(curr); + DLFreeElem(curr); + if (!prev) { /* removed head */ + curr = DLGetHead(BackendList); + continue; + } + curr = DLGetSucc(curr); } /* * ------------- @@ -865,11 +919,11 @@ CleanupProc(int pid, * ---------------- */ if (ActiveBackends == TRUE && Reinit) { - if (DebugLvl) - fprintf(stderr, "%s: CleanupProc: reinitializing shared memory and semaphores\n", - progname); - quasi_exitpg(); - reset_shared(PostPortName); + if (DebugLvl) + fprintf(stderr, "%s: CleanupProc: reinitializing shared memory and semaphores\n", + progname); + quasi_exitpg(); + reset_shared(PostPortName); } } @@ -877,20 +931,20 @@ CleanupProc(int pid, * BackendStartup -- start backend process * * returns: STATUS_ERROR if the fork/exec failed, STATUS_OK - * otherwise. + * otherwise. * */ int BackendStartup(StartupInfo *packet, /* client's startup packet */ - Port *port, - int *pidPtr) + Port *port, + int *pidPtr) { Backend* bn; /* for backend cleanup */ - int pid, i; - static char envEntry[4][2 * ARGV_SIZE]; + int pid, i; + static char envEntry[4][2 * ARGV_SIZE]; for (i = 0; i < 4; ++i) { - memset(envEntry[i], 0, 2*ARGV_SIZE); + memset(envEntry[i], 0, 2*ARGV_SIZE); } /* * Set up the necessary environment variables for the backend @@ -903,50 +957,50 @@ BackendStartup(StartupInfo *packet, /* client's startup packet */ sprintf(envEntry[2], "PG_USER=%s", packet->user); putenv(envEntry[2]); if (!getenv("PGDATA")) { - sprintf(envEntry[3], "PGDATA=%s", DataDir); - putenv(envEntry[3]); + sprintf(envEntry[3], "PGDATA=%s", DataDir); + putenv(envEntry[3]); } if (DebugLvl > 2) { - char **p; - extern char **environ; - - fprintf(stderr, "%s: BackendStartup: environ dump:\n", - progname); - fprintf(stderr, "-----------------------------------------\n"); - for (p = environ; *p; ++p) - fprintf(stderr, "\t%s\n", *p); - fprintf(stderr, "-----------------------------------------\n"); + char **p; + extern char **environ; + + fprintf(stderr, "%s: BackendStartup: environ dump:\n", + progname); + fprintf(stderr, "-----------------------------------------\n"); + for (p = environ; *p; ++p) + fprintf(stderr, "\t%s\n", *p); + fprintf(stderr, "-----------------------------------------\n"); } #ifndef WIN32 - if ((pid = FORK()) == 0) { /* child */ - if (DoExec(packet, port->sock)) - fprintf(stderr, "%s child[%d]: BackendStartup: execv failed\n", - progname, pid); - /* use _exit to keep from double-flushing stdio */ - _exit(1); + if ((pid = FORK()) == 0) { /* child */ + if (DoExec(packet, port->sock)) + fprintf(stderr, "%s child[%d]: BackendStartup: execv failed\n", + progname, pid); + /* use _exit to keep from double-flushing stdio */ + _exit(1); } /* in parent */ if (pid < 0) { - fprintf(stderr, "%s: BackendStartup: fork failed\n", - progname); - return(STATUS_ERROR); + fprintf(stderr, "%s: BackendStartup: fork failed\n", + progname); + return(STATUS_ERROR); } #else pid = DoExec(packet, port->sock); if (pid == FALSE) { - fprintf(stderr, "%s: BackendStartup: CreateProcess failed\n", - progname); - return(STATUS_ERROR); + fprintf(stderr, "%s: BackendStartup: CreateProcess failed\n", + progname); + return(STATUS_ERROR); } #endif /* WIN32 */ if (DebugLvl) - fprintf(stderr, "%s: BackendStartup: pid %d user %s db %s socket %d\n", - progname, pid, packet->user, - (packet->database[0] == '\0' ? packet->user : packet->database), - port->sock); + fprintf(stderr, "%s: BackendStartup: pid %d user %s db %s socket %d\n", + progname, pid, packet->user, + (packet->database[0] == '\0' ? packet->user : packet->database), + port->sock); /* adjust backend counter */ /* XXX Don't know why this is done, but for now backend needs it */ @@ -957,16 +1011,16 @@ BackendStartup(StartupInfo *packet, /* client's startup packet */ * list of backends. */ if (!(bn = (Backend *) calloc(1, sizeof (Backend)))) { - fprintf(stderr, "%s: BackendStartup: malloc failed\n", - progname); - ExitPostmaster(1); + fprintf(stderr, "%s: BackendStartup: malloc failed\n", + progname); + ExitPostmaster(1); } bn->pid = pid; DLAddHead(BackendList,DLNewElem(bn)); if (MultiplexedBackends) - MultiplexedBackendPort++; + MultiplexedBackendPort++; *pidPtr = pid; @@ -986,17 +1040,17 @@ BackendStartup(StartupInfo *packet, /* client's startup packet */ static void split_opts(char **argv, int *argcp, char *s) { - int i = *argcp; + int i = *argcp; while (s && *s) { - while (isspace(*s)) - ++s; - if (*s) - argv[i++] = s; - while (*s && !isspace(*s)) - ++s; - if (isspace(*s)) - *s++ = '\0'; + while (isspace(*s)) + ++s; + if (*s) + argv[i++] = s; + while (*s && !isspace(*s)) + ++s; + if (isspace(*s)) + *s++ = '\0'; } *argcp = i; } @@ -1010,26 +1064,26 @@ split_opts(char **argv, int *argcp, char *s) * fork() because we don't have vfork(), then we don't really care.) * * returns: - * Shouldn't return at all. - * If execv() fails, return status. + * Shouldn't return at all. + * If execv() fails, return status. */ static int DoExec(StartupInfo *packet, int portFd) { - char execbuf[MAXPATHLEN]; - char portbuf[ARGV_SIZE]; + char execbuf[MAXPATHLEN]; + char portbuf[ARGV_SIZE]; char mbbuf[ARGV_SIZE]; - char debugbuf[ARGV_SIZE]; - char ttybuf[ARGV_SIZE + 1]; - char argbuf[(2 * ARGV_SIZE) + 1]; + char debugbuf[ARGV_SIZE]; + char ttybuf[ARGV_SIZE + 1]; + char argbuf[(2 * ARGV_SIZE) + 1]; /* * each argument takes at least three chars, so we can't * have more than ARGV_SIZE arguments in (2 * ARGV_SIZE) * chars (i.e., packet->options plus ExtraOptions)... */ - char *av[ARGV_SIZE]; - char dbbuf[ARGV_SIZE + 1]; - int ac = 0; + char *av[ARGV_SIZE]; + char dbbuf[ARGV_SIZE + 1]; + int ac = 0; int i; #if defined(WIN32) char win32_args[(2 * ARGV_SIZE) + 1]; @@ -1054,16 +1108,16 @@ DoExec(StartupInfo *packet, int portFd) */ if (DebugLvl > 1) { - (void) sprintf(debugbuf, "-d%d", DebugLvl - 1); - av[ac++] = debugbuf; + (void) sprintf(debugbuf, "-d%d", DebugLvl - 1); + av[ac++] = debugbuf; } else - av[ac++] = "-Q"; + av[ac++] = "-Q"; /* Pass the requested debugging output file */ if (packet->tty[0]) { - (void) strncpy(ttybuf, packet->tty, ARGV_SIZE); - av[ac++] = "-o"; + (void) strncpy(ttybuf, packet->tty, ARGV_SIZE); + av[ac++] = "-o"; #if defined(WIN32) /* BIG HACK - The front end is passing "/dev/null" here which ** causes new backends to fail. So, as a very special case, @@ -1092,20 +1146,20 @@ DoExec(StartupInfo *packet, int portFd) split_opts(av, &ac, argbuf); if (packet->database[0]) - (void) strncpy(dbbuf, packet->database, ARGV_SIZE); + (void) strncpy(dbbuf, packet->database, ARGV_SIZE); else - (void) strncpy(dbbuf, packet->user, NAMEDATALEN); + (void) strncpy(dbbuf, packet->user, NAMEDATALEN); dbbuf[ARGV_SIZE] = '\0'; av[ac++] = dbbuf; av[ac] = (char *) NULL; if (DebugLvl > 1) { - fprintf(stderr, "%s child[%ld]: execv(", - progname, (long)getpid()); - for (i = 0; i < ac; ++i) - fprintf(stderr, "%s, ", av[i]); - fprintf(stderr, ")\n"); + fprintf(stderr, "%s child[%ld]: execv(", + progname, (long)getpid()); + for (i = 0; i < ac; ++i) + fprintf(stderr, "%s, ", av[i]); + fprintf(stderr, ")\n"); } #ifndef WIN32 @@ -1156,7 +1210,7 @@ ExitPostmaster(int status) * should the backends all be killed? probably not. */ if (ServerSock != INVALID_SOCK) - close(ServerSock); + close(ServerSock); exitpg(status); } @@ -1166,50 +1220,17 @@ dumpstatus(SIGNAL_ARGS) Dlelem *curr = DLGetHead(PortList); while (curr) { - Port *port = DLE_VAL(curr); - - fprintf(stderr, "%s: dumpstatus:\n", progname); - fprintf(stderr, "\tsock %d: nBytes=%d, laddr=0x%lx, raddr=0x%lx\n", - port->sock, port->nBytes, - (long int) port->laddr.sin_addr.s_addr, - (long int) port->raddr.sin_addr.s_addr); - curr = DLGetSucc(curr); + Port *port = DLE_VAL(curr); + + fprintf(stderr, "%s: dumpstatus:\n", progname); + fprintf(stderr, "\tsock %d: nBytes=%d, laddr=0x%lx, raddr=0x%lx\n", + port->sock, port->nBytes, + (long int) port->laddr.sin_addr.s_addr, + (long int) port->raddr.sin_addr.s_addr); + curr = DLGetSucc(curr); } } -static void -checkDataDir(void) -{ - char path[MAXPATHLEN]; - FILE *fp; - - sprintf(path, "%s%cbase%ctemplate1%cpg_class", DataDir, SEP_CHAR, SEP_CHAR, - SEP_CHAR); - if ((fp=fopen(path, "r")) == NULL) { - fprintf(stderr, "%s does not find the database. Expected to find it " - "in the PGDATA directory \"%s\", but unable to open file " - "with pathname \"%s\".\n", - progname, DataDir, path); - exit(2); - } - fclose(fp); - -#ifndef WIN32 - { - char *reason; /* reason ValidatePgVersion failed. NULL if didn't */ - ValidatePgVersion(DataDir, &reason); - if (reason) { - fprintf(stderr, - "Database system in directory %s " - "is not compatible with this version of " - "Postgres, or we are unable to read the PG_VERSION file. " - "Explanation from ValidatePgVersion: %s\n", - DataDir, reason); - free(reason); - exit(2); - } - } -#endif /* WIN32 */ -} + diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 85de467d57..4c38e663f6 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.18 1996/11/11 04:54:51 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.19 1996/11/14 10:24:07 bryanh Exp $ * * NOTES * this is the "main" module of the postgres backend and @@ -15,7 +15,7 @@ * *------------------------------------------------------------------------- */ -#include "libpq/pqsignal.h" /* substitute for */ +#include "libpq/pqsignal.h" /* substitute for */ #if defined(linux) #ifndef __USE_POSIX @@ -31,9 +31,9 @@ #include #include #include -#include /* for MAXHOSTNAMELEN on most */ +#include /* for MAXHOSTNAMELEN on most */ #ifndef MAXHOSTNAMELEN -#include /* for MAXHOSTNAMELEN on some */ +#include /* for MAXHOSTNAMELEN on some */ #endif #include #ifdef aix @@ -49,9 +49,9 @@ #include "lib/dllist.h" #include "parser/catalog_utils.h" -#include "parser/parse_query.h" /* for MakeTimeRange() */ +#include "parser/parse_query.h" /* for MakeTimeRange() */ #include "commands/async.h" -#include "tcop/tcopprot.h" /* where declarations for this file go */ +#include "tcop/tcopprot.h" /* where declarations for this file go */ #include "optimizer/planner.h" #include "tcop/tcopprot.h" @@ -86,26 +86,26 @@ #include "rewrite/rewriteHandler.h" /* for QueryRewrite() */ /* ---------------- - * global variables + * global variables * ---------------- */ -static bool DebugPrintPlan = false; -static bool DebugPrintParse = false; -static bool DebugPrintRewrittenParsetree = false; -/*static bool EnableRewrite = true; , never changes why have it*/ +static bool DebugPrintPlan = false; +static bool DebugPrintParse = false; +static bool DebugPrintRewrittenParsetree = false; +/*static bool EnableRewrite = true; , never changes why have it*/ CommandDest whereToSendOutput; -extern int lockingOff; -extern int NBuffers; +extern int lockingOff; +extern int NBuffers; -int fsyncOff = 0; +int fsyncOff = 0; -int dontExecute = 0; -static int ShowStats; -static bool IsEmptyQuery = false; +int dontExecute = 0; +static int ShowStats; +static bool IsEmptyQuery = false; -Relation reldesc; /* current relation descritor */ -char relname[80]; /* current relation name */ +Relation reldesc; /* current relation descritor */ +char relname[80]; /* current relation name */ #if defined(WIN32) || defined(next) jmp_buf Warn_restart; @@ -116,15 +116,15 @@ sigjmp_buf Warn_restart; #endif /*defined(WIN32) || defined(next) */ int InWarn; -extern int NBuffers; +extern int NBuffers; -static int EchoQuery = 0; /* default don't echo */ -time_t tim; -char pg_pathname[256]; -static int ShowParserStats; -static int ShowPlannerStats; -int ShowExecutorStats; -FILE *StatFp; +static int EchoQuery = 0; /* default don't echo */ +time_t tim; +char pg_pathname[256]; +static int ShowParserStats; +static int ShowPlannerStats; +int ShowExecutorStats; +FILE *StatFp; typedef struct frontend { bool fn_connected; @@ -137,8 +137,8 @@ typedef struct frontend { static Dllist* frontendList; /* ---------------- - * people who want to use EOF should #define DONTUSENEWLINE in - * tcop/tcopdebug.h + * people who want to use EOF should #define DONTUSENEWLINE in + * tcop/tcopdebug.h * ---------------- */ #ifndef TCOP_DONTUSENEWLINE @@ -148,8 +148,8 @@ int UseNewLine = 0; /* Use EOF as query delimiters */ #endif /* TCOP_DONTUSENEWLINE */ /* ---------------- - * bushy tree plan flag: if true planner will generate bushy-tree - * plans + * bushy tree plan flag: if true planner will generate bushy-tree + * plans * ---------------- */ int BushyPlanFlag = 0; /* default to false -- consider only left-deep trees */ @@ -162,27 +162,27 @@ int XfuncMode = 0; /* * ---------------- * Note: _exec_repeat_ defaults to 1 but may be changed - * by a DEBUG command. If you set this to a large - * number N, run a single query, and then set it - * back to 1 and run N queries, you can get an idea - * of how much time is being spent in the parser and - * planner b/c in the first case this overhead only - * happens once. -cim 6/9/91 + * by a DEBUG command. If you set this to a large + * number N, run a single query, and then set it + * back to 1 and run N queries, you can get an idea + * of how much time is being spent in the parser and + * planner b/c in the first case this overhead only + * happens once. -cim 6/9/91 * ---------------- */ int _exec_repeat_ = 1; /* ---------------------------------------------------------------- - * decls for routines only used in this file + * decls for routines only used in this file * ---------------------------------------------------------------- */ static char InteractiveBackend(char *inBuf); -static char SocketBackend(char *inBuf, int multiplexedBackend); -static char ReadCommand(char *inBuf, int multiplexedBackend); +static char SocketBackend(char *inBuf, bool multiplexedBackend); +static char ReadCommand(char *inBuf, bool multiplexedBackend); /* ---------------------------------------------------------------- - * routines to obtain user input + * routines to obtain user input * ---------------------------------------------------------------- */ @@ -195,82 +195,82 @@ static char ReadCommand(char *inBuf, int multiplexedBackend); static char InteractiveBackend(char *inBuf) { - char *stuff = inBuf; /* current place in input buffer */ - int c; /* character read from getc() */ - bool end = false; /* end-of-input flag */ - bool backslashSeen = false; /* have we seen a \ ? */ + char *stuff = inBuf; /* current place in input buffer */ + int c; /* character read from getc() */ + bool end = false; /* end-of-input flag */ + bool backslashSeen = false; /* have we seen a \ ? */ /* ---------------- - * display a prompt and obtain input from the user + * display a prompt and obtain input from the user * ---------------- */ printf("> "); for (;;) { - if (UseNewLine) { - /* ---------------- - * if we are using \n as a delimiter, then read - * characters until the \n. - * ---------------- - */ - while ( (c = getc(stdin)) != EOF) { - if (c == '\n') { - if (backslashSeen) { - stuff--; - continue; - } else { - /* keep the newline character */ - *stuff++ = '\n'; - *stuff++ = '\0'; - break; - } - } else if (c == '\\') - backslashSeen = true; - else - backslashSeen = false; - - *stuff++ = (char)c; - } - - if (c == EOF) - end = true; - } else { - /* ---------------- - * otherwise read characters until EOF. - * ---------------- - */ - while ( (c = getc(stdin)) != EOF ) - *stuff++ = (char)c; - - if ( stuff == inBuf ) - end = true; - } - - if (end) { - if (!Quiet) puts("EOF"); - IsEmptyQuery = true; - exitpg(0); - } - - /* ---------------- - * otherwise we have a user query so process it. - * ---------------- - */ - break; + if (UseNewLine) { + /* ---------------- + * if we are using \n as a delimiter, then read + * characters until the \n. + * ---------------- + */ + while ( (c = getc(stdin)) != EOF) { + if (c == '\n') { + if (backslashSeen) { + stuff--; + continue; + } else { + /* keep the newline character */ + *stuff++ = '\n'; + *stuff++ = '\0'; + break; + } + } else if (c == '\\') + backslashSeen = true; + else + backslashSeen = false; + + *stuff++ = (char)c; + } + + if (c == EOF) + end = true; + } else { + /* ---------------- + * otherwise read characters until EOF. + * ---------------- + */ + while ( (c = getc(stdin)) != EOF ) + *stuff++ = (char)c; + + if ( stuff == inBuf ) + end = true; + } + + if (end) { + if (!Quiet) puts("EOF"); + IsEmptyQuery = true; + exitpg(0); + } + + /* ---------------- + * otherwise we have a user query so process it. + * ---------------- + */ + break; } /* ---------------- - * if the query echo flag was given, print the query.. + * if the query echo flag was given, print the query.. * ---------------- */ if (EchoQuery) - printf("query is: %s\n", inBuf); + printf("query is: %s\n", inBuf); return('Q'); } /* ---------------- - * SocketBackend() Is called for frontend-backend connections + * SocketBackend() Is called for frontend-backend connections * * If the input is a query (case 'Q') then the string entered by * the user is placed in its parameter inBuf. @@ -282,91 +282,91 @@ InteractiveBackend(char *inBuf) */ static char -SocketBackend(char *inBuf, int multiplexedBackend) +SocketBackend(char *inBuf, bool multiplexedBackend) { char qtype[2]; char result = '\0'; /* ---------------- - * get input from the frontend + * get input from the frontend * ---------------- */ (void) strcpy(qtype, "?"); if (pq_getnchar(qtype,0,1) == EOF) { - /* ------------ - * when front-end applications quits/dies - * ------------ - */ - if (multiplexedBackend) { - return 'X'; - } - else - exitpg(0); + /* ------------ + * when front-end applications quits/dies + * ------------ + */ + if (multiplexedBackend) { + return 'X'; + } + else + exitpg(0); } switch(*qtype) { - /* ---------------- - * 'Q': user entered a query - * ---------------- - */ + /* ---------------- + * 'Q': user entered a query + * ---------------- + */ case 'Q': - pq_getstr(inBuf, MAX_PARSE_BUFFER); - result = 'Q'; - break; - - /* ---------------- - * 'F': calling user/system functions - * ---------------- - */ - case 'F': - pq_getstr(inBuf, MAX_PARSE_BUFFER);/* ignore the rest of the line */ + pq_getstr(inBuf, MAX_PARSE_BUFFER); + result = 'Q'; + break; + + /* ---------------- + * 'F': calling user/system functions + * ---------------- + */ + case 'F': + pq_getstr(inBuf, MAX_PARSE_BUFFER);/* ignore the rest of the line */ result = 'F'; break; - - /* ---------------- - * 'X': frontend is exiting - * ---------------- - */ + + /* ---------------- + * 'X': frontend is exiting + * ---------------- + */ case 'X': - result = 'X'; - break; - - /* ---------------- - * otherwise we got garbage from the frontend. - * - * XXX are we certain that we want to do an elog(FATAL) here? - * -cim 1/24/90 - * ---------------- - */ + result = 'X'; + break; + + /* ---------------- + * otherwise we got garbage from the frontend. + * + * XXX are we certain that we want to do an elog(FATAL) here? + * -cim 1/24/90 + * ---------------- + */ default: - elog(FATAL, "Socket command type %c unknown\n", *qtype); - break; + elog(FATAL, "Socket command type %c unknown\n", *qtype); + break; } return result; } /* ---------------- - * ReadCommand reads a command from either the frontend or - * standard input, places it in inBuf, and returns a char - * representing whether the string is a 'Q'uery or a 'F'astpath - * call. + * ReadCommand reads a command from either the frontend or + * standard input, places it in inBuf, and returns a char + * representing whether the string is a 'Q'uery or a 'F'astpath + * call. * ---------------- */ static char -ReadCommand(char *inBuf, int multiplexedBackend) +ReadCommand(char *inBuf, bool multiplexedBackend) { if (IsUnderPostmaster || multiplexedBackend) - return SocketBackend(inBuf, multiplexedBackend); + return SocketBackend(inBuf, multiplexedBackend); else - return InteractiveBackend(inBuf); + return InteractiveBackend(inBuf); } List * -pg_plan(char *query_string, /* string to execute */ - Oid *typev, /* argument types */ - int nargs, /* number of arguments */ - QueryTreeList **queryListP, /* pointer to the parse trees */ - CommandDest dest) /* where results should go */ +pg_plan(char *query_string, /* string to execute */ + Oid *typev, /* argument types */ + int nargs, /* number of arguments */ + QueryTreeList **queryListP, /* pointer to the parse trees */ + CommandDest dest) /* where results should go */ { QueryTreeList *querytree_list; int i; @@ -378,17 +378,17 @@ pg_plan(char *query_string, /* string to execute */ Query* querytree; /* ---------------- - * (1) parse the request string into a list of parse trees + * (1) parse the request string into a list of parse trees * ---------------- */ if (ShowParserStats) - ResetUsage(); + ResetUsage(); querytree_list = parser(query_string, typev, nargs); if (ShowParserStats) { - fprintf(stderr, "! Parser Stats:\n"); - ShowUsage(); + fprintf(stderr, "! Parser Stats:\n"); + ShowUsage(); } /* new_list holds the rewritten queries */ @@ -397,46 +397,46 @@ pg_plan(char *query_string, /* string to execute */ new_list->qtrees = (Query**)malloc(new_list->len * sizeof(Query*)); /* ---------------- - * (2) rewrite the queries, as necessary + * (2) rewrite the queries, as necessary * ---------------- */ j = 0; /* counter for the new_list, new_list can be longer than - old list as a result of rewrites */ + old list as a result of rewrites */ for (i=0;ilen;i++) { querytree = querytree_list->qtrees[i]; - + - /* don't rewrite utilites */ - if (querytree->commandType == CMD_UTILITY) { - new_list->qtrees[j++] = querytree; - continue; - } - - if ( DebugPrintParse == true ) { - printf("\ninput string is \"%s\"\n",query_string); - printf("\n---- \tparser outputs :\n"); - nodeDisplay(querytree); - printf("\n"); - } - - /* rewrite queries (retrieve, append, delete, replace) */ - rewritten = QueryRewrite(querytree); - if (rewritten != NULL) { - int len, k; - len = length(rewritten); - if (len == 1) - new_list->qtrees[j++] = (Query*)lfirst(rewritten); - else { - /* rewritten queries are longer than original query */ - /* grow the new_list to accommodate */ - new_list->len += len - 1; /* - 1 because originally we - allocated one space for the query */ - new_list->qtrees = realloc(new_list->qtrees, - new_list->len * sizeof(Query*)); - for (k=0;kqtrees[j++] = (Query*)nth(k, rewritten); - } - } + /* don't rewrite utilites */ + if (querytree->commandType == CMD_UTILITY) { + new_list->qtrees[j++] = querytree; + continue; + } + + if ( DebugPrintParse == true ) { + printf("\ninput string is \"%s\"\n",query_string); + printf("\n---- \tparser outputs :\n"); + nodeDisplay(querytree); + printf("\n"); + } + + /* rewrite queries (retrieve, append, delete, replace) */ + rewritten = QueryRewrite(querytree); + if (rewritten != NULL) { + int len, k; + len = length(rewritten); + if (len == 1) + new_list->qtrees[j++] = (Query*)lfirst(rewritten); + else { + /* rewritten queries are longer than original query */ + /* grow the new_list to accommodate */ + new_list->len += len - 1; /* - 1 because originally we + allocated one space for the query */ + new_list->qtrees = realloc(new_list->qtrees, + new_list->len * sizeof(Query*)); + for (k=0;kqtrees[j++] = (Query*)nth(k, rewritten); + } + } } /* we're done with the original lists, free it */ @@ -455,83 +455,83 @@ pg_plan(char *query_string, /* string to execute */ * ---------------- */ for (i=0;ilen;i++) { - List *l; - List *rt = NULL; + List *l; + List *rt = NULL; - querytree = querytree_list->qtrees[i]; + querytree = querytree_list->qtrees[i]; - /* ---------------- - * utilities don't have time ranges - * ---------------- - */ - if (querytree->commandType == CMD_UTILITY) - continue; - - rt = querytree->rtable; - - foreach (l, rt) { - RangeTblEntry *rte = lfirst(l); - TimeRange *timequal = rte->timeRange; + /* ---------------- + * utilities don't have time ranges + * ---------------- + */ + if (querytree->commandType == CMD_UTILITY) + continue; + + rt = querytree->rtable; + + foreach (l, rt) { + RangeTblEntry *rte = lfirst(l); + TimeRange *timequal = rte->timeRange; - if (timequal) { - int timecode = (rte->timeRange->endDate == NULL)? 0 : 1; + if (timequal) { + int timecode = (rte->timeRange->endDate == NULL)? 0 : 1; - rte->timeQual = makeTimeRange(rte->timeRange->startDate, - rte->timeRange->endDate, - timecode); - }else { - rte->timeQual = NULL; - } - } - - /* check for archived relations */ - plan_archive(rt); + rte->timeQual = makeTimeRange(rte->timeRange->startDate, + rte->timeRange->endDate, + timecode); + }else { + rte->timeQual = NULL; + } + } + + /* check for archived relations */ + plan_archive(rt); } if (DebugPrintRewrittenParsetree == true) { - printf("\n=================\n"); - printf(" After Rewriting\n"); - printf("=================\n"); + printf("\n=================\n"); + printf(" After Rewriting\n"); + printf("=================\n"); - for (i=0; ilen; i++) { - print(querytree_list->qtrees[i]); - printf("\n"); - } + for (i=0; ilen; i++) { + print(querytree_list->qtrees[i]); + printf("\n"); + } } for (i=0; ilen;i++) { querytree = querytree_list->qtrees[i]; - - /* - * For each query that isn't a utility invocation, - * generate a plan. - */ - - if (querytree->commandType != CMD_UTILITY) { - - if (IsAbortedTransactionBlockState()) { - /* ---------------- - * the EndCommand() stuff is to tell the frontend - * that the command ended. -cim 6/1/90 - * ---------------- - */ - char *tag = "*ABORT STATE*"; - EndCommand(tag, dest); - - elog(NOTICE, "(transaction aborted): %s", - "queries ignored until END"); - - *queryListP = (QueryTreeList*)NULL; - return (List*)NULL; - } - - if (ShowPlannerStats) ResetUsage(); - plan = planner(querytree); - if (ShowPlannerStats) { - fprintf(stderr, "! Planner Stats:\n"); - ShowUsage(); - } - plan_list = lappend(plan_list, plan); + + /* + * For each query that isn't a utility invocation, + * generate a plan. + */ + + if (querytree->commandType != CMD_UTILITY) { + + if (IsAbortedTransactionBlockState()) { + /* ---------------- + * the EndCommand() stuff is to tell the frontend + * that the command ended. -cim 6/1/90 + * ---------------- + */ + char *tag = "*ABORT STATE*"; + EndCommand(tag, dest); + + elog(NOTICE, "(transaction aborted): %s", + "queries ignored until END"); + + *queryListP = (QueryTreeList*)NULL; + return (List*)NULL; + } + + if (ShowPlannerStats) ResetUsage(); + plan = planner(querytree); + if (ShowPlannerStats) { + fprintf(stderr, "! Planner Stats:\n"); + ShowUsage(); + } + plan_list = lappend(plan_list, plan); #ifdef INDEXSCAN_PATCH /* ---------------- * Print plan if debugging. @@ -539,44 +539,44 @@ pg_plan(char *query_string, /* string to execute */ * also for queries in functions. DZ - 27-8-1996 * ---------------- */ - if ( DebugPrintPlan == true ) { - printf("\nPlan is :\n"); - nodeDisplay(plan); - printf("\n"); - } + if ( DebugPrintPlan == true ) { + printf("\nPlan is :\n"); + nodeDisplay(plan); + printf("\n"); + } #endif - } + } #ifdef FUNC_UTIL_PATCH - /* - * If the command is an utility append a null plan. This is - * needed to keep the plan_list aligned with the querytree_list - * or the function executor will crash. DZ - 30-8-1996 - */ - else { - plan_list = lappend(plan_list, NULL); - } + /* + * If the command is an utility append a null plan. This is + * needed to keep the plan_list aligned with the querytree_list + * or the function executor will crash. DZ - 30-8-1996 + */ + else { + plan_list = lappend(plan_list, NULL); + } #endif } if (queryListP) - *queryListP = querytree_list; + *queryListP = querytree_list; return (plan_list); } /* ---------------------------------------------------------------- - * pg_eval() - * - * Takes a querystring, runs the parser/utilities or - * parser/planner/executor over it as necessary - * Begin Transaction Should have been called before this - * and CommitTransaction After this is called - * This is strictly because we do not allow for nested xactions. + * pg_eval() + * + * Takes a querystring, runs the parser/utilities or + * parser/planner/executor over it as necessary + * Begin Transaction Should have been called before this + * and CommitTransaction After this is called + * This is strictly because we do not allow for nested xactions. * - * NON-OBVIOUS-RESTRICTIONS - * this function _MUST_ allocate a new "parsetree" each time, - * since it may be stored in a named portal and should not - * change its value. + * NON-OBVIOUS-RESTRICTIONS + * this function _MUST_ allocate a new "parsetree" each time, + * since it may be stored in a named portal and should not + * change its value. * * ---------------------------------------------------------------- */ @@ -589,10 +589,10 @@ pg_eval(char *query_string, char **argv, Oid *typev, int nargs) void pg_eval_dest(char *query_string, /* string to execute */ - char **argv, /* arguments */ - Oid *typev, /* argument types */ - int nargs, /* number of arguments */ - CommandDest dest) /* where results should go */ + char **argv, /* arguments */ + Oid *typev, /* argument types */ + int nargs, /* number of arguments */ + CommandDest dest) /* where results should go */ { List *plan_list; Plan *plan; @@ -605,87 +605,87 @@ pg_eval_dest(char *query_string, /* string to execute */ /* pg_plan could have failed */ if (querytree_list == NULL) - return; + return; for (i=0;ilen;i++) { - querytree = querytree_list->qtrees[i]; - + querytree = querytree_list->qtrees[i]; + #ifdef FUNC_UTIL_PATCH - /* - * Advance on the plan_list in every case. Now the plan_list - * has the same length of the querytree_list. DZ - 30-8-1996 - */ - plan = (Plan *) lfirst(plan_list); - plan_list = lnext(plan_list); + /* + * Advance on the plan_list in every case. Now the plan_list + * has the same length of the querytree_list. DZ - 30-8-1996 + */ + plan = (Plan *) lfirst(plan_list); + plan_list = lnext(plan_list); #endif - if (querytree->commandType == CMD_UTILITY) { - /* ---------------- - * process utility functions (create, destroy, etc..) - * - * Note: we do not check for the transaction aborted state - * because that is done in ProcessUtility. - * ---------------- - */ - if (! Quiet) { - time(&tim); - printf("\tProcessUtility() at %s\n", ctime(&tim)); - } - - ProcessUtility(querytree->utilityStmt, dest); - - } else { + if (querytree->commandType == CMD_UTILITY) { + /* ---------------- + * process utility functions (create, destroy, etc..) + * + * Note: we do not check for the transaction aborted state + * because that is done in ProcessUtility. + * ---------------- + */ + if (! Quiet) { + time(&tim); + printf("\tProcessUtility() at %s\n", ctime(&tim)); + } + + ProcessUtility(querytree->utilityStmt, dest); + + } else { #ifndef FUNC_UTIL_PATCH - /* - * Moved before the if. DZ - 30-8-1996 - */ - plan = (Plan *) lfirst(plan_list); - plan_list = lnext(plan_list); + /* + * Moved before the if. DZ - 30-8-1996 + */ + plan = (Plan *) lfirst(plan_list); + plan_list = lnext(plan_list); #endif - + #ifdef INDEXSCAN_PATCH - /* - * Print moved in pg_plan. DZ - 27-8-1996 - */ + /* + * Print moved in pg_plan. DZ - 27-8-1996 + */ #else - /* ---------------- - * print plan if debugging - * ---------------- - */ - if ( DebugPrintPlan == true ) { - printf("\nPlan is :\n"); - nodeDisplay(plan); - printf("\n"); - } + /* ---------------- + * print plan if debugging + * ---------------- + */ + if ( DebugPrintPlan == true ) { + printf("\nPlan is :\n"); + nodeDisplay(plan); + printf("\n"); + } #endif - - /* ---------------- - * execute the plan - * - */ - if (ShowExecutorStats) - ResetUsage(); - - for (j = 0; j < _exec_repeat_; j++) { - if (! Quiet) { - time(&tim); - printf("\tProcessQuery() at %s\n", ctime(&tim)); - } - ProcessQuery(querytree, plan, argv, typev, nargs, dest); - } - - if (ShowExecutorStats) { - fprintf(stderr, "! Executor Stats:\n"); - ShowUsage(); - } - } - /* - * In a query block, we want to increment the command counter - * between queries so that the effects of early queries are - * visible to subsequent ones. - */ - - if (querytree_list) - CommandCounterIncrement(); + + /* ---------------- + * execute the plan + * + */ + if (ShowExecutorStats) + ResetUsage(); + + for (j = 0; j < _exec_repeat_; j++) { + if (! Quiet) { + time(&tim); + printf("\tProcessQuery() at %s\n", ctime(&tim)); + } + ProcessQuery(querytree, plan, argv, typev, nargs, dest); + } + + if (ShowExecutorStats) { + fprintf(stderr, "! Executor Stats:\n"); + ShowUsage(); + } + } + /* + * In a query block, we want to increment the command counter + * between queries so that the effects of early queries are + * visible to subsequent ones. + */ + + if (querytree_list) + CommandCounterIncrement(); } free(querytree_list->qtrees); @@ -693,15 +693,15 @@ pg_eval_dest(char *query_string, /* string to execute */ } /* -------------------------------- - * signal handler routines used in PostgresMain() + * signal handler routines used in PostgresMain() * - * handle_warn() is used to catch kill(getpid(),1) which - * occurs when elog(WARN) is called. + * handle_warn() is used to catch kill(getpid(),1) which + * occurs when elog(WARN) is called. * * quickdie() occurs when signalled by the postmaster, some backend * has bought the farm we need to stop what we're doing and exit. * - * die() preforms an orderly cleanup via ExitPostgres() + * die() preforms an orderly cleanup via ExitPostgres() * -------------------------------- */ @@ -747,8 +747,8 @@ her exceeded legal ranges or was a divide by zero"); static void usage(char* progname) { fprintf(stderr, - "Usage: %s [-B nbufs] [-d lvl] ] [-f plantype] \t[-m portno] [\t -o filename]\n", - progname); + "Usage: %s [-B nbufs] [-d lvl] ] [-f plantype] \t[-m portno] [\t -o filename]\n", + progname); fprintf(stderr,"\t[-P portno] [-t tracetype] [-x opttype] [-bCEiLFNopQSs] [dbname]\n"); fprintf(stderr, " b: consider bushy plan trees during optimization\n"); fprintf(stderr, " B: set number of buffers in buffer pool\n"); @@ -774,8 +774,8 @@ static void usage(char* progname) } /* ---------------------------------------------------------------- - * PostgresMain - * postgres main loop + * PostgresMain + * postgres main loop * all backends, interactive or otherwise start here * ---------------------------------------------------------------- */ @@ -783,10 +783,10 @@ int PostgresMain(int argc, char *argv[]) { int flagC; - int flagQ; - int flagS; - int flagE; - int flag; + int flagQ; + int flagS; + int flagE; + int flag; char *DBName = NULL; int errs = 0; @@ -795,7 +795,7 @@ PostgresMain(int argc, char *argv[]) char parser_input[MAX_PARSE_BUFFER]; char *userName; - int multiplexedBackend = 0; + bool multiplexedBackend; char* hostName; /* the host name of the backend server */ char hostbuf[MAXHOSTNAMELEN]; int serverSock; @@ -814,12 +814,12 @@ PostgresMain(int argc, char *argv[]) WSADATA WSAData; #endif /* WIN32 */ - extern int optind; - extern char *optarg; + extern int optind; + extern char *optarg; extern short DebugLvl; /* ---------------- - * register signal handlers. + * register signal handlers. * ---------------- */ signal(SIGINT, die); @@ -834,14 +834,15 @@ PostgresMain(int argc, char *argv[]) #endif /* WIN32 */ /* -------------------- - * initialize globals + * initialize globals * ------------------- */ - InitGlobals(); + MasterPid = getpid(); + DataDir = GetPGData(); /* ---------------- - * parse command line arguments + * parse command line arguments * ---------------- */ flagC = flagQ = flagS = flagE = ShowStats = 0; @@ -850,58 +851,60 @@ PostgresMain(int argc, char *argv[]) /* get hostname is either the environment variable PGHOST or 'localhost' */ if (!(hostName = getenv("PGHOST"))) { - if (gethostname(hostbuf, MAXHOSTNAMELEN) < 0) - (void) strcpy(hostbuf, "localhost"); - hostName = hostbuf; + if (gethostname(hostbuf, MAXHOSTNAMELEN) < 0) + (void) strcpy(hostbuf, "localhost"); + hostName = hostbuf; } - while ((flag = getopt(argc, argv, "B:bCd:Ef:iLm:MNo:P:pQSst:x:F")) != EOF) - switch (flag) { - - case 'b': - /* ---------------- - * set BushyPlanFlag to true. - * ---------------- - */ - BushyPlanFlag = 1; - break; - case 'B': - /* ---------------- - * specify the size of buffer pool - * ---------------- - */ - NBuffers = atoi(optarg); - break; - - case 'C': - /* ---------------- - * don't print version string (don't know why this is 'C' --mao) - * ---------------- - */ - flagC = 1; - break; - - /* ---------------- - * -debug mode - * ---------------- - */ - case 'd': - /* DebugMode = true; */ - flagQ = 0; - DebugPrintPlan = true; - DebugPrintParse = true; - DebugPrintRewrittenParsetree = true; - DebugLvl = (short)atoi(optarg); - break; - - case 'E': - /* ---------------- - * E - echo the query the user entered - * ---------------- - */ - flagE = 1; - break; - + DataDir = getenv("PGDATA"); /* default */ + multiplexedBackend = false; /* default */ + + while ((flag = getopt(argc, argv, "B:bCD:d:Ef:iLm:MNo:P:pQSst:x:F")) + != EOF) + switch (flag) { + + case 'b': + /* ---------------- + * set BushyPlanFlag to true. + * ---------------- + */ + BushyPlanFlag = 1; + break; + case 'B': + /* ---------------- + * specify the size of buffer pool + * ---------------- + */ + NBuffers = atoi(optarg); + break; + + case 'C': + /* ---------------- + * don't print version string (don't know why this is 'C' --mao) + * ---------------- + */ + flagC = 1; + break; + + case 'D': /* PGDATA directory */ + DataDir = optarg; + + case 'd': /* debug level */ + flagQ = 0; + DebugPrintPlan = true; + DebugPrintParse = true; + DebugPrintRewrittenParsetree = true; + DebugLvl = (short)atoi(optarg); + break; + + case 'E': + /* ---------------- + * E - echo the query the user entered + * ---------------- + */ + flagE = 1; + break; + case 'F': /* -------------------- * turn off fsync @@ -910,52 +913,52 @@ PostgresMain(int argc, char *argv[]) fsyncOff = 1; break; - case 'f': - /* ----------------- - * f - forbid generation of certain plans - * ----------------- - */ - switch (optarg[0]) { - case 's': /* seqscan */ + case 'f': + /* ----------------- + * f - forbid generation of certain plans + * ----------------- + */ + switch (optarg[0]) { + case 's': /* seqscan */ _enable_seqscan_ = false; break; - case 'i': /* indexscan */ + case 'i': /* indexscan */ _enable_indexscan_ = false; break; - case 'n': /* nestloop */ + case 'n': /* nestloop */ _enable_nestloop_ = false; break; - case 'm': /* mergejoin */ + case 'm': /* mergejoin */ _enable_mergesort_ = false; break; - case 'h': /* hashjoin */ + case 'h': /* hashjoin */ _enable_hashjoin_ = false; break; - default: + default: errs++; - } - break; + } + break; - case 'i': - dontExecute = 1; - break; - - case 'L': - /* -------------------- - * turn off locking - * -------------------- - */ - lockingOff = 1; - break; - - case 'm': - /* start up a listening backend that can respond to - multiple front-ends. (Note: all the front-end connections - are still connected to a single-threaded backend. Requests - are FCFS. Everything is in one transaction - */ - multiplexedBackend = 1; - serverPortnum = atoi(optarg); + case 'i': + dontExecute = 1; + break; + + case 'L': + /* -------------------- + * turn off locking + * -------------------- + */ + lockingOff = 1; + break; + + case 'm': + /* start up a listening backend that can respond to + multiple front-ends. (Note: all the front-end connections + are still connected to a single-threaded backend. Requests + are FCFS. Everything is in one transaction + */ + multiplexedBackend = true; + serverPortnum = atoi(optarg); #ifdef WIN32 /* There was no postmaster started so the shared memory ** for the shared memory table hasn't been allocated so @@ -963,159 +966,168 @@ PostgresMain(int argc, char *argv[]) */ _nt_init(); #endif /* WIN32 */ - break; - case 'M': - exit(PostmasterMain(argc, argv)); - break; - case 'N': - /* ---------------- - * N - Don't use newline as a query delimiter - * ---------------- - */ - UseNewLine = 0; - break; - - case 'o': - /* ---------------- - * o - send output (stdout and stderr) to the given file - * ---------------- - */ - (void) strncpy(OutputFileName, optarg, MAXPGPATH); - break; - - case 'p': /* started by postmaster */ - /* ---------------- - * p - special flag passed if backend was forked - * by a postmaster. - * ---------------- - */ - IsUnderPostmaster = true; - break; - - case 'P': - /* ---------------- - * P - Use the passed file descriptor number as the port - * on which to communicate with the user. This is ONLY - * useful for debugging when fired up by the postmaster. - * ---------------- - */ - Portfd = atoi(optarg); - break; - - case 'Q': - /* ---------------- - * Q - set Quiet mode (reduce debugging output) - * ---------------- - */ - flagQ = 1; - break; - - case 'S': - /* ---------------- - * S - assume stable main memory - * (don't flush all pages at end transaction) - * ---------------- - */ - flagS = 1; - SetTransactionFlushEnabled(false); - break; - - case 's': - /* ---------------- - * s - report usage statistics (timings) after each query - * ---------------- - */ - ShowStats = 1; - StatFp = stderr; - break; - - case 't': - /* ---------------- - * tell postgres to report usage statistics (timings) for - * each query - * - * -tpa[rser] = print stats for parser time of each query - * -tpl[anner] = print stats for planner time of each query - * -te[xecutor] = print stats for executor time of each query - * caution: -s can not be used together with -t. - * ---------------- - */ - StatFp = stderr; - switch (optarg[0]) { - case 'p': if (optarg[1] == 'a') - ShowParserStats = 1; - else if (optarg[1] == 'l') - ShowPlannerStats = 1; - else - errs++; - break; - case 'e': ShowExecutorStats = 1; break; - default: errs++; break; - } - break; - - case 'x': + break; + case 'M': + exit(PostmasterMain(argc, argv)); + break; + case 'N': + /* ---------------- + * N - Don't use newline as a query delimiter + * ---------------- + */ + UseNewLine = 0; + break; + + case 'o': + /* ---------------- + * o - send output (stdout and stderr) to the given file + * ---------------- + */ + (void) strncpy(OutputFileName, optarg, MAXPGPATH); + break; + + case 'p': /* started by postmaster */ + /* ---------------- + * p - special flag passed if backend was forked + * by a postmaster. + * ---------------- + */ + IsUnderPostmaster = true; + break; + + case 'P': + /* ---------------- + * P - Use the passed file descriptor number as the port + * on which to communicate with the user. This is ONLY + * useful for debugging when fired up by the postmaster. + * ---------------- + */ + Portfd = atoi(optarg); + break; + + case 'Q': + /* ---------------- + * Q - set Quiet mode (reduce debugging output) + * ---------------- + */ + flagQ = 1; + break; + + case 'S': + /* ---------------- + * S - assume stable main memory + * (don't flush all pages at end transaction) + * ---------------- + */ + flagS = 1; + SetTransactionFlushEnabled(false); + break; + + case 's': + /* ---------------- + * s - report usage statistics (timings) after each query + * ---------------- + */ + ShowStats = 1; + StatFp = stderr; + break; + + case 't': + /* ---------------- + * tell postgres to report usage statistics (timings) for + * each query + * + * -tpa[rser] = print stats for parser time of each query + * -tpl[anner] = print stats for planner time of each query + * -te[xecutor] = print stats for executor time of each query + * caution: -s can not be used together with -t. + * ---------------- + */ + StatFp = stderr; + switch (optarg[0]) { + case 'p': if (optarg[1] == 'a') + ShowParserStats = 1; + else if (optarg[1] == 'l') + ShowPlannerStats = 1; + else + errs++; + break; + case 'e': ShowExecutorStats = 1; break; + default: errs++; break; + } + break; + + case 'x': #if 0 /* planner/xfunc.h */ - /* control joey hellerstein's expensive function optimization */ - if (XfuncMode != 0) - { - fprintf(stderr, "only one -x flag is allowed\n"); - errs++; - break; - } - if (strcmp(optarg, "off") == 0) - XfuncMode = XFUNC_OFF; - else if (strcmp(optarg, "nor") == 0) - XfuncMode = XFUNC_NOR; - else if (strcmp(optarg, "nopull") == 0) - XfuncMode = XFUNC_NOPULL; - else if (strcmp(optarg, "nopm") == 0) - XfuncMode = XFUNC_NOPM; - else if (strcmp(optarg, "pullall") == 0) - XfuncMode = XFUNC_PULLALL; - else if (strcmp(optarg, "wait") == 0) - XfuncMode = XFUNC_WAIT; - else { - fprintf(stderr, "use -x {off,nor,nopull,nopm,pullall,wait}\n"); - errs++; - } + /* control joey hellerstein's expensive function optimization */ + if (XfuncMode != 0) + { + fprintf(stderr, "only one -x flag is allowed\n"); + errs++; + break; + } + if (strcmp(optarg, "off") == 0) + XfuncMode = XFUNC_OFF; + else if (strcmp(optarg, "nor") == 0) + XfuncMode = XFUNC_NOR; + else if (strcmp(optarg, "nopull") == 0) + XfuncMode = XFUNC_NOPULL; + else if (strcmp(optarg, "nopm") == 0) + XfuncMode = XFUNC_NOPM; + else if (strcmp(optarg, "pullall") == 0) + XfuncMode = XFUNC_PULLALL; + else if (strcmp(optarg, "wait") == 0) + XfuncMode = XFUNC_WAIT; + else { + fprintf(stderr, "use -x {off,nor,nopull,nopm,pullall,wait}\n"); + errs++; + } #endif - break; - - default: - /* ---------------- - * default: bad command line option - * ---------------- - */ - errs++; - } + break; + + default: + /* ---------------- + * default: bad command line option + * ---------------- + */ + errs++; + } /* ---------------- - * get user name and pathname and check command line validity + * get user name and pathname and check command line validity * ---------------- */ SetPgUserName(); userName = GetPgUserName(); if (FindBackend(pg_pathname, argv[0]) < 0) - elog(FATAL, "%s: could not locate executable, bailing out...", - argv[0]); + elog(FATAL, "%s: could not locate executable, bailing out...", + argv[0]); if (errs || argc - optind > 1) { - usage (argv[0]); - exitpg(1); + usage (argv[0]); + exitpg(1); } else if (argc - optind == 1) { - DBName = argv[optind]; + DBName = argv[optind]; } else if ((DBName = userName) == NULL) { - fprintf(stderr, "%s: USER undefined and no database specified\n", - argv[0]); - exitpg(1); + fprintf(stderr, "%s: USER undefined and no database specified\n", + argv[0]); + exitpg(1); } if (ShowStats && - (ShowParserStats || ShowPlannerStats || ShowExecutorStats)) { - fprintf(stderr, "-s can not be used together with -t.\n"); - exitpg(1); + (ShowParserStats || ShowPlannerStats || ShowExecutorStats)) { + fprintf(stderr, "-s can not be used together with -t.\n"); + exitpg(1); + } + + if (!DataDir) { + fprintf(stderr, "%s does not know where to find the database system " + "data. You must specify the directory that contains the " + "database system either by specifying the -D invocation " + "option or by setting the PGDATA environment variable.\n\n", + argv[0]); + exitpg(1); } Noversion = flagC; @@ -1123,52 +1135,52 @@ PostgresMain(int argc, char *argv[]) EchoQuery = flagE; /* ---------------- - * print flags + * print flags * ---------------- */ if (! Quiet) { - puts("\t---debug info---"); - printf("\tQuiet = %c\n", Quiet ? 't' : 'f'); - printf("\tNoversion = %c\n", Noversion ? 't' : 'f'); - printf("\tstable = %c\n", flagS ? 't' : 'f'); - printf("\ttimings = %c\n", ShowStats ? 't' : 'f'); - printf("\tbufsize = %d\n", NBuffers); - - printf("\tquery echo = %c\n", EchoQuery ? 't' : 'f'); - printf("\tmultiplexed backend? = %c\n", multiplexedBackend ? 't' : 'f'); - printf("\tDatabaseName = [%s]\n", DBName); - puts("\t----------------\n"); + puts("\t---debug info---"); + printf("\tQuiet = %c\n", Quiet ? 't' : 'f'); + printf("\tNoversion = %c\n", Noversion ? 't' : 'f'); + printf("\tstable = %c\n", flagS ? 't' : 'f'); + printf("\ttimings = %c\n", ShowStats ? 't' : 'f'); + printf("\tbufsize = %d\n", NBuffers); + + printf("\tquery echo = %c\n", EchoQuery ? 't' : 'f'); + printf("\tmultiplexed backend? = %c\n", multiplexedBackend ? 't' : 'f'); + printf("\tDatabaseName = [%s]\n", DBName); + puts("\t----------------\n"); } /* ---------------- - * initialize portal file descriptors + * initialize portal file descriptors * ---------------- */ if (IsUnderPostmaster == true) { - if (Portfd < 0) { - fprintf(stderr, - "Postmaster flag set: no port number specified, use /dev/null\n"); - Portfd = open(NULL_DEV, O_RDWR, 0666); - } - pq_init(Portfd); + if (Portfd < 0) { + fprintf(stderr, + "Postmaster flag set: no port number specified, use /dev/null\n"); + Portfd = open(NULL_DEV, O_RDWR, 0666); + } + pq_init(Portfd); } #ifdef WIN32 if ((status = WSAStartup(MAKEWORD(1,1), &WSAData)) == 0) - (void) printf("%s\nInitializing WinSock: %s\n", WSAData.szDescription, WSAData.szSystemStatus); + (void) printf("%s\nInitializing WinSock: %s\n", WSAData.szDescription, WSAData.szSystemStatus); else { - fprintf(stderr, "Error initializing WinSock: %d is the err", status); - exit(1); + fprintf(stderr, "Error initializing WinSock: %d is the err", status); + exit(1); } #endif /* WIN32 */ if (multiplexedBackend) { if (serverPortnum == 0 || - StreamServerPort(hostName, serverPortnum, &serverSock) != STATUS_OK) - { - fprintf(stderr, "Postgres: cannot create stream port %d\n", serverPortnum); - exit(1); - } + StreamServerPort(hostName, serverPortnum, &serverSock) != STATUS_OK) + { + fprintf(stderr, "Postgres: cannot create stream port %d\n", serverPortnum); + exit(1); + } /* { char buf[100]; @@ -1183,34 +1195,34 @@ PostgresMain(int argc, char *argv[]) frontendList = DLNewList(); /* add the original FrontEnd to the list */ if (IsUnderPostmaster == true) { - FrontEnd *fe = malloc(sizeof(FrontEnd)); + FrontEnd *fe = malloc(sizeof(FrontEnd)); - FD_SET(Portfd, &basemask); - maxFd = Max(serverSock,Portfd) + 1; + FD_SET(Portfd, &basemask); + maxFd = Max(serverSock,Portfd) + 1; - fe->fn_connected = true; - fe->fn_Pfin = Pfin; - fe->fn_Pfout = Pfout; - fe->fn_done = false; - (fe->fn_port).sock = Portfd; - DLAddHead(frontendList, DLNewElem(fe)); - numFE++; + fe->fn_connected = true; + fe->fn_Pfin = Pfin; + fe->fn_Pfout = Pfout; + fe->fn_done = false; + (fe->fn_port).sock = Portfd; + DLAddHead(frontendList, DLNewElem(fe)); + numFE++; } else { - numFE = 1; - maxFd = serverSock + 1; + numFE = 1; + maxFd = serverSock + 1; } } if (IsUnderPostmaster || multiplexedBackend) - whereToSendOutput = Remote; + whereToSendOutput = Remote; else - whereToSendOutput = Debug; + whereToSendOutput = Debug; SetProcessingMode(InitProcessing); /* initialize */ if (! Quiet) { - puts("\tInitPostgres().."); + puts("\tInitPostgres().."); } #if WIN32 @@ -1220,7 +1232,7 @@ PostgresMain(int argc, char *argv[]) InitPostgres(DBName); /* ---------------- - * if an exception is encountered, processing resumes here + * if an exception is encountered, processing resumes here * so we abort the current transaction and start a new one. * This must be done after we initialize the slave backends * so that the slaves signal the master to abort the transaction @@ -1238,26 +1250,26 @@ PostgresMain(int argc, char *argv[]) #else if (setjmp(Warn_restart) != 0) { #endif /* WIN32 */ - InWarn = 1; + InWarn = 1; - time(&tim); - - if (! Quiet) - printf("\tAbortCurrentTransaction() at %s\n", ctime(&tim)); + time(&tim); + + if (! Quiet) + printf("\tAbortCurrentTransaction() at %s\n", ctime(&tim)); - memset(parser_input, 0, MAX_PARSE_BUFFER); - - AbortCurrentTransaction(); + memset(parser_input, 0, MAX_PARSE_BUFFER); + + AbortCurrentTransaction(); } InWarn = 0; /* ---------------- - * POSTGRES main processing loop begins here + * POSTGRES main processing loop begins here * ---------------- */ if (IsUnderPostmaster == false) { - puts("\nPOSTGRES backend interactive interface"); - puts("$Revision: 1.18 $ $Date: 1996/11/11 04:54:51 $"); + puts("\nPOSTGRES backend interactive interface"); + puts("$Revision: 1.19 $ $Date: 1996/11/14 10:24:07 $"); } /* ---------------- @@ -1272,183 +1284,183 @@ PostgresMain(int argc, char *argv[]) for (;;) { if (multiplexedBackend) { - if (numFE == 0) - break; + if (numFE == 0) + break; - memmove((char *) &rmask, (char *) &basemask, sizeof(fd_set)); - nSelected = select(maxFd, &rmask,0,0,0); + memmove((char *) &rmask, (char *) &basemask, sizeof(fd_set)); + nSelected = select(maxFd, &rmask,0,0,0); - if (nSelected < 0) { + if (nSelected < 0) { - if (errno == EINTR) continue; - fprintf(stderr,"postgres: multiplexed backend select failed\n"); - exitpg(1); - } - if (FD_ISSET(serverSock, &rmask)) { - /* new connection pending on our well-known port's socket */ - newFE = (FrontEnd*) malloc (sizeof(FrontEnd)); - memset(newFE, 0, sizeof(FrontEnd)); - newFE->fn_connected = false; - newFE->fn_done = false; - newPort = &(newFE->fn_port); - if (StreamConnection(serverSock,newPort) != STATUS_OK) { - StreamClose(newPort->sock); - newFd = -1; - } - else { - DLAddHead(frontendList, DLNewElem(newFE)); - numFE++; - newFd = newPort->sock; - if (newFd >= maxFd) maxFd = newFd + 1; - FD_SET(newFd, &rmask); - FD_SET(newFd, &basemask); - --nSelected; - FD_CLR(serverSock, &rmask); - } - continue; - } /* if FD_ISSET(serverSock) */ + if (errno == EINTR) continue; + fprintf(stderr,"postgres: multiplexed backend select failed\n"); + exitpg(1); + } + if (FD_ISSET(serverSock, &rmask)) { + /* new connection pending on our well-known port's socket */ + newFE = (FrontEnd*) malloc (sizeof(FrontEnd)); + memset(newFE, 0, sizeof(FrontEnd)); + newFE->fn_connected = false; + newFE->fn_done = false; + newPort = &(newFE->fn_port); + if (StreamConnection(serverSock,newPort) != STATUS_OK) { + StreamClose(newPort->sock); + newFd = -1; + } + else { + DLAddHead(frontendList, DLNewElem(newFE)); + numFE++; + newFd = newPort->sock; + if (newFd >= maxFd) maxFd = newFd + 1; + FD_SET(newFd, &rmask); + FD_SET(newFd, &basemask); + --nSelected; + FD_CLR(serverSock, &rmask); + } + continue; + } /* if FD_ISSET(serverSock) */ /* if we get here, it means that the serverSocket was not the one - selected. Instead, one of the front ends was selected. - find which one */ - curr = DLGetHead(frontendList); - while (curr) { - FrontEnd *fe = (FrontEnd*)DLE_VAL(curr); - Port *port = &(fe->fn_port); + selected. Instead, one of the front ends was selected. + find which one */ + curr = DLGetHead(frontendList); + while (curr) { + FrontEnd *fe = (FrontEnd*)DLE_VAL(curr); + Port *port = &(fe->fn_port); - /* this is lifted from postmaster.c */ - if (FD_ISSET(port->sock, &rmask)) { - if (fe->fn_connected == false) { - /* we have a message from a new frontEnd */ - status = PacketReceive(port, &port->buf, NON_BLOCKING); - if (status == STATUS_OK) { - fe->fn_connected = true; - pq_init(port->sock); - fe->fn_Pfin = Pfin; - fe->fn_Pfout = Pfout; - } - else - fprintf(stderr,"Multiplexed backend: error in reading packets from %d\n", port->sock); + /* this is lifted from postmaster.c */ + if (FD_ISSET(port->sock, &rmask)) { + if (fe->fn_connected == false) { + /* we have a message from a new frontEnd */ + status = PacketReceive(port, &port->buf, NON_BLOCKING); + if (status == STATUS_OK) { + fe->fn_connected = true; + pq_init(port->sock); + fe->fn_Pfin = Pfin; + fe->fn_Pfout = Pfout; + } + else + fprintf(stderr,"Multiplexed backend: error in reading packets from %d\n", port->sock); } - else /* we have a query from an existing, active FrontEnd */ - { - Pfin = fe->fn_Pfin; - Pfout = fe->fn_Pfout; - currentFE = fe; + else /* we have a query from an existing, active FrontEnd */ + { + Pfin = fe->fn_Pfin; + Pfout = fe->fn_Pfout; + currentFE = fe; } - if (fe->fn_done) - { - Dlelem *c = curr; - curr = DLGetSucc(curr); - DLRemove(c); - } + if (fe->fn_done) + { + Dlelem *c = curr; + curr = DLGetSucc(curr); + DLRemove(c); + } break; - } - else - curr = DLGetSucc(curr); - } + } + else + curr = DLGetSucc(curr); + } } - /* ---------------- - * (1) read a command. - * ---------------- - */ - memset(parser_input, 0, MAX_PARSE_BUFFER); + /* ---------------- + * (1) read a command. + * ---------------- + */ + memset(parser_input, 0, MAX_PARSE_BUFFER); - firstchar = ReadCommand(parser_input, multiplexedBackend); - /* process the command */ - switch (firstchar) { - /* ---------------- - * 'F' indicates a fastpath call. - * XXX HandleFunctionRequest - * ---------------- - */ - case 'F': - IsEmptyQuery = false; - - /* start an xact for this function invocation */ - if (! Quiet) { - time(&tim); - printf("\tStartTransactionCommand() at %s\n", ctime(&tim)); - } - - StartTransactionCommand(); - HandleFunctionRequest(); - break; - - /* ---------------- - * 'Q' indicates a user query - * ---------------- - */ - case 'Q': - fflush(stdout); - - if ( parser_input[0] == ' ' && parser_input[1] == '\0' ) { - /* ---------------- - * if there is nothing in the input buffer, don't bother - * trying to parse and execute anything.. - * ---------------- - */ - IsEmptyQuery = true; - } else { - /* ---------------- - * otherwise, process the input string. - * ---------------- - */ - IsEmptyQuery = false; - if (ShowStats) - ResetUsage(); - - /* start an xact for this query */ - if (! Quiet) { - time(&tim); - printf("\tStartTransactionCommand() at %s\n", ctime(&tim)); - } - StartTransactionCommand(); - - pg_eval(parser_input, (char **) NULL, (Oid *) NULL, 0); - - if (ShowStats) - ShowUsage(); - } - break; - - /* ---------------- - * 'X' means that the frontend is closing down the socket - * ---------------- - */ - case 'X': - IsEmptyQuery = true; + firstchar = ReadCommand(parser_input, multiplexedBackend); + /* process the command */ + switch (firstchar) { + /* ---------------- + * 'F' indicates a fastpath call. + * XXX HandleFunctionRequest + * ---------------- + */ + case 'F': + IsEmptyQuery = false; + + /* start an xact for this function invocation */ + if (! Quiet) { + time(&tim); + printf("\tStartTransactionCommand() at %s\n", ctime(&tim)); + } + + StartTransactionCommand(); + HandleFunctionRequest(); + break; + + /* ---------------- + * 'Q' indicates a user query + * ---------------- + */ + case 'Q': + fflush(stdout); + + if ( parser_input[0] == ' ' && parser_input[1] == '\0' ) { + /* ---------------- + * if there is nothing in the input buffer, don't bother + * trying to parse and execute anything.. + * ---------------- + */ + IsEmptyQuery = true; + } else { + /* ---------------- + * otherwise, process the input string. + * ---------------- + */ + IsEmptyQuery = false; + if (ShowStats) + ResetUsage(); + + /* start an xact for this query */ + if (! Quiet) { + time(&tim); + printf("\tStartTransactionCommand() at %s\n", ctime(&tim)); + } + StartTransactionCommand(); + + pg_eval(parser_input, (char **) NULL, (Oid *) NULL, 0); + + if (ShowStats) + ShowUsage(); + } + break; + + /* ---------------- + * 'X' means that the frontend is closing down the socket + * ---------------- + */ + case 'X': + IsEmptyQuery = true; if (multiplexedBackend) { FD_CLR(currentFE->fn_port.sock, &basemask); - currentFE->fn_done = true; + currentFE->fn_done = true; numFE--; - } - pq_close(); - break; - - default: - elog(WARN,"unknown frontend message was recieved"); - } - - /* ---------------- - * (3) commit the current transaction - * - * Note: if we had an empty input buffer, then we didn't - * call pg_eval, so we don't bother to commit this transaction. - * ---------------- - */ - if (! IsEmptyQuery) { - if (! Quiet) { - time(&tim); - printf("\tCommitTransactionCommand() at %s\n", ctime(&tim)); - } - CommitTransactionCommand(); - - } else { - if (IsUnderPostmaster || multiplexedBackend) - NullCommand(Remote); - } - + } + pq_close(); + break; + + default: + elog(WARN,"unknown frontend message was recieved"); + } + + /* ---------------- + * (3) commit the current transaction + * + * Note: if we had an empty input buffer, then we didn't + * call pg_eval, so we don't bother to commit this transaction. + * ---------------- + */ + if (! IsEmptyQuery) { + if (! Quiet) { + time(&tim); + printf("\tCommitTransactionCommand() at %s\n", ctime(&tim)); + } + CommitTransactionCommand(); + + } else { + if (IsUnderPostmaster || multiplexedBackend) + NullCommand(Remote); + } + } /* infinite for-loop */ exitpg(0); return 1; @@ -1487,16 +1499,16 @@ ShowUsage(void) memmove((char *)&user, (char *)&r.ru_utime, sizeof(user)); memmove((char *)&sys, (char *)&r.ru_stime,sizeof(sys)); if (elapse_t.tv_usec < Save_t.tv_usec) { - elapse_t.tv_sec--; - elapse_t.tv_usec += 1000000; + elapse_t.tv_sec--; + elapse_t.tv_usec += 1000000; } if (r.ru_utime.tv_usec < Save_r.ru_utime.tv_usec) { - r.ru_utime.tv_sec--; - r.ru_utime.tv_usec += 1000000; + r.ru_utime.tv_sec--; + r.ru_utime.tv_usec += 1000000; } if (r.ru_stime.tv_usec < Save_r.ru_stime.tv_usec) { - r.ru_stime.tv_sec--; - r.ru_stime.tv_usec += 1000000; + r.ru_stime.tv_sec--; + r.ru_stime.tv_usec += 1000000; } /* diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index f35c5d7d8d..ae4aea90f6 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.10 1996/11/10 03:03:28 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.11 1996/11/14 10:24:22 bryanh Exp $ * *------------------------------------------------------------------------- */ @@ -234,7 +234,7 @@ DebugFileOpen(void) fd = fileno(stderr); if (fcntl(fd, F_GETFD, 0) < 0) { sprintf(OutputFileName, "%s/pg.errors.%d", - GetPGData(), (int)getpid()); + DataDir, (int)getpid()); fd = open(OutputFileName, O_CREAT|O_APPEND|O_WRONLY, 0666); } #endif /* WIN32 */ diff --git a/src/backend/utils/init/Makefile b/src/backend/utils/init/Makefile index ccbc145d7b..b3b4ef8c76 100644 --- a/src/backend/utils/init/Makefile +++ b/src/backend/utils/init/Makefile @@ -4,7 +4,7 @@ # Makefile for utils/init # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/utils/init/Makefile,v 1.3 1996/11/12 06:46:40 bryanh Exp $ +# $Header: /cvsroot/pgsql/src/backend/utils/init/Makefile,v 1.4 1996/11/14 10:24:32 bryanh Exp $ # #------------------------------------------------------------------------- @@ -16,9 +16,6 @@ INCLUDE_OPT = -I../.. \ -I../../../include CFLAGS += $(INCLUDE_OPT) -# The following defines really ought to go in config.h -CFLAGS += -DPOSTGRESDIR='"$(POSTGRESDIR)"' -DPGDATADIR='"$(DATADIR)"' \ - -DPOSTPORT='"$(POSTPORT)"' OBJS = enbl.o findbe.o globals.o miscinit.o postinit.o diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c index aafec5dc3a..2326ca1cf9 100644 --- a/src/backend/utils/init/globals.c +++ b/src/backend/utils/init/globals.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.2 1996/11/06 10:31:54 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.3 1996/11/14 10:24:38 bryanh Exp $ * * NOTES * Globals used all over the place should be declared here and not @@ -99,12 +99,3 @@ char *SharedSystemRelationNames[] = { VariableRelationName, 0 }; - -/* set up global variables, pointers, etc. */ -void InitGlobals() -{ - MasterPid = getpid(); - DataDir = GetPGData(); -} - - diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index aaaaf00ab9..a9639d7a74 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.2 1996/11/06 10:31:57 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.3 1996/11/14 10:24:41 bryanh Exp $ * *------------------------------------------------------------------------- */ @@ -345,35 +345,3 @@ SetUserId() UserRelationName); UserId = (Oid) ((Form_pg_user) GETSTRUCT(userTup))->usesysid; } - -/* ---------------- - * GetPGHome - * - * Get POSTGRESHOME from environment, or return default. - * ---------------- - */ -char * -GetPGHome() -{ -#ifdef USE_ENVIRONMENT - char *h; - - if ((h = getenv("POSTGRESHOME")) != (char *) NULL) - return (h); -#endif /* USE_ENVIRONMENT */ - return (POSTGRESDIR); - -} - -char * -GetPGData() -{ -#ifdef USE_ENVIRONMENT - char *p; - - if ((p = getenv("PGDATA")) != (char *) NULL) { - return (p); - } -#endif /* USE_ENVIRONMENT */ - return (PGDATADIR); -} diff --git a/src/bin/createdb/Makefile b/src/bin/createdb/Makefile index 8ec1429d10..fdbc2db7b5 100644 --- a/src/bin/createdb/Makefile +++ b/src/bin/createdb/Makefile @@ -7,21 +7,17 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/bin/createdb/Attic/Makefile,v 1.2 1996/11/11 13:39:34 bryanh Exp $ +# $Header: /cvsroot/pgsql/src/bin/createdb/Attic/Makefile,v 1.3 1996/11/14 10:24:45 bryanh Exp $ # #------------------------------------------------------------------------- SRCDIR= ../.. include ../../Makefile.global -SEDSCRIPT= \ - -e "s^_fUnKy_BINDIR_sTuFf_^$(BINDIR)^g" \ - -e "s^_fUnKy_POSTPORT_sTuFf_^$(POSTPORT)^g" - all: createdb -createdb: - sed $(SEDSCRIPT) createdb +createdb: createdb.sh + cp createdb.sh createdb install: createdb $(INSTALL) $(INSTL_EXE_OPTS) $< $(DESTDIR)$(BINDIR)/$< diff --git a/src/bin/createdb/createdb.sh b/src/bin/createdb/createdb.sh index 819cb54891..741b34e2ea 100644 --- a/src/bin/createdb/createdb.sh +++ b/src/bin/createdb/createdb.sh @@ -11,23 +11,10 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/bin/createdb/Attic/createdb.sh,v 1.4 1996/09/21 06:24:07 scrappy Exp $ +# $Header: /cvsroot/pgsql/src/bin/createdb/Attic/createdb.sh,v 1.5 1996/11/14 10:24:46 bryanh Exp $ # #------------------------------------------------------------------------- -# ---------------- -# Set paths from environment or default values. -# The _fUnKy_..._sTuFf_ gets set when the script is installed -# from the default value for this build. -# Currently the only thing we look for from the environment is -# PGDATA, PGHOST, and PGPORT -# -# ---------------- -[ -z "$PGPORT" ] && PGPORT=_fUnKy_POSTPORT_sTuFf_ -[ -z "$PGHOST" ] && PGHOST=localhost -BINDIR=_fUnKy_BINDIR_sTuFf_ -PATH=$BINDIR:$PATH - CMDNAME=`basename $0` if [ -z "$USER" ]; then @@ -55,12 +42,29 @@ do shift; done -AUTHOPT="-a $AUTHSYS" -[ -z "$AUTHSYS" ] && AUTHOPT="" +if [-z "$AUTHSYS" ]; then + AUTHOPT = "" +else + AUTHOPT = "-a $AUTHSYS" +fi -psql -tq $AUTHOPT -h $PGHOST -p $PGPORT -c "create database $dbname" template1 || { +if [-z "$PGHOST" ]; then + PGHOSTOPT = "" +else + PGHOSTOPT = "-h $PGHOST" +fi + +if [-z "$PGPORT" ]; then + PGPORTOPT = "" +else + PGPORTOPT = "-p $PGPORT" +fi + +psql -tq $AUTHOPT $PGHOSTOPT $PGPORTOPT -c "create database $dbname" template1 + +if [ $? -ne 0 ] echo "$CMDNAME: database creation failed on $dbname." exit 1 -} +fi exit 0 diff --git a/src/bin/createuser/Makefile b/src/bin/createuser/Makefile index 7828758b59..45b8db3da2 100644 --- a/src/bin/createuser/Makefile +++ b/src/bin/createuser/Makefile @@ -7,7 +7,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/bin/createuser/Attic/Makefile,v 1.2 1996/11/11 13:39:40 bryanh Exp $ +# $Header: /cvsroot/pgsql/src/bin/createuser/Attic/Makefile,v 1.3 1996/11/14 10:24:48 bryanh Exp $ # #------------------------------------------------------------------------- @@ -15,14 +15,12 @@ SRCDIR= ../.. include ../../Makefile.global SEDSCRIPT= \ - -e "s^_fUnKy_BINDIR_sTuFf_^$(BINDIR)^g" \ - -e "s^_fUnKy_POSTPORT_sTuFf_^$(POSTPORT)^g" \ -e "s^_fUnKy_DASH_N_sTuFf_^$(DASH_N)^g" \ -e "s^_fUnKy_BACKSLASH_C_sTuFf_^$(BACKSLASH_C)^g" all: createuser -createuser: +createuser: createuser.sh sed $(SEDSCRIPT) createuser install: createuser diff --git a/src/bin/createuser/createuser.sh b/src/bin/createuser/createuser.sh index 3081baa5d3..5789b72b60 100644 --- a/src/bin/createuser/createuser.sh +++ b/src/bin/createuser/createuser.sh @@ -8,25 +8,12 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/bin/createuser/Attic/createuser.sh,v 1.5 1996/10/04 20:29:35 scrappy Exp $ +# $Header: /cvsroot/pgsql/src/bin/createuser/Attic/createuser.sh,v 1.6 1996/11/14 10:24:54 bryanh Exp $ # # Note - this should NOT be setuid. # #------------------------------------------------------------------------- -# ---------------- -# Set paths from environment or default values. -# The _fUnKy_..._sTuFf_ gets set when the script is installed -# from the default value for this build. -# Currently the only thing we look for from the environment is -# PGDATA, PGHOST, and PGPORT -# -# ---------------- -[ -z "$PGPORT" ] && PGPORT=_fUnKy_POSTPORT_sTuFf_ -[ -z "$PGHOST" ] && PGHOST=localhost -BINDIR=_fUnKy_BINDIR_sTuFf_ -PATH=$BINDIR:$PATH - CMDNAME=`basename $0` if [ -z "$USER" ]; then @@ -52,10 +39,25 @@ do shift; done -AUTHOPT="-a $AUTHSYS" -[ -z "$AUTHSYS" ] && AUTHOPT="" +if [-z "$AUTHSYS" ]; then + AUTHOPT = "" +else + AUTHOPT = "-a $AUTHSYS" +fi -PARGS="-tq $AUTHOPT -h $PGHOST -p $PGPORT" +if [-z "$PGHOST" ]; then + PGHOSTOPT = "" +else + PGHOSTOPT = "-h $PGHOST" +fi + +if [-z "$PGPORT" ]; then + PGPORTOPT = "" +else + PGPORTOPT = "-p $PGPORT" +fi + +PARGS="-tq $AUTHOPT $PGHOSTOPT $PGPORTOPT # # generate the first part of the actual monitor command diff --git a/src/bin/destroydb/Makefile b/src/bin/destroydb/Makefile index 10b839d899..eee13fe39e 100644 --- a/src/bin/destroydb/Makefile +++ b/src/bin/destroydb/Makefile @@ -7,21 +7,17 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/bin/destroydb/Attic/Makefile,v 1.2 1996/11/11 13:39:47 bryanh Exp $ +# $Header: /cvsroot/pgsql/src/bin/destroydb/Attic/Makefile,v 1.3 1996/11/14 10:25:10 bryanh Exp $ # #------------------------------------------------------------------------- SRCDIR= ../.. include ../../Makefile.global -SEDSCRIPT= \ - -e "s^_fUnKy_BINDIR_sTuFf_^$(BINDIR)^g" \ - -e "s^_fUnKy_POSTPORT_sTuFf_^$(POSTPORT)^g" - all: destroydb -destroydb: - sed $(SEDSCRIPT) destroydb +destroydb: destroydb.sh + cp destroydb.sh destroydb install: destroydb $(INSTALL) $(INSTL_EXE_OPTS) $< $(DESTDIR)$(BINDIR)/$< diff --git a/src/bin/destroydb/destroydb.sh b/src/bin/destroydb/destroydb.sh index cddd2d9670..e0b0e4256e 100644 --- a/src/bin/destroydb/destroydb.sh +++ b/src/bin/destroydb/destroydb.sh @@ -11,23 +11,10 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/bin/destroydb/Attic/destroydb.sh,v 1.4 1996/09/21 06:24:24 scrappy Exp $ +# $Header: /cvsroot/pgsql/src/bin/destroydb/Attic/destroydb.sh,v 1.5 1996/11/14 10:25:14 bryanh Exp $ # #------------------------------------------------------------------------- -# ---------------- -# Set paths from environment or default values. -# The _fUnKy_..._sTuFf_ gets set when the script is installed -# from the default value for this build. -# Currently the only thing we look for from the environment is -# PGDATA, PGHOST, and PGPORT -# -# ---------------- -[ -z "$PGPORT" ] && PGPORT=_fUnKy_POSTPORT_sTuFf_ -[ -z "$PGHOST" ] && PGHOST=localhost -BINDIR=_fUnKy_BINDIR_sTuFf_ -PATH=$BINDIR:$PATH - CMDNAME=`basename $0` if [ -z "$USER" ]; then @@ -55,10 +42,25 @@ do shift; done -AUTHOPT="-a $AUTHSYS" -[ -z "$AUTHSYS" ] && AUTHOPT="" +if [-z "$AUTHSYS" ]; then + AUTHOPT = "" +else + AUTHOPT = "-a $AUTHSYS" +fi -psql -tq -h $PGHOST -p $PGPORT -c "drop database $dbname" template1 +if [-z "$PGHOST" ]; then + PGHOSTOPT = "" +else + PGHOSTOPT = "-h $PGHOST" +fi + +if [-z "$PGPORT" ]; then + PGPORTOPT = "" +else + PGPORTOPT = "-p $PGPORT" +fi + +psql -tq $AUTHOPT $PGHOSTOPT $PGPORTOPT -c "drop database $dbname" template1 if [ $? -ne 0 ] then diff --git a/src/bin/destroyuser/Makefile b/src/bin/destroyuser/Makefile index 5db5796c75..d890371793 100644 --- a/src/bin/destroyuser/Makefile +++ b/src/bin/destroyuser/Makefile @@ -7,7 +7,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/bin/destroyuser/Attic/Makefile,v 1.2 1996/11/11 13:40:04 bryanh Exp $ +# $Header: /cvsroot/pgsql/src/bin/destroyuser/Attic/Makefile,v 1.3 1996/11/14 10:25:16 bryanh Exp $ # #------------------------------------------------------------------------- @@ -15,14 +15,12 @@ SRCDIR= ../.. include ../../Makefile.global SEDSCRIPT= \ - -e "s^_fUnKy_BINDIR_sTuFf_^$(BINDIR)^g" \ - -e "s^_fUnKy_POSTPORT_sTuFf_^$(POSTPORT)^g" \ -e "s^_fUnKy_DASH_N_sTuFf_^$(DASH_N)^g" \ -e "s^_fUnKy_BACKSLASH_C_sTuFf_^$(BACKSLASH_C)^g" all: destroyuser -destroyuser: +destroyuser: destroyuser.sh sed $(SEDSCRIPT) destroyuser install: destroyuser diff --git a/src/bin/destroyuser/destroyuser.sh b/src/bin/destroyuser/destroyuser.sh index 8f6afc1ee7..41d9509c1f 100644 --- a/src/bin/destroyuser/destroyuser.sh +++ b/src/bin/destroyuser/destroyuser.sh @@ -8,25 +8,12 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/bin/destroyuser/Attic/destroyuser.sh,v 1.4 1996/09/21 06:24:31 scrappy Exp $ +# $Header: /cvsroot/pgsql/src/bin/destroyuser/Attic/destroyuser.sh,v 1.5 1996/11/14 10:25:19 bryanh Exp $ # # Note - this should NOT be setuid. # #------------------------------------------------------------------------- -# ---------------- -# Set paths from environment or default values. -# The _fUnKy_..._sTuFf_ gets set when the script is installed -# from the default value for this build. -# Currently the only thing we look for from the environment is -# PGDATA, PGHOST, and PGPORT -# -# ---------------- -[ -z "$PGPORT" ] && PGPORT=_fUnKy_POSTPORT_sTuFf_ -[ -z "$PGHOST" ] && PGHOST=localhost -BINDIR=_fUnKy_BINDIR_sTuFf_ -PATH=$BINDIR:$PATH - CMDNAME=`basename $0` if [ -z "$USER" ]; then @@ -52,10 +39,25 @@ do shift; done -AUTHOPT="-a $AUTHSYS" -[ -z "$AUTHSYS" ] && AUTHOPT="" +if [-z "$AUTHSYS" ]; then + AUTHOPT = "" +else + AUTHOPT = "-a $AUTHSYS" +fi -PARGS="-tq $AUTHOPT -p $PGPORT -h $PGHOST" +if [-z "$PGHOST" ]; then + PGHOSTOPT = "" +else + PGHOSTOPT = "-h $PGHOST" +fi + +if [-z "$PGPORT" ]; then + PGPORTOPT = "" +else + PGPORTOPT = "-p $PGPORT" +fi + +PARGS="-tq $AUTHOPT $PGHOSTOPT $PGPORTOPT # # generate the first part of the actual monitor command diff --git a/src/bin/initdb/Makefile b/src/bin/initdb/Makefile index 0d9d066e9d..6efbdcc18f 100644 --- a/src/bin/initdb/Makefile +++ b/src/bin/initdb/Makefile @@ -7,7 +7,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/bin/initdb/Makefile,v 1.2 1996/11/11 13:40:25 bryanh Exp $ +# $Header: /cvsroot/pgsql/src/bin/initdb/Makefile,v 1.3 1996/11/14 10:25:22 bryanh Exp $ # #------------------------------------------------------------------------- @@ -15,16 +15,12 @@ SRCDIR= ../.. include ../../Makefile.global SEDSCRIPT= \ - -e "s^_fUnKy_BINDIR_sTuFf_^$(BINDIR)^g" \ - -e "s^_fUnKy_LIBDIR_sTuFf_^$(LIBDIR)^g" \ - -e "s^_fUnKy_DATADIR_sTuFf_^$(DATADIR)^g" \ -e "s^_fUnKy_NAMEDATALEN_sTuFf_^$(NAMEDATALEN)^g" \ - -e "s^_fUnKy_OIDNAMELEN_sTuFf_^$(OIDNAMELEN)^g" \ - -e "s^_fUnKy_POSTPORT_sTuFf_^$(POSTPORT)^g" + -e "s^_fUnKy_OIDNAMELEN_sTuFf_^$(OIDNAMELEN)^g" all: initdb -initdb: +initdb: initdb.sh sed $(SEDSCRIPT) initdb install: initdb diff --git a/src/bin/initdb/initdb.sh b/src/bin/initdb/initdb.sh index b986d2e291..e163b38818 100644 --- a/src/bin/initdb/initdb.sh +++ b/src/bin/initdb/initdb.sh @@ -26,31 +26,32 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.12 1996/10/12 07:49:56 bryanh Exp $ +# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.13 1996/11/14 10:25:33 bryanh Exp $ # #------------------------------------------------------------------------- # ---------------- -# Set paths from environment or default values. # The _fUnKy_..._sTuFf_ gets set when the script is built (with make) # from parameters set in the make file. -# Currently the only thing we look for from the environment is -# PGDATA, PGHOST, and PGPORT. However, we should have environment -# variables for all the paths. # # ---------------- -[ -z "$PGDATA" ] && { PGDATA=_fUnKy_DATADIR_sTuFf_; export PGDATA; } -[ -z "$PGPORT" ] && { PGPORT=_fUnKy_POSTPORT_sTuFf_; export PGPORT; } -[ -z "$PGHOST" ] && { PGHOST=localhost; export PGHOST; } -BINDIR=_fUnKy_BINDIR_sTuFf_ -LIBDIR=_fUnKy_LIBDIR_sTuFf_ + NAMEDATALEN=_fUnKy_NAMEDATALEN_sTuFf_ OIDNAMELEN=_fUnKy_OIDNAMELEN_sTuFf_ -PATH=$BINDIR:$PATH -export PATH CMDNAME=`basename $0` +# Find the default PGLIB directory (the directory that contains miscellaneous +# files that are part of Postgres). The user-written program postconfig +# outputs variable settings like "PGLIB=/usr/lib/whatever". If it doesn't +# output a PGLIB value, then there is no default and the user must +# specify the pglib option. Postconfig may not exist, in which case +# our invocation of it silently fails. + +# The x=x below is to satisfy export if postconfig returns nothing. + +export x=x $(postconfig 2>/dev/null) + # Set defaults: debug=0 noclean=0 @@ -62,45 +63,60 @@ do # ${ARG#--username=} is not reliable or available on all platforms case "$1" in - --debug|-d) - debug=1 - echo "Running with debug mode on." - ;; - --noclean|-n) - noclean=1 - echo "Running with noclean mode on. Mistakes will not be cleaned up." - ;; - --template|-t) - template_only=1 - echo "updating template1 database only." - ;; - --username=*) - POSTGRES_SUPERUSERNAME="`echo $1 | sed s/^--username=//`" - ;; - -u) - shift - POSTGRES_SUPERUSERNAME="$1" - ;; - -u*) - POSTGRES_SUPERUSERNAME="`echo $1 | sed s/^-u//`" - ;; - --pgdata=*) - PGDATA="`echo $1 | sed s/^--pgdata=//`" - ;; - -r) - shift - PGDATA="$1" - ;; - -r*) - PGDATA="`echo $1 | sed s/^-r//`" - ;; - *) - echo "Unrecognized option '$1'. Syntax is:" - echo "initdb [-t | --template] [-d | --debug] [-n | --noclean]" \ - "[-u SUPERUSER | --username=SUPERUSER] [-r DATADIR | --pgdata=DATADIR]" - exit 100 - esac - shift + --debug|-d) + debug=1 + echo "Running with debug mode on." + ;; + --noclean|-n) + noclean=1 + echo "Running with noclean mode on. " + "Mistakes will not be cleaned up." + ;; + --template|-t) + template_only=1 + echo "updating template1 database only." + ;; + --username=*) + POSTGRES_SUPERUSERNAME="`echo $1 | sed s/^--username=//`" + ;; + -u) + shift + POSTGRES_SUPERUSERNAME="$1" + ;; + -u*) + POSTGRES_SUPERUSERNAME="`echo $1 | sed s/^-u//`" + ;; + --pgdata=*) + PGDATA="`echo $1 | sed s/^--pgdata=//`" + ;; + -r) + shift + PGDATA="$1" + ;; + -r*) + PGDATA="`echo $1 | sed s/^-r//`" + ;; + --pglib=*) + PGLIB="`echo $1 | sed s/^--pglib=//`" + ;; + -l) + shift + PGLIB="$1" + ;; + -l*) + PGLIB="`echo $1 | sed s/^-l//`" + ;; + + *) + echo "Unrecognized option '$1'. Syntax is:" + echo "initdb [-t | --template] [-d | --debug]" \ + "[-n | --noclean]" \ + "[-u SUPERUSER | --username=SUPERUSER]" \ + "[-r DATADIR | --pgdata=DATADIR]" \ + "[-l LIBDIR | --pglib=LIBDIR]" + exit 100 + esac + shift done if [ "$debug" -eq 1 ]; then @@ -109,9 +125,34 @@ else BACKENDARGS="-boot -C -F -Q" fi -TEMPLATE=$LIBDIR/local1_template1.bki.source -GLOBAL=$LIBDIR/global1.bki.source -PG_HBA_SAMPLE=$LIBDIR/pg_hba.conf.sample +TEMPLATE=$PGLIB/local1_template1.bki.source +GLOBAL=$PGLIB/global1.bki.source +PG_HBA_SAMPLE=$PGLIB/pg_hba.conf.sample + +#------------------------------------------------------------------------- +# Make sure he told us where to find the Postgres files. +#------------------------------------------------------------------------- +if [ -z $PGLIB ]; then + echo "$CMDNAME does not know where to find the files that make up " + echo "Postgres (the PGLIB directory). You must identify the PGLIB " + echo "directory either with a --pglib invocation option, or by " + echo "setting the PGLIB environment variable, or by having a program " + echo "called 'postconfig' in your search path that sets the PGLIB " + echo "environment variable." + exit 20 +fi + +#------------------------------------------------------------------------- +# Make sure he told us where to build the database system +#------------------------------------------------------------------------- + +if [ -z $PGDATA ]; then + echo "$CMDNAME: You must identify the PGDATA directory, where the data" + echo "for this database system will reside. Do this with either a" + echo "--pgdata invocation option or a PGDATA environment variable." + echo + exit 20 +fi #------------------------------------------------------------------------- # Find the input files @@ -120,7 +161,9 @@ PG_HBA_SAMPLE=$LIBDIR/pg_hba.conf.sample for PREREQ_FILE in $TEMPLATE $GLOBAL $PG_HBA_SAMPLE; do if [ ! -f $PREREQ_FILE ]; then echo "$CMDNAME does not find the file '$PREREQ_FILE'." - echo "This means Postgres95 is incorrectly installed." + echo "This means you have identified an invalid PGLIB directory." + echo "You specify a PGLIB directory with a --pglib invocation " + echo "option, a PGLIB environment variable, or a postconfig program." exit 1 fi done @@ -157,15 +200,13 @@ fi if [ $POSTGRES_SUPERUID -ne `pg_id` -a `pg_id` -ne 0 ]; then echo "Only the unix superuser may initialize a database with a different" echo "Postgres superuser. (You must be able to create files that belong" - echo "to the specified Postgres userid)." + echo "to the specified unix user)." exit 2 fi echo "We are initializing the database system with username" \ "$POSTGRES_SUPERUSERNAME (uid=$POSTGRES_SUPERUID)." -echo "Please be aware that Postgres is not secure. Anyone who can connect" -echo "to the database can act as user $POSTGRES_SUPERUSERNAME" \ - "with very little effort." +echo "This user will own all the files and must also own the server process." echo # ----------------------------------------------------------------------- @@ -182,8 +223,8 @@ if [ -d "$PGDATA" ]; then echo "database system already exists." echo echo "If you want to create a new database system, either remove " - echo "the $PGDATA directory or run initdb with environment variable" - echo "PGDATA set to something other than $PGDATA." + echo "the $PGDATA directory or run initdb with a --pgdata option " + echo "other than $PGDATA." exit 1 fi else diff --git a/src/include/config.h b/src/include/config.h index 377f9ce63e..ff90c1364f 100644 --- a/src/include/config.h +++ b/src/include/config.h @@ -159,6 +159,14 @@ /* OIDNAMELEN should be set to NAMEDATALEN + sizeof(Oid) */ #define OIDNAMELEN 36 +/* + * DEF_PGPORT is the TCP port number on which the Postmaster listens by + * default. This can be overriden by command options, environment variables, + * and the postconfig hook. + */ + +#define DEF_PGPORT "5432" + /* turn this on if you prefer European style dates instead of American * style dates */ diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index da88c6f824..844340f9ef 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -4,7 +4,6 @@ * this file contains general postgres administration and initialization * stuff that used to be spread out between the following files: * globals.h global variables - * magic.h PG_RELEASE, PG_VERSION, etc defines * pdir.h directory path crud * pinit.h postgres initialization * pmod.h processing modes @@ -12,7 +11,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: miscadmin.h,v 1.3 1996/11/12 06:47:10 bryanh Exp $ + * $Id: miscadmin.h,v 1.4 1996/11/14 10:25:42 bryanh Exp $ * * NOTES * some of the information in this file will be moved to @@ -36,13 +35,12 @@ extern int PostmasterMain(int argc, char* argv[]); * from utils/init/globals.c */ extern int Portfd; -extern int Noversion; /* moved from magic.c */ -extern int MasterPid; /* declared and defined in utils/initglobals.c */ +extern int Noversion; +extern int MasterPid; extern int Quiet; extern char *DataDir; extern char OutputFileName[]; -extern void InitGlobals(void); /* * done in storage/backendid.h for now. @@ -83,8 +81,6 @@ extern char *GetPgUserName(void); extern void SetPgUserName(void); extern Oid GetUserId(void); extern void SetUserId(void); -extern char *GetPGHome(void); -extern char *GetPGData(void); extern int ValidateBackend(char *path); extern int FindBackend(char *backend, char *argv0); extern int CheckPathAccess(char *path, char *name, int open_mode); diff --git a/src/interfaces/libpq++/Makefile b/src/interfaces/libpq++/Makefile index 0c734256a9..90e9a770c2 100644 --- a/src/interfaces/libpq++/Makefile +++ b/src/interfaces/libpq++/Makefile @@ -7,7 +7,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/Makefile,v 1.3 1996/11/13 10:35:39 bryanh Exp $ +# $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/Makefile,v 1.4 1996/11/14 10:25:54 bryanh Exp $ # #------------------------------------------------------------------------- @@ -21,7 +21,7 @@ INCLUDE_OPT= \ -I../include \ -I$(LIBPQDIR) -CXXFLAGS+= $(INCLUDE_OPT) -DPOSTPORT='"$(POSTPORT)"' +CXXFLAGS+= $(INCLUDE_OPT) ifdef KRBVERS CXXFLAGS+= $(KRBFLAGS) diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile index 5648ebb313..9e33abd8cb 100644 --- a/src/interfaces/libpq/Makefile +++ b/src/interfaces/libpq/Makefile @@ -7,7 +7,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/interfaces/libpq/Makefile,v 1.16 1996/11/12 11:42:21 bryanh Exp $ +# $Header: /cvsroot/pgsql/src/interfaces/libpq/Makefile,v 1.17 1996/11/14 10:25:48 bryanh Exp $ # #------------------------------------------------------------------------- @@ -17,7 +17,7 @@ include ../Makefile.global # We need the backend directory here for its fmgr.h INCLUDE_OPT= -I../include -I../backend -CFLAGS+= $(INCLUDE_OPT) -DPOSTPORT='"$(POSTPORT)"' +CFLAGS+= $(INCLUDE_OPT) ifdef KRBVERS CFLAGS+= $(KRBFLAGS) diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index 49cd005cb1..88e2c294ad 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.18 1996/11/11 12:16:54 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.19 1996/11/14 10:25:50 bryanh Exp $ * *------------------------------------------------------------------------- */ @@ -63,7 +63,7 @@ static void conninfo_free(void); /* ---------- - * Definition of the conninfo parametes and their fallback resources. + * Definition of the conninfo parameters and their fallback resources. * If Environment-Var and Compiled-in are specified as NULL, no * fallback is available. If after all no value can be determined * for an option, an error is returned. @@ -93,7 +93,7 @@ static PQconninfoOption PQconninfoOptions[] = { { "host", "PGHOST", DefaultHost, NULL, "Database-Host", "", 40 }, - { "port", "PGPORT", POSTPORT, NULL, + { "port", "PGPORT", DEF_PGPORT, NULL, "Database-Port", "", 6 }, { "tty", "PGTTY", DefaultTty, NULL, @@ -192,7 +192,6 @@ PQconnectdb(const char *conninfo) conn->Pfdebug = NULL; conn->port = NULL; conn->notifyList = DLNewList(); - conn->lobjfuncs = NULL; conn->pghost = strdup(conninfo_getval("host")); conn->pgport = strdup(conninfo_getval("port")); @@ -300,7 +299,6 @@ PQsetdb(const char *pghost, const char* pgport, const char* pgoptions, const cha conn->Pfdebug = NULL; conn->port = NULL; conn->notifyList = DLNewList(); - conn->lobjfuncs = NULL; if (!pghost || pghost[0] == '\0') { if (!(tmp = getenv("PGHOST"))) { @@ -312,7 +310,7 @@ PQsetdb(const char *pghost, const char* pgport, const char* pgoptions, const cha if (!pgport || pgport[0] == '\0') { if (!(tmp = getenv("PGPORT"))) { - tmp = POSTPORT; + tmp = DEF_PGPORT; } conn->pgport = strdup(tmp); } else @@ -521,7 +519,6 @@ freePGconn(PGconn *conn) if (conn->dbName) free(conn->dbName); if (conn->pguser) free(conn->pguser); if (conn->notifyList) DLFreeList(conn->notifyList); - if (conn->lobjfuncs) free(conn->lobjfuncs); free(conn); }