|
|
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.