|
|
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.