]> git.proxmox.com Git - mirror_edk2.git/blame - StdLib/LibC/Stdio/findfp.c
StdLib: Remove an unnecessary dependency from LibWchar.
[mirror_edk2.git] / StdLib / LibC / Stdio / findfp.c
CommitLineData
0c1992fb 1/** @file\r
2\r
3 Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
4 This program and the accompanying materials are licensed and made available under\r
5 the terms and conditions of the BSD License that accompanies this distribution.\r
6 The full text of the license may be found at\r
7 http://opensource.org/licenses/bsd-license.\r
8\r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
2aa62f2b 11\r
2aa62f2b 12 * Copyright (c) 1990, 1993\r
13 * The Regents of the University of California. All rights reserved.\r
14 *\r
15 * This code is derived from software contributed to Berkeley by\r
16 * Chris Torek.\r
17 *\r
18 * Redistribution and use in source and binary forms, with or without\r
19 * modification, are permitted provided that the following conditions\r
20 * are met:\r
21 * 1. Redistributions of source code must retain the above copyright\r
22 * notice, this list of conditions and the following disclaimer.\r
23 * 2. Redistributions in binary form must reproduce the above copyright\r
24 * notice, this list of conditions and the following disclaimer in the\r
25 * documentation and/or other materials provided with the distribution.\r
26 * 3. Neither the name of the University nor the names of its contributors\r
27 * may be used to endorse or promote products derived from this software\r
28 * without specific prior written permission.\r
29 *\r
30 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
31 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
34 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
36 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
38 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
39 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
40 * SUCH DAMAGE.\r
0c1992fb 41\r
42 NetBSD: findfp.c,v 1.23 2006/10/07 21:40:46 thorpej Exp\r
43 findfp.c 8.2 (Berkeley) 1/4/94\r
44**/\r
2aa62f2b 45#include <LibConfig.h>\r
46#include <sys/EfiCdefs.h>\r
2aa62f2b 47\r
48#include "namespace.h"\r
49#include <sys/param.h>\r
2aa62f2b 50#include <stdio.h>\r
51#include <errno.h>\r
52#include <stdlib.h>\r
53#include <string.h>\r
0c1992fb 54#include <unistd.h>\r
2aa62f2b 55#include "reentrant.h"\r
56#include "local.h"\r
57#include "glue.h"\r
58#include <MainData.h>\r
59\r
60int __sdidinit;\r
61\r
62#define NDYNAMIC 10 /* add ten more whenever necessary */\r
63\r
64#define std(flags, file) \\r
65/* p r w flags file bf lfbsize cookie close */ \\r
66 { NULL, 0, 0, flags, file, { NULL, 0 }, 0, __sF + file, __sclose, \\r
67/* read seek write ext up */ \\r
68 __sread, __sseek, __swrite, { (void *)(__sFext + file), 0 }, NULL, \\r
69/* ur ubuf, nbuf lb blksize offset */ \\r
70 0, { '\0', '\0', '\0' }, { '\0' }, { NULL, 0 }, 0, (fpos_t)0 }\r
71\r
72 /* the usual - (stdin + stdout + stderr) */\r
73static FILE usual[FOPEN_MAX - 3];\r
74static struct __sfileext usualext[FOPEN_MAX - 3];\r
75static struct glue uglue = { 0, FOPEN_MAX - 3, usual };\r
76\r
77#if defined(_REENTRANT) && !defined(__lint__) /* XXX lint is busted */\r
78#define STDEXT { ._lock = MUTEX_INITIALIZER, ._lockcond = COND_INITIALIZER }\r
79struct __sfileext __sFext[3] = { STDEXT,\r
80 STDEXT,\r
81 STDEXT};\r
82#else\r
83struct __sfileext __sFext[3];\r
84#endif\r
85\r
86FILE __sF[3] = {\r
87 std(__SRD, STDIN_FILENO), /* stdin */\r
88 std(__SWR, STDOUT_FILENO), /* stdout */\r
89 std(__SWR|__SNBF, STDERR_FILENO) /* stderr */\r
90};\r
91struct glue __sglue = { &uglue, 3, __sF };\r
92\r
93static struct glue *moreglue(int);\r
94void f_prealloc(void);\r
95\r
96#ifdef _REENTRANT\r
97rwlock_t __sfp_lock = RWLOCK_INITIALIZER;\r
98#endif\r
99\r
100static struct glue *\r
101moreglue(int n)\r
102{\r
103 struct glue *g;\r
104 FILE *p;\r
105 struct __sfileext *pext;\r
106 static FILE empty;\r
107\r
108 g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE)\r
109 + n * sizeof(struct __sfileext));\r
110 if (g == NULL)\r
111 return (NULL);\r
112 p = (FILE *)ALIGN((g + 1));\r
113 g->next = NULL;\r
114 g->niobs = n;\r
115 g->iobs = p;\r
116 pext = (void *)(p + n);\r
117 while (--n >= 0) {\r
118 *p = empty;\r
119 _FILEEXT_SETUP(p, pext);\r
120 p++;\r
121 pext++;\r
122 }\r
123 return (g);\r
124}\r
125\r
126/*\r
127 * Find a free FILE for fopen et al.\r
128 */\r
129FILE *\r
130__sfp()\r
131{\r
132 FILE *fp;\r
133 int n;\r
134 struct glue *g;\r
135\r
136 if (!__sdidinit)\r
137 __sinit();\r
138\r
139 rwlock_wrlock(&__sfp_lock);\r
140 for (g = &__sglue;; g = g->next) {\r
141 for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)\r
142 if (fp->_flags == 0)\r
143 goto found;\r
144 if (g->next == NULL && (g->next = moreglue(NDYNAMIC)) == NULL)\r
145 break;\r
146 }\r
147 rwlock_unlock(&__sfp_lock);\r
148 return (NULL);\r
149found:\r
150 fp->_flags = 1; /* reserve this slot; caller sets real flags */\r
151 fp->_p = NULL; /* no current pointer */\r
152 fp->_w = 0; /* nothing to read or write */\r
153 fp->_r = 0;\r
154 fp->_bf._base = NULL; /* no buffer */\r
155 fp->_bf._size = 0;\r
156 fp->_lbfsize = 0; /* not line buffered */\r
157 fp->_file = -1; /* no file */\r
158/* fp->_cookie = <any>; */ /* caller sets cookie, _read/_write etc */\r
159 _UB(fp)._base = NULL; /* no ungetc buffer */\r
160 _UB(fp)._size = 0;\r
161 fp->_lb._base = NULL; /* no line buffer */\r
162 fp->_lb._size = 0;\r
163 memset(WCIO_GET(fp), 0, sizeof(struct wchar_io_data));\r
164 rwlock_unlock(&__sfp_lock);\r
165 return (fp);\r
166}\r
167\r
168#if 0\r
169/*\r
170 * XXX. Force immediate allocation of internal memory. Not used by stdio,\r
171 * but documented historically for certain applications. Bad applications.\r
172 */\r
173void\r
174f_prealloc()\r
175{\r
176 struct glue *g;\r
177 int n;\r
178\r
179 n = (int)sysconf(_SC_OPEN_MAX) - FOPEN_MAX + 20; /* 20 for slop. */\r
180 for (g = &__sglue; (n -= g->niobs) > 0 && g->next; g = g->next)\r
181 /* void */;\r
182 if (n > 0)\r
183 g->next = moreglue(n);\r
184}\r
185#endif\r
186\r
187/*\r
188 * exit() calls _cleanup() through *gMD->cleanup, set whenever we\r
189 * open or buffer a file. This chicanery is done so that programs\r
190 * that do not use stdio need not link it all in.\r
191 *\r
192 * The name `_cleanup' is, alas, fairly well known outside stdio.\r
193 */\r
194void\r
195_cleanup( void )\r
196{\r
197 /* (void) _fwalk(fclose); */\r
198 (void) fflush(NULL); /* `cheating' */\r
199}\r
200\r
201/*\r
202 * __sinit() is called whenever stdio's internal variables must be set up.\r
203 */\r
204void\r
205__sinit( void )\r
206{\r
207 int i;\r
208\r
209 for (i = 0; i < FOPEN_MAX - 3; i++)\r
210 _FILEEXT_SETUP(&usual[i], &usualext[i]);\r
211\r
212 /* make sure we clean up on exit */\r
213 gMD->cleanup = _cleanup; /* conservative */\r
214 __sdidinit = 1;\r
215}\r