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" /* from S5R2 1.2 */ 31 32 /*LINTLIBRARY*/ 33 #include <stdio.h> 34 #include <errno.h> 35 #include "iob.h" 36 37 #define active(iop) ((iop)->_flag & (_IOREAD|_IOWRT|_IORW)) 38 39 extern char *calloc(); 40 41 static unsigned char sbuf[NSTATIC][_SBFSIZ]; 42 unsigned char (*_smbuf)[_SBFSIZ] = sbuf; 43 static FILE **iobglue; 44 static FILE **endglue; 45 46 /* 47 * Find a free FILE for fopen et al. 48 * We have a fixed static array of entries, and in addition 49 * may allocate additional entries dynamically, up to the kernel 50 * limit on the number of open files. 51 * At first just check for a free slot in the fixed static array. 52 * If none are available, then we allocate a structure to glue together 53 * the old and new FILE entries, which are then no longer contiguous. 54 */ 55 FILE * 56 _findiop() 57 { 58 register FILE **iov, *iop; 59 register FILE *fp; 60 61 if(iobglue == NULL) { 62 for(iop = _iob; iop < _iob + NSTATIC; iop++) 63 if(!active(iop)) 64 return(iop); 65 66 if(_f_morefiles() == 0) { 67 errno = ENOMEM; 68 return(NULL); 69 } 70 } 71 72 iov = iobglue; 73 while(*iov != NULL && active(*iov)) 74 if (++iov >= endglue) { 75 errno = EMFILE; 76 return(NULL); 77 } 78 79 if(*iov == NULL) 80 *iov = (FILE *)calloc(1, sizeof **iov); 81 82 return(*iov); 83 } 84 85 _f_morefiles() 86 { 87 register FILE **iov; 88 register FILE *fp; 89 register 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 f_prealloc() 113 { 114 register FILE **iov; 115 register FILE *fp; 116 117 if(iobglue == NULL && _f_morefiles() == 0) 118 return; 119 120 for(iov = iobglue; iov < endglue; iov++) 121 if(*iov == NULL) 122 *iov = (FILE *)calloc(1, sizeof **iov); 123 } 124 125 void 126 _fwalk(function) 127 register int (*function)(); 128 { 129 register FILE **iov; 130 register 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