1 /* 2 * Copyright (c) 1983, 1985 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 */ 6 7 #ifndef lint 8 static char sccsid[] = "@(#)findfp.c 5.3 (Berkeley) 02/06/86"; 9 #endif not lint 10 11 #include <stdio.h> 12 #include <errno.h> 13 14 extern int errno; 15 16 #define active(iop) ((iop)->_flag & (_IOREAD|_IOWRT|_IORW)) 17 18 #define NSTATIC 20 /* stdin + stdout + stderr + the usual */ 19 20 FILE _iob[NSTATIC] = { 21 { 0, NULL, NULL, 0, _IOREAD, 0 }, /* stdin */ 22 { 0, NULL, NULL, 0, _IOWRT, 1 }, /* stdout */ 23 { 0, NULL, NULL, 0, _IOWRT|_IONBF, 2 }, /* stderr */ 24 }; 25 26 extern char *calloc(); 27 28 static FILE **iobglue; 29 static FILE **endglue; 30 static int nfiles; 31 32 FILE * 33 _findiop() 34 { 35 register FILE **iov; 36 register FILE *fp; 37 38 if (iobglue == 0 && _stdio_init() == 0) { 39 errno = ENOMEM; 40 return (NULL); 41 } 42 43 iov = iobglue; 44 while (*iov != NULL && active(*iov)) 45 if (++iov >= endglue) { 46 errno = EMFILE; 47 return (NULL); 48 } 49 50 if (*iov == NULL) 51 *iov = (FILE *)calloc(1, sizeof **iov); 52 53 return (*iov); 54 } 55 56 _stdio_init() 57 { 58 register FILE **iov; 59 register FILE *fp; 60 61 nfiles = getdtablesize(); 62 63 iobglue = (FILE **)calloc(nfiles, sizeof *iobglue); 64 if (iobglue == NULL) 65 return (0); 66 67 endglue = iobglue + nfiles; 68 69 for (fp = _iob, iov = iobglue; fp < &_iob[NSTATIC]; /* void */) 70 *iov++ = fp++; 71 return (1); 72 } 73 74 f_prealloc() 75 { 76 register FILE **iov; 77 register FILE *fp; 78 79 if (iobglue == NULL && _stdio_init() == 0) 80 return; 81 82 for (iov = iobglue; iov < endglue; iov++) 83 if (*iov == NULL) 84 *iov = (FILE *)calloc(1, sizeof **iov); 85 } 86 87 _fwalk(function) 88 register int (*function)(); 89 { 90 register FILE **iov; 91 register FILE *fp; 92 93 if (iobglue == NULL) { 94 for (fp = _iob; fp < &_iob[NSTATIC]; fp++) 95 if (active(fp)) 96 (*function)(fp); 97 } else { 98 for (iov = iobglue; iov < endglue; iov++) 99 if (*iov && active(*iov)) 100 (*function)(*iov); 101 } 102 } 103 104 _cleanup() 105 { 106 extern int fclose(); 107 108 _fwalk(fclose); 109 } 110