|
|
1.1 ! root 1: # include <stdio.h> ! 2: # include <signal.h> ! 3: # include "ctlmod.h" ! 4: # include "pipes.h" ! 5: # include <resp.h> ! 6: # include <ingres.h> ! 7: # include <aux.h> ! 8: # include <lock.h> ! 9: # include <sccs.h> ! 10: ! 11: SCCSID(@(#)main.c 8.1 12/31/84) ! 12: ! 13: /* ! 14: ** MAIN -- initialize control module ! 15: ** ! 16: ** Called only once, this routine sets everything up. ! 17: ** ! 18: ** The format of the argv is as follows: ! 19: ** argv[0] -- pathname ! 20: ** argv[1] -- file descriptor for input pipe or'ed with ! 21: ** 0100 to make it printable in a 'ps'. ! 22: ** argv[2] -- Fileset ! 23: ** argv[3] -- Usercode ! 24: ** argv[4] -- Database ! 25: ** argv[5] -- Pathname ! 26: ** ! 27: ** Parameters: ! 28: ** argc, argv -- as usual ! 29: ** ! 30: ** Returns: ! 31: ** none ! 32: ** ! 33: ** Side Effects: ! 34: ** Many; see code. ! 35: ** Proc_name is set to the working process name. ! 36: ** Fileset, Database, Usercode -- set from argv. ! 37: ** Trace vectors are initialized. ! 38: ** ! 39: ** Requires: ! 40: ** markopen -- to mark the open files. ! 41: ** The input pipe must have the Cm struct in it as ! 42: ** the first data. ! 43: ** ! 44: ** Trace Flags: ! 45: ** 1 ! 46: */ ! 47: ! 48: struct resp Resp; /* State response structure */ ! 49: struct _cm_t Cm; /* the system topography map */ ! 50: struct _ctx_t Ctx; /* the current context */ ! 51: int Syncs[CM_MAXPROC];/* expected SYNC's from each proc */ ! 52: ! 53: /* General System Information */ ! 54: char *Proc_name; /* the 'name' of the currently running proc */ ! 55: char *Fileset; /* a unique string to make filenames from */ ! 56: char *Database; /* the name of the current database */ ! 57: char *Usercode; /* the code of the current user */ ! 58: char *Pathname; /* the pathname of the root of INGRES */ ! 59: int Equel; /* set if running an Equel program */ ! 60: int RubLevel; /* rubout level, -1 if ignored */ ! 61: struct out_arg Out_arg; /* output arguments */ ! 62: jmp_buf CmReset; /* restart addr on interrupt */ ! 63: # ifdef xMONITOR ! 64: struct monitor CmMonBuf; /* monitor buffer for CM overhead */ ! 65: # endif xMONITOR ! 66: ! 67: main(argc, argv) ! 68: int argc; ! 69: char **argv; ! 70: { ! 71: register int i; ! 72: struct fn_def *f; ! 73: register char **q; ! 74: register char *p; ! 75: pb_t pb; ! 76: static int reenter; ! 77: extern rubcatch(); ! 78: extern error(); ! 79: bool nobuffer; ! 80: extern pb_t *MonPpb; ! 81: extern long CmOfiles; /* defined in markopen.c */ ! 82: int lock_type = -1; /* type of data base lock to request */ ! 83: int wait_action = -1; /* type of wait action on the data abse */ ! 84: char *args; /* used to process args of sysmod */ ! 85: int j; ! 86: ! 87: Ctx.ctx_name = Proc_name = argv[0]; ! 88: argv[argc] = NULL; ! 89: nobuffer = tTrace(argv, argv[1][1], FuncVect[0]->fn_tvect, 30); ! 90: Ctx.ctx_tvect = tT; ! 91: reenter = 0; ! 92: setjmp(CmReset); ! 93: if (reenter++) ! 94: exit(-1); ! 95: if (signal(SIGINT, SIG_IGN) == SIG_DFL) ! 96: signal(SIGINT, rubcatch); ! 97: else ! 98: RubLevel = -1; ! 99: MonPpb = &pb; ! 100: ! 101: /* mark all currently open files */ ! 102: acc_init(); ! 103: markopen(&CmOfiles); ! 104: ! 105: /* ! 106: ** Process argument vector. ! 107: ** The easy ones just involve saving a pointer. ! 108: ** argv[1] is used to get a file descriptor; this ! 109: ** becomes the initial input. This file ! 110: ** is read to fill in the Cm (configuration) ! 111: ** structure. ! 112: */ ! 113: ! 114: if (tTf(1, 0) || argc < 6) ! 115: prargs(argc, argv); ! 116: ! 117: if (argc < 6) ! 118: syserr("main: argc=%d", argc); ! 119: q = &argv[2]; ! 120: Fileset = *q++; ! 121: Usercode = *q++; ! 122: Database = *q++; ! 123: Pathname = *q++; ! 124: ! 125: i = read(argv[1][0] & 077, (char *) &Cm, sizeof Cm); ! 126: if (i != sizeof Cm) ! 127: syserr("main: read %d", i); ! 128: ! 129: ! 130: /* set up other globals */ ! 131: Ctx.ctx_name = Proc_name = Cm.cm_myname; ! 132: initbuf(Qbuf, QbufSize, ERR_QBUF, error); ! 133: Ctx.ctx_cmark = Ctx.ctx_pmark = markbuf(Qbuf); ! 134: ! 135: ! 136: if ( !sequal( Proc_name, "SYSMOD")) ! 137: { ! 138: /* process flags */ ! 139: for (; (p = *q) != NULL; q++) ! 140: { ! 141: if (p[0] != '-') ! 142: continue; ! 143: switch (p[1]) ! 144: { ! 145: case 'l': /* Lock type */ ! 146: if ( Alockdes < 0 ) ! 147: break; ! 148: if ( p[2] < '0' || p[2] > '9' ) ! 149: syserr("Illegal lock number %s",&p[2]); ! 150: lock_type = atoi(&p[2]); ! 151: if ( wait_action < 0 ) ! 152: break; ! 153: if ( setdbl(wait_action,lock_type) < 0 ) ! 154: { ! 155: syserr("Data base temporarily unavailable"); ! 156: } ! 157: break; ! 158: case 'W': ! 159: /* ! 160: ** type of data base wait to preform ! 161: */ ! 162: if ( Alockdes < 0 ) ! 163: break; ! 164: if ( p[2] < '0' || p[2] > '9' ) ! 165: syserr("Illegal wait action %s",&p[2]); ! 166: wait_action = atoi(&p[2]); ! 167: if ( lock_type < 0 ) ! 168: break; ! 169: if ( setdbl(wait_action,lock_type) < 0 ) ! 170: { ! 171: syserr("Data base temporarily unavailable"); ! 172: } ! 173: break; ! 174: case '&': /* equel program */ ! 175: Equel = 1; ! 176: if (p[6] != '\0') ! 177: Equel = 2; ! 178: break; ! 179: ! 180: case 'c': /* c0 sizes */ ! 181: Out_arg.c0width = atoi(&p[2]); ! 182: break; ! 183: ! 184: case 'i': /* iNsizes */ ! 185: switch (p[2]) ! 186: { ! 187: ! 188: case '1': ! 189: Out_arg.i1width = atoi(&p[3]); ! 190: break; ! 191: ! 192: case '2': ! 193: Out_arg.i2width = atoi(&p[3]); ! 194: break; ! 195: ! 196: case '4': ! 197: Out_arg.i4width = atoi(&p[3]); ! 198: break; ! 199: ! 200: } ! 201: break; ! 202: ! 203: case 'f': /* fN sizes */ ! 204: p = &p[3]; ! 205: i = *p++; ! 206: while (*p != '.') ! 207: p++; ! 208: *p++ = 0; ! 209: if ((*q)[2] == '4') ! 210: { ! 211: Out_arg.f4width = atoi(&(*q)[4]); ! 212: Out_arg.f4prec = atoi(p); ! 213: Out_arg.f4style = i; ! 214: } ! 215: else ! 216: { ! 217: Out_arg.f8width = atoi(&(*q)[4]); ! 218: Out_arg.f8prec = atoi(p); ! 219: Out_arg.f8style = i; ! 220: } ! 221: *--p = '.'; /* restore parm for dbu's */ ! 222: break; ! 223: ! 224: case 'v': /* vertical seperator */ ! 225: Out_arg.coldelim = p[2]; ! 226: break; ! 227: ! 228: } ! 229: } ! 230: ! 231: } ! 232: /* set up trace flags */ ! 233: for (i = 0; i < NumFunc; i++) ! 234: { ! 235: f = FuncVect[i]; ! 236: if (f->fn_tflag != '\0') ! 237: nobuffer |= tTrace(argv, f->fn_tflag, f->fn_tvect, f->fn_tsize); ! 238: Ctx.ctx_name = Proc_name = f->fn_name; ! 239: (*f->fn_initfn)(argc, argv); ! 240: } ! 241: /* end of ingres flags */ ! 242: ! 243: /* ! 244: ** Buffer standard output ! 245: ** ! 246: ** Since VM/UNIX always buffers, we force non-buffered ! 247: ** output if any trace flags are set. ! 248: */ ! 249: ! 250: if (!nobuffer) ! 251: set_so_buf(); ! 252: else ! 253: setbuf(stdout, NULL); ! 254: ! 255: /* if Equel, tell the program to go ahead */ ! 256: if (Equel && Cm.cm_myproc == 1) ! 257: { ! 258: pb_prime(&pb, PB_REG); ! 259: pb.pb_st = PB_FRONT; ! 260: pb_flush(&pb); ! 261: } ! 262: ! 263: /* ! 264: ** Start executing routines. ! 265: ** ! 266: ** Do_seq knows to exit if we get an EOF on the input pipe. ! 267: */ ! 268: ! 269: i = setjmp(CmReset); ! 270: # ifdef xMONITOR ! 271: markperf(&CmMonBuf); ! 272: # endif xMONITOR ! 273: initbuf(Qbuf, QbufSize, ERR_QBUF, error); ! 274: clrmem((char *) &Ctx, sizeof Ctx); ! 275: Ctx.ctx_cmark = Ctx.ctx_pmark = markbuf(Qbuf); ! 276: Ctx.ctx_name = Proc_name = Cm.cm_myname; ! 277: Ctx.ctx_tvect = tT = FuncVect[0]->fn_tvect; ! 278: # ifdef xCTR2 ! 279: if (tTf(1, 1)) ! 280: lprintf("main: setjmp: %d\n", i); ! 281: # endif ! 282: if (RubLevel >= 0) ! 283: signal(SIGINT, rubcatch); ! 284: closeall(FALSE, CmOfiles); ! 285: for (;;) ! 286: { ! 287: Cm.cm_input = Cm.cm_rinput; ! 288: pb.pb_st = PB_UNKNOWN; ! 289: do_seq(&pb); ! 290: } ! 291: } ! 292: /* ! 293: ** RUBPROC -- process rubout signals ! 294: ** ! 295: ** This routine does the processing needed on rubouts ! 296: ** when running with the control module. It basically ! 297: ** flushes pipes. ! 298: ** ! 299: ** Parameters: ! 300: ** none. ! 301: ** ! 302: ** Returns: ! 303: ** never ! 304: ** ! 305: ** Side Effects: ! 306: ** Flushes pipes, etc. ! 307: */ ! 308: ! 309: rubproc() ! 310: { ! 311: register int i; ! 312: pb_t pb; ! 313: register int stat; ! 314: ! 315: /* ! 316: ** Update the world for consistency. ! 317: */ ! 318: ! 319: fflush(stdout); ! 320: closecatalog(FALSE); ! 321: i = pageflush(NULL); ! 322: if (i != 0) ! 323: syserr("rubproc: pageflush %d", i); ! 324: ! 325: /* ! 326: ** Send SYNC blocks to all processes that are adjacent ! 327: ** in the write direction. ! 328: ** Arrange to ignore blocks from all processes that ! 329: ** are adjacent in the read direction. ! 330: */ ! 331: ! 332: pb_prime(&pb, PB_SYNC); ! 333: for (i = 0; i < CM_MAXPROC; i++) ! 334: { ! 335: stat = Cm.cm_proc[i].pr_stat; ! 336: if ((stat & PR_RADJCT) != 0) ! 337: Syncs[i]++; ! 338: if ((stat & PR_WADJCT) != 0) ! 339: { ! 340: pb.pb_proc = i; ! 341: pb_write(&pb); ! 342: } ! 343: } ! 344: ! 345: /* ! 346: ** Cleanup and exit. ! 347: */ ! 348: ! 349: cm_cleanup(2); ! 350: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.