manual page distributed with 4.2BSD
[unix-history] / usr / src / lib / libc / stdio / findfp.c
index 07e04ff..cbcf288 100644 (file)
@@ -1,69 +1,79 @@
-/* @(#)findfp.c        1.1 (Berkeley) %G% */
-#include "stdio.h"
+/* @(#)findfp.c        1.3 (Berkeley) %G% */
+#include <stdio.h>
 
 
-#define NSTATIC        5       /* stdin, stdout, stderr, plus slack */
+#define active(iop)    ((iop)->_flag & (_IOREAD|_IOWRT|_IORW))
 
 
-extern char *calloc();
-
-static FILE **iov, **iovend;
-static FILE *dummy[NSTATIC];
+#define NSTATIC        3       /* stdin + stdout + stderr */
 
 FILE _iob[NSTATIC] = {
 
 FILE _iob[NSTATIC] = {
-       { 0, NULL, NULL, NULL, _IOREAD, 0 },            /* stdin  */
-       { 0, NULL, NULL, NULL, _IOWRT, 1 },             /* stdout */
-       { 0, NULL, NULL, NULL, _IOWRT+_IONBF, 2 },      /* stderr */
+       { 0, NULL, NULL, 0, _IOREAD,            0 },    /* stdin  */
+       { 0, NULL, NULL, 0, _IOWRT,             1 },    /* stdout */
+       { 0, NULL, NULL, 0, _IOWRT|_IONBF,      2 },    /* stderr */
 };
 
 };
 
+static FILE    *_lastbuf = _iob + NSTATIC;
+
+extern char    *calloc();
+
+static FILE    **iobglue;
+static FILE    **endglue;
+static int     nfiles;
+
 FILE *
 _findiop()
 {
 FILE *
 _findiop()
 {
-       register FILE **iovp;
+       register FILE **iov;
        register FILE *fp;
        register FILE *fp;
-       register int nfiles;
-       register int i;
-       char *p;
 
 
-       if (iov == NULL) {
+       if (nfiles <= 0)
                nfiles = getdtablesize();
                nfiles = getdtablesize();
-               if (nfiles > NSTATIC)
-                       p = calloc(1, nfiles * sizeof *iov +
-                                   (nfiles - NSTATIC) * sizeof **iov);
-               else
-                       p = NULL;
-
-               if (p == NULL) {
-                       iov = dummy;
-                       iovend = iov + NSTATIC;
-               } else {
-                       iov = (FILE **)p;
-                       iovend = iov + nfiles;
-
-                       fp = (FILE *)iovend;
-                       for (iovp = iov + NSTATIC; iovp < iovend; /* void */)
-                               *iovp++ = fp++;
-               }
-
-               for (i = 0; i < NSTATIC; i++)
-                       iov[i] = &_iob[i];
+
+       if (iobglue == NULL) {
+               iobglue = (FILE **)calloc(nfiles, sizeof *iobglue);
+               if (iobglue == NULL)
+                       return (NULL);
+
+               endglue = iobglue + nfiles;
+
+               iov = iobglue;
+               for (fp = _iob; fp < _lastbuf; /* void */)
+                       *iov++ = fp++;
        }
 
        }
 
-       for (iovp = iov; (*iovp)->_flag & (_IOREAD|_IOWRT|_IORW); /* void */)
-               if (++iovp >= iovend)
+       iov = iobglue;
+       while (*iov != NULL && active(*iov))
+               if (++iov >= endglue)
                        return (NULL);
 
                        return (NULL);
 
-       return (*iovp);
+       if (*iov == NULL)
+               *iov = (FILE *)calloc(1, sizeof **iov);
+
+       return (*iov);
+}
+
+_fwalk(function)
+       register int (*function)();
+{
+       register FILE **iov;
+       register FILE *fp;
+
+       if (function == NULL)
+               return;
+
+       if (iobglue == NULL) {
+               for (fp = _iob; fp < _lastbuf; fp++)
+                       if (active(fp))
+                               (*function)(fp);
+       } else {
+               for (iov = iobglue; iov < endglue; iov++)
+                       if (*iov != NULL && active(*iov))
+                               (*function)(*iov);
+       }
 }
 
 _cleanup()
 {
 }
 
 _cleanup()
 {
-       register FILE *_lastbuf = _iob + NSTATIC;
-       register FILE **iovp;
-       register FILE *iop;
-
-       if (iov == NULL)
-               for (iop = _iob; iop < _lastbuf; iop++)
-                       fclose(iop);
-       else
-               for (iovp = iov; iovp < iovend; iovp++)
-                       fclose(*iovp);
+       extern int fclose();
+
+       _fwalk(fclose);
 }
 }