2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved. 2N/A/* Copyright (c) 1988 AT&T */ 2N/A/* All Rights Reserved */ 2N/A#
define FILE_ARY_SZ 8 /* a nice size for FILE array & end_buffer_ptrs */ 2N/A * Macros to declare and loop over a fp or fp/xfp combo to 2N/A * avoid some of the _LP64 ifdef hell. 2N/A/* The extended 32-bit file structure for use in link buffers */ 2N/A * The magic number stored is actually the pointer scrambled with 2N/A * a magic number. Pointers to data items live everywhere in memory 2N/A * so we scramble the pointer in order to avoid accidental collisions. 2N/A /* NULL for the __first_link in ILP32 */ 2N/A int niob;
/* length of the arrays */ 2N/A * With dynamic linking, iob may be in either the library or in the user's 2N/A * a.out, so the run time linker fixes up the first entry in __first_link at 2N/A * process startup time. 2N/A * In 32 bit processes, we don't have xFILE[FILE_ARY_SZ] but FILE[], 2N/A * and _xftab[] instead; this is denoted by having iobp set to NULL in 2N/A * 32 bit mode for the first link entry. 2N/A * Information cached to speed up searches. We remember where we 2N/A * last found a free FILE* and we remember whether we saw any fcloses 2N/A * in between. We also count the number of chunks we allocated, see 2N/A * _findiop() for an explanation. 2N/A * These variables are all protected by _first_link_lock. 2N/A * All functions that understand the linked list of iob's follow. 2N/A__cleanup(
void)
/* called at process end to flush ouput streams */ 2N/A * For fork1-safety (see libc_prepare_atfork(), etc). 2N/A * XXX: We should acquire all of the iob locks here. 2N/A * XXX: We should release all of the iob locks here. 2N/A /* Allow compiler to optimize the loop */ 2N/A * The additional _IONBF check guards againsts 2N/A * allocated but uninitialized iops (see _findiop). 2N/A * We also automatically skip non allocated iop's. 2N/A * Don't block on locks. 2N/A /* Recheck after locking */ 2N/A/* allocate an unused stream; NULL if cannot */ 2N/A /* used so there only needs to be one malloc() */ 2N/A struct {
/* Normal */ 2N/A struct {
/* Reversed */ 2N/A * lock to make testing of fp->_flag == 0 and acquiring the fp atomic 2N/A * and for allocation of new links 2N/A * low contention expected on _findiop(), hence coarse locking. 2N/A * for finer granularity, use fp->_lock for allocating an iop 2N/A * and make the testing of lp->next and allocation of new link atomic 2N/A * If there was a sufficient number of fcloses since we last started 2N/A * at __first_link, we rescan all fp's again. We do not rescan for 2N/A * all fcloses; that would simplify the algorithm but would make 2N/A * search times near O(n) again. 2N/A * Worst case behaviour would still be pretty bad (open a full set, 2N/A * then continously opening and closing one FILE * gets you a full 2N/A * scan each time). That's why we over allocate 1 FILE for each 2N/A * 32 chunks. More over allocation is better; this is a nice 2N/A * empirical value which doesn't cost a lot of memory, doesn't 2N/A * overallocate until we reach 256 FILE *s and keeps the performance 2N/A * pretty close to the optimum. 2N/A * Need to allocate another and put it in the linked list. 2N/A * The problem with referencing a word after a FILE* is the possibility 2N/A * of a SIGSEGV if a non-stdio issue FILE structure ends on a page 2N/A * boundary. We run this check so we never need to run an expensive 2N/A * check like mincore() in order to know whether it is 2N/A * safe to dereference ((xFILE*)fp)->xmagic. 2N/A * We allocate the block with two alternative layouts; if one 2N/A * layout is not properly aligned for our purposes, the other layout 2N/A * will be because the size of _link_ is small compared to 2N/A * The check performed is this: 2N/A * If the distance from pkgp to the end of the page is 2N/A * less than the the offset of the last xmagic field in the 2N/A * xFILE structure, (the 0x1000 boundary is inside our just 2N/A * allocated structure) and the distance modulo the size of xFILE 2N/A * is identical to the offset of the first xmagic in the 2N/A * structure (i.e., XXXXXX000 points to an xmagic field), 2N/A * we need to use the reverse structure. 2N/A /* Use reversed structure */ 2N/A /* Use normal structure */ 2N/A fp->
_flag = 0
377;
/* claim the fp by setting low 8 bits */ 2N/A * when we don't know what it is we'll 2N/A * do the old behaviour and flush 2N/A * check for what is non-SEEKABLE 2N/A * otherwise assume it's SEEKABLE so we get the old 2N/A * behaviour and flush the stream 2N/A * Awkward functions not needed for the sane 64 bit environment. 2N/A * xmagic must not be aligned on a 4K boundary. We guarantee this in 2N/A * For binary compatibility with user programs using the 2N/A * old _bufend macro. This is *so* broken, fileno() 2N/A * is not the proper index. 2N/A * _reallock() is invoked in each stdio call through the IOB_LCK() macro, 2N/A * it is therefor extremely performance sensitive. We get better performance 2N/A * by inlining the STDIOP check in IOB_LCK and inlining a custom version 2N/A * of getfxdat() here. 2N/A/* make sure _cnt, _ptr are correct */ 2N/A/* really write out current buffer contents */ 2N/A * Hopefully, be stable with respect to interrupts... 2N/A/* flush (write) buffer */ 2N/A /* Allow the compiler to optimize the load out of the loop */ 2N/A * We need to grab the file locks or file corruption 2N/A * will happen. But we first check the flags field 2N/A * knowing that when it is 0, it isn't allocated and 2N/A * cannot be allocated while we're holding the 2N/A * _first_link_lock. And when _IONBF is set (also the 2N/A * case when _flag is 0377, or alloc in progress), we 2N/A * Ignore locked streams; it will appear as if 2N/A * concurrent updates happened after fflush(NULL). Note 2N/A * that we even attempt to lock if the locking is set to 2N/A * "by caller". We don't want to penalize callers of 2N/A * __fsetlocking() by not flushing their files. Note: if 2N/A * __fsetlocking() callers don't employ any locking, they 2N/A * may still face corruption in fflush(NULL); but that's 2N/A * no change from earlier releases. 2N/A /* flag 0, flag 0377, or _IONBF set */ 2N/A * don't need to worry about the _IORW case 2N/A * since the iop will also marked with _IOREAD 2N/A * or _IOWRT whichever we are really doing 2N/A /* Flush write buffers */ 2N/A * flush seekable read buffers 2N/A * don't flush non-seekable read buffers 2N/A /* this portion is always assumed locked */ 2N/A /* needed for ungetc & multibyte pushbacks */ 2N/A/* flush buffer and close stream */ 2N/A return (
EOF);
/* avoid passing zero to FLOCKFILE */ 2N/A /* Is not unbuffered and opened for read and/or write ? */ 2N/A/* close all open streams */ 2N/A /* code stolen from fclose(), above */ 2N/A /* Not unbuffered and opened for read and/or write? */ 2N/A/* flush buffer, close fd but keep the stream used by freopen() */ 2N/A /* Is not unbuffered and opened for read and/or write ? */ 2N/A return (
NULL);
/* locked: fp in use */ 2N/A fp->
_flag = 0
377;
/* claim the fp by setting low 8 bits */ 2N/A * This function gets the pointer to the mbstate_t structure associated 2N/A * with the specified iop. 2N/A * If the associated mbstate_t found, the pointer to the mbstate_t is 2N/A * returned. Otherwise, NULL is returned. 2N/A * More 32-bit only functions. 2N/A * The negative value indicates that Extended fd FILE's has not 2N/A * been enabled by the user. 2N/A * Failure indicates a FILE * not allocated through stdio; 2N/A * it means the flag values are probably bogus and that if 2N/A * a file descriptor is set, it's in _magic. 2N/A * Inline getxfdat() for performance reasons. 2N/A * if this is not an internal extended FILE then check 2N/A * if _file is being changed from underneath us. 2N/A * It should not be because if 2N/A * it is then then we lose our ability to guard against 2N/A * silent data corruption. 2N/A "Application violated extended FILE safety mechanism.\n" 2N/A "Please read the man page for extendedFILE.\nAborting\n");
2N/A /* Already known to contain at least one byte */ 2N/A * Activates extended fd's in FILE's 2N/Astatic const int tries[] = {
196,
120,
60,
3};
2N/A * search for an available fd and make it the badfd 2N/A if (
fd < 0)
/* failed to find an available fd */ 2N/A /* caller requests that fd be the chosen badfd */