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