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