|
|
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 7.3 9/26/83) ! 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: ! 85: Ctx.ctx_name = Proc_name = argv[0]; ! 86: argv[argc] = NULL; ! 87: nobuffer = tTrace(argv, argv[1][1], FuncVect[0]->fn_tvect, 30); ! 88: Ctx.ctx_tvect = tT; ! 89: reenter = 0; ! 90: setjmp(CmReset); ! 91: if (reenter++) ! 92: exit(-1); ! 93: if (signal(SIGINT, SIG_IGN) == SIG_DFL) ! 94: signal(SIGINT, rubcatch); ! 95: else ! 96: RubLevel = -1; ! 97: MonPpb = &pb; ! 98: ! 99: /* mark all currently open files */ ! 100: acc_init(); ! 101: markopen(&CmOfiles); ! 102: ! 103: /* ! 104: ** Process argument vector. ! 105: ** The easy ones just involve saving a pointer. ! 106: ** argv[1] is used to get a file descriptor; this ! 107: ** becomes the initial input. This file ! 108: ** is read to fill in the Cm (configuration) ! 109: ** structure. ! 110: */ ! 111: ! 112: if (tTf(1, 0) || argc < 6) ! 113: prargs(argc, argv); ! 114: if (argc < 6) ! 115: syserr("main: argc=%d", argc); ! 116: q = &argv[2]; ! 117: Fileset = *q++; ! 118: Usercode = *q++; ! 119: Database = *q++; ! 120: Pathname = *q++; ! 121: ! 122: i = read(argv[1][0] & 077, (char *) &Cm, sizeof Cm); ! 123: if (i != sizeof Cm) ! 124: syserr("main: read %d", i); ! 125: ! 126: /* set up other globals */ ! 127: Ctx.ctx_name = Proc_name = Cm.cm_myname; ! 128: initbuf(Qbuf, QbufSize, ERR_QBUF, error); ! 129: Ctx.ctx_cmark = Ctx.ctx_pmark = markbuf(Qbuf); ! 130: ! 131: ! 132: /* process flags */ ! 133: for (; (p = *q) != NULL; q++) ! 134: { ! 135: if (p[0] != '-') ! 136: continue; ! 137: switch (p[1]) ! 138: { ! 139: case 'l': /* Lock type */ ! 140: if ( Alockdes < 0 ) ! 141: break; ! 142: if ( p[2] < '0' || p[2] > '9' ) ! 143: syserr("Illegal lock number %s",&p[2]); ! 144: lock_type = atoi(&p[2]); ! 145: if ( wait_action < 0 ) ! 146: break; ! 147: if ( setdbl(wait_action,lock_type) < 0 ) ! 148: { ! 149: syserr("Data base temporarily unavailable"); ! 150: } ! 151: break; ! 152: case 'W': ! 153: /* ! 154: ** type of data base wait to preform ! 155: */ ! 156: if ( Alockdes < 0 ) ! 157: break; ! 158: if ( p[2] < '0' || p[2] > '9' ) ! 159: syserr("Illegal wait action %s",&p[2]); ! 160: wait_action = atoi(&p[2]); ! 161: if ( lock_type < 0 ) ! 162: break; ! 163: if ( setdbl(wait_action,lock_type) < 0 ) ! 164: { ! 165: syserr("Data base temporarily unavailable"); ! 166: } ! 167: break; ! 168: case '&': /* equel program */ ! 169: Equel = 1; ! 170: if (p[6] != '\0') ! 171: Equel = 2; ! 172: break; ! 173: ! 174: case 'c': /* c0 sizes */ ! 175: Out_arg.c0width = atoi(&p[2]); ! 176: break; ! 177: ! 178: case 'i': /* iNsizes */ ! 179: switch (p[2]) ! 180: { ! 181: ! 182: case '1': ! 183: Out_arg.i1width = atoi(&p[3]); ! 184: break; ! 185: ! 186: case '2': ! 187: Out_arg.i2width = atoi(&p[3]); ! 188: break; ! 189: ! 190: case '4': ! 191: Out_arg.i4width = atoi(&p[3]); ! 192: break; ! 193: ! 194: } ! 195: break; ! 196: ! 197: case 'f': /* fN sizes */ ! 198: p = &p[3]; ! 199: i = *p++; ! 200: while (*p != '.') ! 201: p++; ! 202: *p++ = 0; ! 203: if ((*q)[2] == '4') ! 204: { ! 205: Out_arg.f4width = atoi(&(*q)[4]); ! 206: Out_arg.f4prec = atoi(p); ! 207: Out_arg.f4style = i; ! 208: } ! 209: else ! 210: { ! 211: Out_arg.f8width = atoi(&(*q)[4]); ! 212: Out_arg.f8prec = atoi(p); ! 213: Out_arg.f8style = i; ! 214: } ! 215: *--p = '.'; /* restore parm for dbu's */ ! 216: break; ! 217: ! 218: case 'v': /* vertical seperator */ ! 219: Out_arg.coldelim = p[2]; ! 220: break; ! 221: ! 222: } ! 223: } ! 224: ! 225: /* set up trace flags */ ! 226: for (i = 0; i < NumFunc; i++) ! 227: { ! 228: f = FuncVect[i]; ! 229: if (f->fn_tflag != '\0') ! 230: nobuffer |= tTrace(argv, f->fn_tflag, f->fn_tvect, f->fn_tsize); ! 231: Ctx.ctx_name = Proc_name = f->fn_name; ! 232: (*f->fn_initfn)(argc, argv); ! 233: } ! 234: ! 235: /* ! 236: ** Buffer standard output ! 237: ** ! 238: ** Since VM/UNIX always buffers, we force non-buffered ! 239: ** output if any trace flags are set. ! 240: */ ! 241: ! 242: if (!nobuffer) ! 243: set_so_buf(); ! 244: else ! 245: setbuf(stdout, NULL); ! 246: ! 247: /* if Equel, tell the program to go ahead */ ! 248: if (Equel && Cm.cm_myproc == 1) ! 249: { ! 250: pb_prime(&pb, PB_REG); ! 251: pb.pb_st = PB_FRONT; ! 252: pb_flush(&pb); ! 253: } ! 254: ! 255: /* ! 256: ** Start executing routines. ! 257: ** ! 258: ** Do_seq knows to exit if we get an EOF on the input pipe. ! 259: */ ! 260: ! 261: i = setjmp(CmReset); ! 262: # ifdef xMONITOR ! 263: markperf(&CmMonBuf); ! 264: # endif xMONITOR ! 265: initbuf(Qbuf, QbufSize, ERR_QBUF, error); ! 266: clrmem((char *) &Ctx, sizeof Ctx); ! 267: Ctx.ctx_cmark = Ctx.ctx_pmark = markbuf(Qbuf); ! 268: Ctx.ctx_name = Proc_name = Cm.cm_myname; ! 269: Ctx.ctx_tvect = tT = FuncVect[0]->fn_tvect; ! 270: # ifdef xCTR2 ! 271: if (tTf(1, 1)) ! 272: lprintf("main: setjmp: %d\n", i); ! 273: # endif ! 274: if (RubLevel >= 0) ! 275: signal(SIGINT, rubcatch); ! 276: closeall(FALSE, CmOfiles); ! 277: for (;;) ! 278: { ! 279: Cm.cm_input = Cm.cm_rinput; ! 280: pb.pb_st = PB_UNKNOWN; ! 281: do_seq(&pb); ! 282: } ! 283: } ! 284: /* ! 285: ** RUBPROC -- process rubout signals ! 286: ** ! 287: ** This routine does the processing needed on rubouts ! 288: ** when running with the control module. It basically ! 289: ** flushes pipes. ! 290: ** ! 291: ** Parameters: ! 292: ** none. ! 293: ** ! 294: ** Returns: ! 295: ** never ! 296: ** ! 297: ** Side Effects: ! 298: ** Flushes pipes, etc. ! 299: */ ! 300: ! 301: rubproc() ! 302: { ! 303: register int i; ! 304: pb_t pb; ! 305: register int stat; ! 306: ! 307: /* ! 308: ** Update the world for consistency. ! 309: */ ! 310: ! 311: fflush(stdout); ! 312: closecatalog(FALSE); ! 313: i = pageflush(NULL); ! 314: if (i != 0) ! 315: syserr("rubproc: pageflush %d", i); ! 316: ! 317: /* ! 318: ** Send SYNC blocks to all processes that are adjacent ! 319: ** in the write direction. ! 320: ** Arrange to ignore blocks from all processes that ! 321: ** are adjacent in the read direction. ! 322: */ ! 323: ! 324: pb_prime(&pb, PB_SYNC); ! 325: for (i = 0; i < CM_MAXPROC; i++) ! 326: { ! 327: stat = Cm.cm_proc[i].pr_stat; ! 328: if ((stat & PR_RADJCT) != 0) ! 329: Syncs[i]++; ! 330: if ((stat & PR_WADJCT) != 0) ! 331: { ! 332: pb.pb_proc = i; ! 333: pb_write(&pb); ! 334: } ! 335: } ! 336: ! 337: /* ! 338: ** Cleanup and exit. ! 339: */ ! 340: ! 341: cm_cleanup(2); ! 342: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.