1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1987 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984 AT&T */ 28 /* All Rights Reserved */ 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 /*LINTLIBRARY*/ 33 #include <stdio.h> 34 #include <errno.h> 35 #include <malloc.h> 36 #include "iob.h" 37 38 #define active(iop) ((iop)->_flag & (_IOREAD|_IOWRT|_IORW)) 39 40 static unsigned char sbuf[NSTATIC][_SBFSIZ]; 41 unsigned char (*_smbuf)[_SBFSIZ] = sbuf; 42 static FILE **iobglue; 43 static FILE **endglue; 44 45 /* 46 * Find a free FILE for fopen et al. 47 * We have a fixed static array of entries, and in addition 48 * may allocate additional entries dynamically, up to the kernel 49 * limit on the number of open files. 50 * At first just check for a free slot in the fixed static array. 51 * If none are available, then we allocate a structure to glue together 52 * the old and new FILE entries, which are then no longer contiguous. 53 */ 54 FILE * 55 _findiop(void) 56 { 57 FILE **iov, *iop; 58 FILE *fp; 59 60 if(iobglue == NULL) { 61 for(iop = _iob; iop < _iob + NSTATIC; iop++) 62 if(!active(iop)) 63 return(iop); 64 65 if(_f_morefiles() == 0) { 66 errno = ENOMEM; 67 return(NULL); 68 } 69 } 70 71 iov = iobglue; 72 while(*iov != NULL && active(*iov)) 73 if (++iov >= endglue) { 74 errno = EMFILE; 75 return(NULL); 76 } 77 78 if(*iov == NULL) 79 *iov = (FILE *)calloc(1, sizeof **iov); 80 81 return(*iov); 82 } 83 84 int 85 _f_morefiles(void) 86 { 87 FILE **iov; 88 FILE *fp; 89 unsigned char *cp; 90 int nfiles; 91 92 nfiles = getdtablesize(); 93 94 iobglue = (FILE **)calloc(nfiles, sizeof *iobglue); 95 if(iobglue == NULL) 96 return(0); 97 98 if((_smbuf = (unsigned char (*)[_SBFSIZ])malloc(nfiles * sizeof *_smbuf)) == NULL) { 99 free((char *)iobglue); 100 iobglue = NULL; 101 return(0); 102 } 103 104 endglue = iobglue + nfiles; 105 106 for(fp = _iob, iov = iobglue; fp < &_iob[NSTATIC]; /* void */) 107 *iov++ = fp++; 108 109 return(1); 110 } 111 112 void 113 f_prealloc(void) 114 { 115 FILE **iov; 116 FILE *fp; 117 118 if(iobglue == NULL && _f_morefiles() == 0) 119 return; 120 121 for(iov = iobglue; iov < endglue; iov++) 122 if(*iov == NULL) 123 *iov = (FILE *)calloc(1, sizeof **iov); 124 } 125 126 void 127 _fwalk(int (*function)(FILE *)) 128 { 129 FILE **iov; 130 FILE *fp; 131 132 if(function == NULL) 133 return; 134 135 if(iobglue == NULL) { 136 for(fp = _iob; fp < &_iob[NSTATIC]; fp++) 137 if(active(fp)) 138 (*function)(fp); 139 } else { 140 for(iov = iobglue; iov < endglue; iov++) 141 if(*iov && active(*iov)) 142 (*function)(*iov); 143 } 144 } 145