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: }

Defined functions

main defined in line 67; never used
rubproc defined in line 309; never used

Defined variables

CmMonBuf defined in line 64; used 1 times
CmReset defined in line 62; used 2 times
Database defined in line 56; used 1 times
Equel defined in line 59; used 3 times
Fileset defined in line 55; used 1 times
Out_arg defined in line 61; used 11 times
Pathname defined in line 58; used 1 times
Proc_name defined in line 54; used 5 times
Resp defined in line 48; never used
RubLevel defined in line 60; used 2 times
Syncs defined in line 51; used 4 times
Usercode defined in line 57; used 1 times
Last modified: 1986-04-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1758
Valid CSS Valid XHTML 1.0 Strict