|
|
1.1 root 1: /* $Header: /src386/STREAMS/coh.386/RCS/fifo.c,v 2.3 93/08/09 13:35:27 bin Exp Locker: bin $ */
2: /*
3: * File: fifo.c
4: *
5: * Purpose: allow kernel to fetch data from real-mode bootstrap data area
6: *
7: * $Log: fifo.c,v $
8: * Revision 2.3 93/08/09 13:35:27 bin
9: * Kernel 82 changes
10: *
11: * Revision 2.3 93/07/26 14:59:42 nigel
12: * Nigel's R80
13: *
14: * Revision 1.3 93/04/14 10:06:27 root
15: * r75
16: *
17: * Revision 1.2 92/01/06 11:59:11 hal
18: * Compile with cc.mwc.
19: */
20:
21: /*
22: * Includes.
23: */
24:
25: #include <kernel/typed.h>
26:
27: /*
28: * Definitions.
29: * Constants.
30: * Macros with argument lists.
31: * Typedefs.
32: * Enums.
33: */
34:
35: typedef unsigned char uchar;
36: typedef unsigned int uint;
37: typedef unsigned long ulong;
38:
39: /*
40: * Functions.
41: * Import Functions.
42: * Export Functions.
43: * Local Functions.
44: */
45: FIFO * fifo_open();
46: int fifo_close();
47: typed_space * fifo_read();
48:
49: /*
50: * Global Data.
51: * Import Variables.
52: * Export Variables.
53: * Local Variables.
54: *
55: * Arguments are passed into the kernel through boot_gift.
56: * If you start getting "Not enough room for all arguments." messages
57: * at boot time, just increase the BG_LEN to whatever you need.
58: * This structure is EXACTLY BG_LEN bytes long.
59: */
60: TYPED_SPACE(boot_gift, BG_LEN, T_FIFO_SIC);
61:
62: /*
63: * fifo_open()
64: *
65: * Open a typed space as a fifo.
66: *
67: * Takes a typed_space that is already allocated, and a mode. The type of
68: * the typed space must be a FIFO. Only T_FIFO_SIC has been implemented
69: * (static, in-core fifo).
70: *
71: * The mode indicates whether to open for reading or writing.
72: * mode == 0 means read only.
73: * mode == 1 means write only.
74: * Other values are illegal.
75: *
76: * Returns a pointer to an initialized FIFO structure. FIFO structures are
77: * allocated from a pre-allocated array. Returns F_NULL if it can't open
78: * the fifo.
79: */
80: FIFO *
81: fifo_open(fifo_space, mode)
82: typed_space *fifo_space;
83: int mode;
84: {
85: /* ff_table is a table of FIFO structures which can be allocated on
86: * demand. It is functionally similiar to the file descriptor table
87: * in the kernel.
88: */
89: static FIFO ff_table[NFIFOS];
90: static int inited = 0; /* Has ff_table been initialized? */
91:
92: int i; /* A handy counter. */
93: FIFO *the_fifo; /* The fifo we are going to allocate. */
94:
95: /* Initialize ff_table the first time we get called. */
96: if (!inited) {
97: for (i = 0; i < NFIFOS; ++i) {
98: ff_table[i].f_space = F_NULL;
99: ff_table[i].f_flags = 0;
100: }
101: inited = 1;
102: }
103:
104: /* Check the type of the space we were passed. */
105: switch (fifo_space->ts_type) {
106: case T_FIFO: /* Overly general type, assuming SIC. */
107: fifo_space->ts_type = T_FIFO_SIC;
108: break;
109: case T_FIFO_SIC: /* Static In-core Fifo. */
110: break;
111: case T_FIFO_DIC: /* Dynamic In-core Fifo (can grow). */
112: return(F_NULL); /* Unimplemented. */
113: case T_FIFO_SP: /* Static Permanent Fifo (fixed size file). */
114: return(F_NULL); /* Unimplemented. */
115: case T_FIFO_DP: /* Dynamic Permanent Fifo (ordinary file). */
116: return(F_NULL); /* Unimplemented. */
117: default:
118: return(F_NULL); /* Illegal type encountered. */
119: }
120:
121: /* ASSERTION: fifo_space is a valid and implemented FIFO. */
122:
123: /* Find the first free FIFO structure. */
124:
125: /* This should be re-implemented using a malloc-based scheme.
126: * At the moment, the tertiary boot libraries do not include a
127: * malloc.
128: */
129: for (i = 0; (i < NFIFOS) && (0 != ff_table[i].f_flags); ++i) {
130: /* Do nothing else. */
131: }
132:
133: if (NFIFOS == i) {
134: return(F_NULL); /* No more free fifo structs. */
135: }
136:
137: the_fifo = &(ff_table[i]);
138:
139: /* ASSERTION: the_fifo points at a FIFO we can take. */
140:
141: /* Initialize the FIFO struct. */
142: the_fifo->f_space = fifo_space;
143: the_fifo->f_offset = fifo_space->ts_data;
144:
145: /* Initilize the flags. */
146: switch(mode) {
147: case 0: /* read */
148: the_fifo->f_flags |= F_READ;
149: break;
150: case 1: /* write */
151: the_fifo->f_flags |= F_WRITE;
152: break;
153: default:
154: return(F_NULL); /* Illegal mode flag. */
155: }
156:
157: return(the_fifo);
158: } /* fifo_open() */
159:
160: /*
161: * fifo_close()
162: *
163: * Finish with using a typed space as a fifo.
164: * Free up FIFO structure associated with a typed space.
165: * Returns 0 if ffp was not open, 1 otherwise.
166: */
167: int
168: fifo_close(ffp)
169: FIFO *ffp;
170: {
171: if (0 == ffp->f_flags) {
172: return(0); /* This ffp is not open. */
173: }
174: ffp->f_space = F_NULL;
175: ffp->f_offset = 0;
176: ffp->f_flags = 0;
177:
178: return(1);
179: } /* fifo_close() */
180:
181: /*
182: * fifo_read()
183: *
184: * Read a typed space from a fifo.
185: * Return a pointer to the next typed space in the fifo ffp. Returns
186: * NULL on end of fifo.
187: *
188: * This read assumes that ffp->f_space has type T_FIFO_SIC.
189: */
190: typed_space *
191: fifo_read(ffp)
192: register FIFO *ffp;
193: {
194: typed_space *retval;
195:
196: /* Read MUST be set. */
197: if (F_READ != F_READ & ffp->f_flags ) {
198: printf(" fifo_read: READ not set ");
199: return 0; /* This ffp is not open for reading. */
200: }
201:
202: /* From here to the end of fifo_read is really fifo_read_sic(). */
203:
204:
205: /* Space of size 0 marks EOFIFO. */
206: if ((long)0 == ffp->f_offset->ts_size) {
207: printf(" fifo_read: space of size 0 ");
208: retval = 0;
209: } else {
210: /* Return the next space. */
211: retval = ffp->f_offset;
212: /* Advance to the next space. */
213: (char *) ffp->f_offset += ffp->f_offset->ts_size;
214: }
215:
216: return retval;
217: } /* fifo_read() */
218:
219: #ifdef TEST
220: #include <stdio.h>
221:
222: /* This is the typed space we will use for our FIFO operations. */
223: TYPED_SPACE(global_space, 128, T_FIFO_SIC); /* Static In-Core Fifo. */
224:
225: void
226: main()
227: {
228: FIFO *ffp; /* Fifo pointer for a handle. */
229: char line[1024]; /* Place to put input lines. */
230: long size; /* Length for line. (Sizes are all long.) */
231: int i;
232:
233: typed_space *local_space;
234:
235: /* Open the fifo for writing. */
236: if (F_NULL == (ffp = fifo_open(&global_space, 1))) {
237: fprintf(stderr, "Can't open global_space for writing.\n");
238: exit(1);
239: }
240:
241: do {
242: printf("Feed me: ");
243: gets(line);
244: size = (long) (strlen(line) + 1);
245: } while (fifo_write_untyped(ffp, line, size, T_STR_STR));
246:
247: if (0 == fifo_close(ffp)) {
248: fprintf(stderr, "Failed to close global_space.\n");
249: exit(1);
250: }
251:
252: printf("OK, global_space is now full.\n");
253: /* ASSERTION: We've filled global_space with strings. */
254:
255: /* Open the fifo for reading. */
256: if (F_NULL == (ffp = fifo_open(&global_space, 0))) {
257: fprintf(stderr, "Can't open global_space for reading.\n");
258: exit(1);
259: }
260:
261: /* Dump the contents of this FIFO. */
262: for (i = 1; (local_space = fifo_read(ffp)); ++i) {
263: printf("%d: size: %ld: type: 0x%x\n", i,
264: local_space->ts_size,
265: local_space->ts_type);
266:
267: /* Assume everything is a NUL terminated string. */
268: printf("datum: %s\n\n", local_space->ts_data);
269: printf("Hit <RETURN>");
270: gets(line);
271: }
272:
273:
274: /* Rewind the file, and dump it out again. */
275: printf("Rewinding.\n");
276: if (0 == fifo_rewind(ffp)) {
277: fprintf("Can't rewind global_space.\n");
278: exit(1);
279: }
280:
281: for (i = 1; (local_space = fifo_read(ffp)); ++i) {
282: printf("%d: size: %ld: type: 0x%x\n", i,
283: local_space->ts_size,
284: local_space->ts_type);
285:
286: /* Assume everything is a NUL terminated string. */
287: printf("datum: %s\n\n", local_space->ts_data);
288: }
289:
290: if (0 == fifo_close(ffp)) {
291: fprintf(stderr, "Failed to close global_space.\n");
292: exit(1);
293: }
294:
295: exit(0);
296: } /* main() */
297:
298: #endif /* TEST */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.