home *** CD-ROM | disk | FTP | other *** search
- /* This is file FINDIOP.C */
- /* This file may have been modified by DJ Delorie (Jan 1991). If so,
- ** these modifications are Coyright (C) 1993 DJ Delorie, 24 Kirsten Ave,
- ** Rochester NH, 03867-2954, USA.
- */
-
- /*
- * Copyright (c) 1983, 1985 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
- #if defined(LIBC_SCCS) && !defined(lint)
- static char sccsid[] = "@(#)findiop.c 5.7 (Berkeley) 9/22/88";
- #endif LIBC_SCCS and not lint
-
- #include <stdio.h>
- #include <errno.h>
- #include <fcntl.h>
-
- extern int errno;
-
- #define active(iop) ((iop)->_flag & (_IOREAD|_IOWRT|_IORW))
-
- #define NSTATIC 20 /* stdin + stdout + stderr + the usual */
-
- FILE _iob[NSTATIC] = {
- { 0, NULL, NULL, 0, _IOREAD|_IOTEXT, 0 }, /* stdin */
- { 0, NULL, NULL, 0, _IOWRT|_IOTEXT, 1 }, /* stdout */
- { 0, NULL, NULL, 0, _IOWRT|_IONBF|_IOTEXT,2 }, /* stderr */
- { 0, NULL, NULL, 0, _IOWRT|_IONBF,3 }, /* stdaux */
- { 0, NULL, NULL, 0, _IOWRT|_IONBF,4 }, /* stdprn */
- };
-
- extern void *calloc();
-
- static char sbuf[NSTATIC];
- char *_smallbuf = sbuf;
- static FILE **iobglue;
- static FILE **endglue;
-
- static _f_morefiles();
-
- int setmode(int handle, int newmode)
- {
- FILE *f, **fp;
- int i;
- for (i=0; i<NSTATIC; i++)
- if (_iob[i]._file == handle)
- {
- f = _iob + i;
- goto got_it;
- }
- if (!iobglue)
- goto not_got_it;
- for (fp=iobglue; fp<endglue; fp++)
- if ((*fp)->_file == handle)
- {
- f = *fp;
- break;
- }
-
- got_it:
- if (newmode & O_BINARY)
- f->_flag &= ~_IOTEXT;
- else
- f->_flag |= _IOTEXT;
-
- not_got_it:
- return _setmode(handle, newmode);
- }
-
- /*
- * Find a free FILE for fopen et al.
- * We have a fixed static array of entries, and in addition
- * may allocate additional entries dynamically, up to the kernel
- * limit on the number of open files.
- * At first just check for a free slot in the fixed static array.
- * If none are available, then we allocate a structure to glue together
- * the old and new FILE entries, which are then no longer contiguous.
- */
- FILE *
- _findiop()
- {
- register FILE **iov, *iop;
- register FILE *fp;
-
- if (iobglue == 0) {
- for (iop = _iob; iop < _iob + NSTATIC; iop++)
- if (!active(iop))
- return (iop);
-
- if (_f_morefiles() == 0) {
- errno = ENOMEM;
- return (NULL);
- }
- }
-
- iov = iobglue;
- while (*iov != NULL && active(*iov))
- if (++iov >= endglue) {
- errno = EMFILE;
- return (NULL);
- }
-
- if (*iov == NULL)
- *iov = (FILE *)calloc(1, sizeof **iov);
-
- return (*iov);
- }
-
- _f_morefiles()
- {
- register FILE **iov;
- register FILE *fp;
- register char *cp;
- int nfiles;
-
- nfiles = getdtablesize();
-
- iobglue = (FILE **)calloc(nfiles, sizeof *iobglue);
- if (iobglue == NULL)
- return (0);
-
- endglue = iobglue + nfiles;
-
- for (fp = _iob, iov = iobglue; fp < &_iob[NSTATIC]; /* void */)
- *iov++ = fp++;
-
- _smallbuf = calloc(nfiles, sizeof(*_smallbuf));
- return (1);
- }
-
- _fwalk(function)
- register int (*function)();
- {
- register FILE **iov;
- register FILE *fp;
-
- if (iobglue == NULL) {
- for (fp = _iob; fp < &_iob[NSTATIC]; fp++)
- if (active(fp))
- (*function)(fp);
- } else {
- for (iov = iobglue; iov < endglue; iov++)
- if (*iov && active(*iov))
- (*function)(*iov);
- }
- }
-