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