|
|
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 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.