Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2000-02-17 22:39:52 +0300
committerChristopher Faylor <me@cgf.cx>2000-02-17 22:39:52 +0300
commit8a0efa53e44919bcf5ccb1d3353618a82afdf8bc (patch)
tree68c3dbf3f2c6fd5d49777def9914d77b5cd4589d /newlib/libc/stdio/findfp.c
parent1fd5e000ace55b323124c7e556a7a864b972a5c4 (diff)
import newlib-2000-02-17 snapshot
Diffstat (limited to 'newlib/libc/stdio/findfp.c')
-rw-r--r--newlib/libc/stdio/findfp.c153
1 files changed, 153 insertions, 0 deletions
diff --git a/newlib/libc/stdio/findfp.c b/newlib/libc/stdio/findfp.c
new file mode 100644
index 000000000..650c638e6
--- /dev/null
+++ b/newlib/libc/stdio/findfp.c
@@ -0,0 +1,153 @@
+/* No user fns here. Pesch 15apr92. */
+
+/*
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include "local.h"
+
+static void
+std (ptr, flags, file, data)
+ FILE *ptr;
+ struct _reent *data;
+{
+ ptr->_p = 0;
+ ptr->_r = 0;
+ ptr->_w = 0;
+ ptr->_flags = flags;
+ ptr->_file = file;
+ ptr->_bf._base = 0;
+ ptr->_bf._size = 0;
+ ptr->_lbfsize = 0;
+ ptr->_cookie = ptr;
+ ptr->_read = __sread;
+ ptr->_write = __swrite;
+ ptr->_seek = __sseek;
+ ptr->_close = __sclose;
+ ptr->_data = data;
+}
+
+struct _glue *
+__sfmoreglue (d, n)
+ struct _reent *d;
+ register int n;
+{
+ struct _glue *g;
+ FILE *p;
+
+ g = (struct _glue *) _malloc_r (d, sizeof (*g) + n * sizeof (FILE));
+ if (g == NULL)
+ return NULL;
+ p = (FILE *) (g + 1);
+ g->_next = NULL;
+ g->_niobs = n;
+ g->_iobs = p;
+ memset (p, 0, n * sizeof (FILE));
+ return g;
+}
+
+/*
+ * Find a free FILE for fopen et al.
+ */
+
+FILE *
+__sfp (d)
+ struct _reent *d;
+{
+ FILE *fp;
+ int n;
+ struct _glue *g;
+
+ if (!d->__sdidinit)
+ __sinit (d);
+ for (g = &d->__sglue;; g = g->_next)
+ {
+ for (fp = g->_iobs, n = g->_niobs; --n >= 0; fp++)
+ if (fp->_flags == 0)
+ goto found;
+ if (g->_next == NULL &&
+ (g->_next = __sfmoreglue (d, NDYNAMIC)) == NULL)
+ break;
+ }
+ d->_errno = ENOMEM;
+ return NULL;
+
+found:
+ fp->_flags = 1; /* reserve this slot; caller sets real flags */
+ fp->_p = NULL; /* no current pointer */
+ fp->_w = 0; /* nothing to read or write */
+ fp->_r = 0;
+ fp->_bf._base = NULL; /* no buffer */
+ fp->_bf._size = 0;
+ fp->_lbfsize = 0; /* not line buffered */
+ fp->_file = -1; /* no file */
+ /* fp->_cookie = <any>; */ /* caller sets cookie, _read/_write etc */
+ fp->_ub._base = NULL; /* no ungetc buffer */
+ fp->_ub._size = 0;
+ fp->_lb._base = NULL; /* no line buffer */
+ fp->_lb._size = 0;
+ fp->_data = d;
+ return fp;
+}
+
+/*
+ * exit() calls _cleanup() through *__cleanup, set whenever we
+ * open or buffer a file. This chicanery is done so that programs
+ * that do not use stdio need not link it all in.
+ *
+ * The name `_cleanup' is, alas, fairly well known outside stdio.
+ */
+
+void
+_cleanup_r (ptr)
+ struct _reent *ptr;
+{
+ /* (void) _fwalk(fclose); */
+ (void) _fwalk (ptr, fflush); /* `cheating' */
+}
+
+#ifndef _REENT_ONLY
+void
+_cleanup ()
+{
+ _cleanup_r (_REENT);
+}
+#endif
+
+/*
+ * __sinit() is called whenever stdio's internal variables must be set up.
+ */
+
+void
+__sinit (s)
+ struct _reent *s;
+{
+ /* make sure we clean up on exit */
+ s->__cleanup = _cleanup_r; /* conservative */
+ s->__sdidinit = 1;
+
+ std (s->__sf + 0, __SRD, 0, s);
+ std (s->__sf + 1, __SWR | __SLBF, 1, s);
+ std (s->__sf + 2, __SWR | __SNBF, 2, s);
+
+ s->__sglue._next = NULL;
+ s->__sglue._niobs = 3;
+ s->__sglue._iobs = &s->__sf[0];
+}