1: # include "../ingres.h" 2: # include "../pipes.h" 3: # include "../aux.h" 4: # include "../unix.h" 5: # include "../access.h" 6: # include "../lock.h" 7: 8: /* 9: ** DBU CONTROLLER -- Handles parameter passing & return for dbu's. 10: ** 11: ** This is the common control routine for calling dbu routines 12: ** and switching overlays when necessary. The specific dbu routine 13: ** is indicated in the funcid according to a set of numbers 14: ** defined in ../symbol.h. The execid is EXEC_DBU. 15: ** 16: ** The dbu controller calls init_proctab to read in the process table. 17: ** This defines the location of each dbu routine (whether they are in 18: ** overlaya, overlayc, overlayi or overlaym). If the requested dbu routine 19: ** is not in the current overlay, the correct overlay is called with 20: ** the execid of the correct overlay (a,c,i,m) and the correct funcid. 21: ** 22: ** To call a dbu, the parameters are read into a buffer and a pc,pv 23: ** parameter structure is made. When the dbu returns, all system 24: ** relations are flushed and a sync is returned. 25: ** If the Dburetflag is set, then the controller returns the 26: ** Dburetcode structure back. 27: ** 28: ** Positional Parameters: 29: ** standard plus 30: ** Xparams[0] - pathname for ksort 31: ** Xparams[1] - process table 32: ** 33: ** Flags: 34: ** -Z -- trace flags. See individual routines for details 35: ** --X -- X & 077 is a file descriptor to read to get the 36: ** first pipe block (instead of R_up). 37: ** 38: ** Files: 39: ** none 40: ** 41: ** Requires: 42: ** initproc() - to initialize the process 43: ** acc_init() - to open any am files. 44: ** Files[] - array of open file descriptors 45: ** init_proctab() - reads in process table 46: ** 47: ** Compilation Flags: 48: ** xZTR[123] used by various routines 49: ** 50: ** Trace Flags: 51: ** Z1 52: ** 53: ** Diagnostics: 54: ** see reference manual 55: ** 56: ** Compilation Instructions: 57: ** To make a specific overlay use 58: ** setup overlay a (for overlaya) 59: ** This does the following: 60: ** cc -f -n overlaya.c ../../lib/dbulib \\ 61: ** ../../lib/access \\ 62: ** ../../lib/utility \ 63: ** 64: ** mv a.out overlaya 65: ** chmod 4700 overlaya 66: ** mv overlaya ../../bin/overlaya 67: ** 68: ** History: 69: ** 1/25/79 (eric) -- Changed '--X' flag to read file 70: ** X. This simplifies rdpipe. 71: ** 1/8/79 (rse) -- added rubproc routine 72: ** 12/18/78 (rse) -- added Dburetcode structure. 73: ** 10-6-78 (rse) - wrote comment block; added pages 74: ** read/wrote on trace flag 75: */ 76: 77: 78: 79: 80: # define MAXARGS 18 /* max number of args to main() */ 81: # define STRBUFSIZ 1000 /* max bytes of arguments */ 82: 83: extern int Files[MAXFILES]; 84: char Cur_id; 85: char Execid; 86: char Funcid; 87: int Noupdt; 88: struct pipfrmt Pbuf; 89: int Dburetflag; 90: struct retcode Dburetcode; 91: 92: 93: main(argc, argv) 94: int argc; 95: char **argv; 96: { 97: extern char *Proc_name; 98: register char *sp; 99: char *parmv[MAXPARMS]; /* ptrs to string parameters */ 100: char stringbuf[STRBUFSIZ]; /* hold parameters for DBU functions */ 101: char *vect[MAXARGS]; 102: int exind; 103: register int i; 104: int j; 105: extern char **Xparams; 106: extern (*Func[])(); /* function pointers */ 107: register char *funcflag; 108: char **vp; 109: extern long Accuread, Accusread, Accuwrite; 110: int pipevect[2]; 111: 112: initproc("OVERLAYx", argv); 113: Noupdt = !setflag(argv, 'U', 0); 114: exind = length(argv[0]) - 1; 115: Cur_id = argv[0][exind]; 116: Proc_name[7] = Cur_id; 117: bmove(argv, vect, argc * sizeof argv[0]); 118: vect[argc] = 0; 119: i = argc; 120: # ifdef xZTR1 121: tTrace(&argc, argv, 'Z'); 122: if (tTf(1, 2)) 123: prargs(i, vect); 124: # endif 125: 126: /* 127: ** Scan argument vector for '--' flag; if found, save location 128: ** of 'X' part for use when we exec another overlay, and read 129: ** the block from the last overlay. If not found, create a 130: ** '--' flag for later use. 131: */ 132: 133: funcflag = NULL; /* tih */ 134: 135: for (vp = vect; *vp != NULL; vp++) 136: { 137: sp = *vp; 138: if (sp[0] == '-' && sp[1] == '-') 139: { 140: /* deferred EXECID/FUNCID */ 141: funcflag = &sp[2]; 142: i = *funcflag & 077; 143: Execid = rdpipe(P_EXECID, &Pbuf, i); 144: Funcid = rdpipe(P_FUNCID, &Pbuf, i); 145: close(i); 146: } 147: } 148: if (funcflag == NULL) 149: { 150: /* put in a -- flag */ 151: *vp++ = sp = "---"; 152: funcflag = &sp[2]; 153: *vp = NULL; 154: Execid = 0; /* read initial exec/func id */ 155: } 156: 157: /* 158: ** Create list of open files. 159: ** This allows us to close all extraneous files when an 160: ** overlay completes (thus checking consistency) or on 161: ** an interrupt, without really knowing what was going 162: ** on. Notice that we call acc_init so that any files 163: ** the access methods need will be open for this test. 164: */ 165: 166: acc_init(); 167: 168: # ifdef xZTR3 169: if (tTf(1, 8)) 170: printf("Open files: "); 171: # endif 172: for (i = 0; i < MAXFILES; i++) 173: if ((Files[i] = dup(i)) >= 0) 174: { 175: close(Files[i]); 176: # ifdef xZTR3 177: if (tTf(1, 8)) 178: printf(" %d", i); 179: # endif 180: } 181: # ifdef xZTR3 182: if (tTf(1, 8)) 183: printf("\n"); 184: # endif 185: 186: /* initialize the process table */ 187: init_proctab(Xparams[1], Cur_id); 188: 189: setexit(); 190: 191: /* *** MAIN LOOP *** */ 192: for (;;) 193: { 194: /* get exec and func id's */ 195: if (Execid == 0) 196: { 197: rdpipe(P_PRIME, &Pbuf); 198: Execid = rdpipe(P_EXECID, &Pbuf, R_up); 199: Funcid = rdpipe(P_FUNCID, &Pbuf, R_up); 200: } 201: 202: if (Execid == EXEC_DBU) 203: get_proctab(Funcid, &Execid, &Funcid); 204: 205: /* see if in this overlay */ 206: if (Execid != Cur_id) 207: break; 208: i = 0; 209: 210: /* read the parameters */ 211: /*** this should check for overflow of stringbuf ***/ 212: for (sp = stringbuf; j = rdpipe(P_NORM, &Pbuf, R_up, sp, 0); sp += j) 213: parmv[i++] = sp; 214: parmv[i] = (char *) -1; 215: # ifdef xZTR1 216: if (tTf(1, 4)) 217: { 218: printf("overlay %c%c: ", Execid, Funcid); 219: prargs(i, parmv); 220: } 221: # endif 222: if (i >= MAXPARMS) 223: syserr("arg ovf %d %c%c", i, Cur_id, Funcid); 224: 225: /* call the specified function (or it's alias) */ 226: # ifdef xZTR3 227: if (tTf(1, 7)) 228: printf("calling %c%c\n", Execid, Funcid); 229: # endif 230: # ifdef xZTR1 231: if (tTf(50, 0)) 232: { 233: Accuread = 0; 234: Accuwrite = 0; 235: Accusread = 0; 236: } 237: # endif 238: j = Funcid - '0'; 239: if (Funcid >= 'A') 240: j -= 'A' - '9' -1; 241: Dburetflag = FALSE; 242: i = (*Func[j])(i, parmv); 243: # ifdef xZTR1 244: if (tTf(1, 5)) 245: printf("returning %d\n", i); 246: if (tTf(50, 0)) 247: { 248: printf("DBU read %s pages,", locv(Accuread)); 249: printf("%s catalog pages,", locv(Accusread)); 250: printf("wrote %s pages\n", locv(Accuwrite)); 251: } 252: # endif 253: 254: /* do termination processing */ 255: finish(); 256: if (Dburetflag) 257: wrpipe(P_NORM, &Pbuf, W_up, &Dburetcode, sizeof (Dburetcode)); 258: wrpipe(P_END, &Pbuf, W_up); 259: } 260: 261: /* 262: ** Transfer to another overlay. 263: ** We only get to this point if we are in the wrong 264: ** overlay to execute the desired command. 265: ** 266: ** We close system catalog caches and access method files 267: ** so that no extra open files will be laying around. 268: ** Then we adjust the pathname of this overlay to point 269: ** to the next overlay. We then perform a little magic: 270: ** we create a pipe, write the current pipe block into 271: ** the write end of that pipe, and then pass the read 272: ** end on to the next overlay (via the --X flag) -- thus 273: ** using the pipe mechanism as a temporary buffer. 274: */ 275: 276: /* close the system catalog caches */ 277: closecatalog(TRUE); 278: 279: /* close any files left open for access methods */ 280: if (acc_close()) 281: syserr("MAIN: acc_close"); 282: 283: /* setup the execid/Funcid for next overlay */ 284: vect[0][exind] = Execid; 285: 286: /* create and fill the communication pipe */ 287: if (pipexx(pipevect) < 0) 288: syserr("main: pipe"); 289: *funcflag = pipevect[0] | 0100; 290: wrpipe(P_WRITE, &Pbuf, pipevect[1], NULL, 0); 291: close(pipevect[1]); 292: 293: # ifdef xZTR1 294: if (tTf(1, 1)) 295: printf("calling %s\n", vect[0]); 296: # endif 297: execv(vect[0], vect); 298: syserr("cannot exec %s", vect[0]); 299: } 300: 301: 302: 303: finish() 304: { 305: struct stat fstat_buf; 306: register int i; 307: register int j; 308: 309: # ifdef xZTR1 310: if (tTf(1, 15)) 311: { 312: for (i = 0; i < MAXFILES; i++) 313: { 314: j = dup(i); 315: if (j < 0) 316: { 317: if (Files[i] >= 0) 318: printf("file %d closed by %c%c\n", 319: i, Cur_id, Funcid); 320: } 321: else 322: { 323: close(j); 324: if (Files[i] < 0) 325: { 326: fstat(i, &fstat_buf); 327: printf("file %d (i# %u) opened by %c%c\n", 328: i, fstat_buf.st_ino, Cur_id, Funcid); 329: close(i); 330: } 331: } 332: } 333: } 334: # endif 335: 336: /* flush the buffers for the system catalogs */ 337: closecatalog(FALSE); 338: 339: wrpipe(P_PRIME, &Pbuf, Execid, 0, Funcid); 340: Execid = Funcid = 0; 341: } 342: 343: 344: 345: rubproc() 346: { 347: register int i; 348: 349: flush(); 350: resyncpipes(); 351: finish(); 352: 353: /* close any extraneous files */ 354: unlall(); 355: for (i = 0; i < MAXFILES; i++) 356: if (Files[i] < 0) 357: close(i); 358: } 359: 360: 361: 362: /* 363: ** PIPEXX -- dummy call to pipe 364: ** 365: ** This is exactly like pipe (in fact, it calls pipe), 366: ** but is included because some versions of the C interface 367: ** to UNIX clobber a register varaible. Yeuch, shit, and 368: ** all that. 369: */ 370: 371: pipexx(pv) 372: int pv[2]; 373: { 374: return (pipe(pv)); 375: }