/* * fifo_k.c -- Routines for reading interally typed fifos. * These are all that need to be included in the kernel. */ #include <sys/typed.h> #ifdef KERNEL /* The input channel from tboot to the kernel. */ TYPED_SPACE(boot_gift, 512, T_FIFO_SIC); #endif /* Read a typed space from a fifo. * Return a pointer to the next typed space in the fifo ffp. Returns * NULL on end of fifo. * * This read assumes that ffp->f_space has type T_FIFO_SIC. */ typed_space * fifo_read(ffp) register FIFO *ffp; { typed_space *retval; /* Read MUST be set. */ if (F_READ != F_READ & ffp->f_flags ) { return(T_NULL); /* This ffp is not open for reading. */ } /* From here to the end of fifo_read is really fifo_read_sic(). */ /* Space of size 0 marks EOFIFO. */ if ((int32)0 == ffp->f_offset->ts_size) { retval = T_NULL; } else { /* Return the next space. */ retval = ffp->f_offset; /* Advance to the next space. */ (char *) ffp->f_offset += ffp->f_offset->ts_size; } return(retval); } /* fifo_read() */ /* Go back to the start of the fifo. * Takes a FIFO. For reading, go back to the first space; for writing * truncate the FIFO to empty. * Returns 1 on success, 0 otherwise. */ int fifo_rewind(ffp) FIFO *ffp; { /* Error checking of arguments. */ if (0 == ffp->f_flags) { return(0); /* This ffp is not open. */ } /* Either reading or writing MUST be set. */ if ((F_READ != F_READ & ffp->f_flags) && (F_WRITE != F_WRITE & ffp->f_flags) ){ return(0); /* Illegal flags. */ } /* Rewind to the first space in this fifo (skip the header). */ ffp->f_offset = ((typed_space *) (ffp->f_space)) + 1; return(1); } /* fifo_rewind() */ /* Finish with using a typed space as a fifo. * Free up FIFO structure associated with a typed space. * Returns 0 if ffp was not open, 1 otherwise. */ int fifo_close(ffp) FIFO *ffp; { if (0 == ffp->f_flags) { return(0); /* This ffp is not open. */ } ffp->f_space = F_NULL; ffp->f_offset = T_NULL; ffp->f_flags = 0; return(1); } /* fifo_close() */ /* Open a typed space as a fifo. * * Takes a typed_space that is already allocated, and a mode. The type of * the typed space must be a FIFO. Only T_FIFO_SIC has been implimented * (static, in-core fifo). * * The mode indicates whether to open for reading or writing. * mode == 0 means read only. * mode == 1 means write only. * Other values are illegal. * * Returns a pointer to an initialized FIFO structure. FIFO structures are * allocated from a pre-allocated array. Returns F_NULL if it can't open * the fifo. */ FIFO * fifo_open(fifo_space, mode) typed_space *fifo_space; int mode; { /* ff_table is a table of FIFO structures which can be allocated on * demand. It is functionally similiar to the file descritor table * in the kernel. */ static FIFO ff_table[NFIFOS]; static int inited = (1==2); /* Has ff_table been initialized? */ int i; /* A handy counter. */ FIFO *the_fifo; /* The fifo we are going to allocate. */ /* Initilize ff_table the first time we get called. */ if (!inited) { for (i = 0; i < NFIFOS; ++i) { ff_table[i].f_space = F_NULL; ff_table[i].f_flags = 0; } inited = (1==1); } /* Check the type of the space we were passed. */ switch (fifo_space->ts_type) { case T_FIFO: /* Overly general type, assuming SIC. */ fifo_space->ts_type = T_FIFO_SIC; break; case T_FIFO_SIC:/* Static In-core Fifo. */ break; case T_FIFO_DIC:/* Dynamic In-core Fifo (can grow). */ return(F_NULL); /* Unimplimented. */ case T_FIFO_SP: /* Static Permanent Fifo (fixed size file). */ return(F_NULL); /* Unimplimented. */ case T_FIFO_DP: /* Dynamic Permanent Fifo (ordinary file). */ return(F_NULL); /* Unimplimented. */ default: return(F_NULL); /* Illegal type encountered. */ } /* Is this space at least big enough for an empty fifo? */ if (fifo_space->ts_size < 2 * (sizeof(typed_space))) { return(F_NULL); } /* ASSERTION: fifo_space is a valid and implimented FIFO. */ /* Find the first free FIFO structure. */ /* This should be re-implimented using a malloc-based scheme. * At the moment, the tertiary boot libraries do not include a * malloc. */ for (i = 0; (i < NFIFOS) && (0 != ff_table[i].f_flags); ++i) { /* Do nothing else. */ } if (NFIFOS == i) { return(F_NULL); /* No more free fifo structs. */ } the_fifo = &(ff_table[i]); /* ASSERTION: the_fifo points at a FIFO we can take. */ /* Initialize the FIFO struct. */ the_fifo->f_space = fifo_space; the_fifo->f_offset = fifo_space->ts_data; /* Note that an open for write does not truncate. */ /* Initilize the flags. */ switch(mode) { case 0: /* read */ the_fifo->f_flags |= F_READ; break; case 1: /* write */ the_fifo->f_flags |= F_WRITE; break; default: return(F_NULL); /* Illegal mode flag. */ } return(the_fifo); } /* fifo_open() */ #ifdef TEST #include <stdio.h> /* This is the typed space we will use for our FIFO operations. */ TYPED_SPACE(global_space, 128, T_FIFO_SIC); /* Static In-Core Fifo. */ int main() { FIFO *ffp; /* Fifo pointer for a handle. */ char line[1024]; /* Place to put input lines. */ long size; /* Length for line. (Sizes are all long.) */ int i; typed_space *local_space; /* Open the fifo for writing. */ if (F_NULL == (ffp = fifo_open(&global_space, 1))) { fprintf(stderr, "Can't open global_space for writing.\n"); exit(1); } do { printf("Feed me: "); gets(line); size = (int32) (strlen(line) + 1); } while (T_NULL != fifo_write_untyped(ffp, line, size, T_STR_STR)); if (0 == fifo_close(ffp)) { fprintf(stderr, "Failed to close global_space.\n"); exit(1); } printf("OK, global_space is now full.\n"); /* ASSERTION: We've filled global_space with strings. */ /* Open the fifo for reading. */ if (F_NULL == (ffp = fifo_open(&global_space, 0))) { fprintf(stderr, "Can't open global_space for reading.\n"); exit(1); } /* Dump the contents of this FIFO. */ for (i = 1; T_NULL != (local_space = fifo_read(ffp)); ++i) { printf("%d: size: %ld: type: 0x%x\n", i, local_space->ts_size, local_space->ts_type); /* Assume everything is a NUL terminated string. */ printf("datum: %s\n\n", local_space->ts_data); printf("Hit <RETURN>"); gets(line); } /* Rewind the file, and dump it out again. */ printf("Rewinding.\n"); if (0 == fifo_rewind(ffp)) { fprintf("Can't rewind global_space.\n"); exit(1); } for (i = 1; T_NULL != (local_space = fifo_read(ffp)); ++i) { printf("%d: size: %ld: type: 0x%x\n", i, local_space->ts_size, local_space->ts_type); /* Assume everything is a NUL terminated string. */ printf("datum: %s\n\n", local_space->ts_data); } if (0 == fifo_close(ffp)) { fprintf(stderr, "Failed to close global_space.\n"); exit(1); } exit(0); } /* main() */ #endif /* TEST */