]> git.saurik.com Git - apple/libc.git/blob - stdio/FreeBSD/findfp.c.patch
Libc-594.1.4.tar.gz
[apple/libc.git] / stdio / FreeBSD / findfp.c.patch
1 --- findfp.c.orig 2009-02-15 03:11:22.000000000 -0800
2 +++ findfp.c 2009-02-15 18:45:19.000000000 -0800
3 @@ -46,7 +46,10 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/f
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 +#include <libkern/OSAtomic.h>
8 +#include <errno.h>
9
10 +#include <pthread.h>
11 #include <spinlock.h>
12
13 #include "libc_private.h"
14 @@ -62,12 +65,19 @@ int __sdidinit;
15 {0}, __sFX + file}
16 /* p r w flags file _bf z cookie close read seek write */
17 /* _ub _extra */
18 +#define __sFXInit {0, PTHREAD_MUTEX_INITIALIZER}
19 + /* set counted */
20 +#define __sFXInit3 {0, PTHREAD_MUTEX_INITIALIZER, 0, 0, 0, 1}
21 /* the usual - (stdin + stdout + stderr) */
22 +
23 +static int __scounted; /* streams counted against STREAM_MAX */
24 +static int __stream_max;
25 +
26 static FILE usual[FOPEN_MAX - 3];
27 static struct __sFILEX usual_extra[FOPEN_MAX - 3];
28 static struct glue uglue = { NULL, FOPEN_MAX - 3, usual };
29
30 -static struct __sFILEX __sFX[3];
31 +static struct __sFILEX __sFX[3] = {__sFXInit3, __sFXInit3, __sFXInit3};
32
33 /*
34 * We can't make this 'static' until 6.0-current due to binary
35 @@ -113,7 +123,7 @@ moreglue(n)
36 {
37 struct glue *g;
38 static FILE empty;
39 - static struct __sFILEX emptyx;
40 + static struct __sFILEX emptyx = __sFXInit;
41 FILE *p;
42 struct __sFILEX *fx;
43
44 @@ -139,7 +149,7 @@ moreglue(n)
45 * Find a free FILE for fopen et al.
46 */
47 FILE *
48 -__sfp()
49 +__sfp(int count)
50 {
51 FILE *fp;
52 int n;
53 @@ -147,6 +157,15 @@ __sfp()
54
55 if (!__sdidinit)
56 __sinit();
57 +
58 + if (count) {
59 + if (__scounted >= __stream_max) {
60 + THREAD_UNLOCK();
61 + errno = EMFILE;
62 + return NULL;
63 + }
64 + OSAtomicIncrement32(&__scounted);
65 + }
66 /*
67 * The list must be locked because a FILE may be updated.
68 */
69 @@ -179,12 +198,27 @@ found:
70 fp->_lb._base = NULL; /* no line buffer */
71 fp->_lb._size = 0;
72 /* fp->_lock = NULL; */ /* once set always set (reused) */
73 + fp->_extra->fl_mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
74 fp->_extra->orientation = 0;
75 + fp->_extra->counted = count ? 1 : 0;
76 memset(&fp->_extra->mbstate, 0, sizeof(mbstate_t));
77 return (fp);
78 }
79
80 /*
81 + * Mark as free and update count as needed
82 + */
83 +__private_extern__ void
84 +__sfprelease(FILE *fp)
85 +{
86 + if (fp->_extra->counted) {
87 + OSAtomicDecrement32(&__scounted);
88 + fp->_extra->counted = 0;
89 + }
90 + fp->_flags = 0;
91 +}
92 +
93 +/*
94 * XXX. Force immediate allocation of internal memory. Not used by stdio,
95 * but documented historically for certain applications. Bad applications.
96 */
97 @@ -244,6 +278,8 @@ __sinit()
98 /* Make sure we clean up on exit. */
99 __cleanup = _cleanup; /* conservative */
100 __sdidinit = 1;
101 + __stream_max = sysconf(_SC_STREAM_MAX);
102 + __scounted = 3; /* std{in,out,err} already exists */
103 }
104 THREAD_UNLOCK();
105 }