]> git.saurik.com Git - apple/libc.git/blobdiff - stdio/FreeBSD/findfp.c
Libc-1439.100.3.tar.gz
[apple/libc.git] / stdio / FreeBSD / findfp.c
index 2d87d6603c4fe3b1f2489dde7de96685c0c3d550..233ca39d01147719c6782cd8ed4cb1afad74c914 100644 (file)
@@ -30,6 +30,9 @@
  * SUCH DAMAGE.
  */
 
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wcomma"
+
 #if defined(LIBC_SCCS) && !defined(lint)
 static char sccsid[] = "@(#)findfp.c   8.2 (Berkeley) 1/4/94";
 #endif /* LIBC_SCCS and not lint */
@@ -56,7 +59,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/findfp.c,v 1.34 2009/12/05 19:31:38 ed Ex
 
 pthread_once_t __sdidinit;
 
-#if !TARGET_OS_EMBEDDED
+#if !TARGET_OS_IPHONE
 #define        NDYNAMIC 10             /* add ten more whenever necessary */
 #else
 #define        NDYNAMIC 1              /* add one at a time on embedded */
@@ -75,17 +78,17 @@ pthread_once_t      __sdidinit;
   /* set counted */
 #define __sFXInit3      {.fl_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER, .counted = 1}
 
-static int __scounted;         /* streams counted against STREAM_MAX */
-static int __stream_max;
+static int64_t __scounted;             /* streams counted against STREAM_MAX */
+static int64_t __stream_max;
 
-#if !TARGET_OS_EMBEDDED
+#if !(TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
 /* usual and usual_extra are data pigs. See 7929728. For embedded we should
  * always allocate dynamically, and probably should for desktop too. */
                                /* the usual - (stdin + stdout + stderr) */
 static FILE usual[FOPEN_MAX - 3];
 static struct __sFILEX usual_extra[FOPEN_MAX - 3];
 static struct glue uglue = { NULL, FOPEN_MAX - 3, usual };
-#endif /* !TARGET_OS_EMBEDDED */
+#endif /* !(TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR) */
 
 static struct __sFILEX __sFX[3] = {__sFXInit3, __sFXInit3, __sFXInit3};
 
@@ -104,7 +107,7 @@ FILE *__stdinp = &__sF[0];
 FILE *__stdoutp = &__sF[1];
 FILE *__stderrp = &__sF[2];
 
-#if !TARGET_OS_EMBEDDED
+#if !(TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
 struct glue __sglue = { &uglue, 3, __sF };
 static struct glue *lastglue = &uglue;
 #else
@@ -119,18 +122,19 @@ static pthread_mutex_t filelist_lock = PTHREAD_MUTEX_INITIALIZER;
 #define FILELIST_UNLOCK()      do { pthread_mutex_unlock(&filelist_lock); } while(0)
 
 static struct glue *
-moreglue(n)
-       int n;
+moreglue(int n)
 {
        struct glue *g;
        FILE *p;
        struct __sFILEX *fx;
+       size_t align;
 
-       g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE) +
+       align = __alignof__( (struct { FILE f; struct __sFILEX s; }){} );
+       g = (struct glue *)malloc(sizeof(*g) + align + n * sizeof(FILE) +
            n * sizeof(struct __sFILEX));
        if (g == NULL)
                return (NULL);
-       p = (FILE *)ALIGN(g + 1);
+       p = (FILE *)roundup((uintptr_t)(g + 1), align);
        fx = (struct __sFILEX *)&p[n];
        g->next = NULL;
        g->niobs = n;
@@ -158,11 +162,20 @@ __sfp(int count)
        pthread_once(&__sdidinit, __sinit);
 
        if (count) {
-               if (__scounted >= __stream_max) {
-                       errno = EMFILE;
+               int64_t new = OSAtomicIncrement64(&__scounted);
+               if (new > __stream_max) {
+                       /* Greater than the saved limit, check again with getrlimit. */
+                       if (new > (__stream_max = sysconf(_SC_STREAM_MAX))){
+                               OSAtomicDecrement64(&__scounted);
+                               errno = EMFILE;
+                               return NULL;
+                       }
+               }
+               /* Overflowing #streams beyond RLIMIT_INFINITY */
+               if (new < 0) {
+                       errno = EOVERFLOW;
                        return NULL;
                }
-               OSAtomicIncrement32(&__scounted);
        }
        /*
         * The list must be locked because a FILE may be updated.
@@ -210,7 +223,7 @@ __private_extern__ void
 __sfprelease(FILE *fp)
 {
        if (fp->_counted) {
-               OSAtomicDecrement32(&__scounted);
+               OSAtomicDecrement64(&__scounted);
                fp->_counted = 0;
        }
        
@@ -259,7 +272,7 @@ f_prealloc(void)
  * The name `_cleanup' is, alas, fairly well known outside stdio.
  */
 void
-_cleanup()
+_cleanup(void)
 {
        /* (void) _fwalk(fclose); */
        (void) _fwalk(__sflush);                /* `cheating' */
@@ -269,9 +282,9 @@ _cleanup()
  * __sinit() is called whenever stdio's internal variables must be set up.
  */
 void
-__sinit()
+__sinit(void)
 {
-#if !TARGET_OS_EMBEDDED
+#if !(TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
        int i;
 #endif
 
@@ -280,7 +293,7 @@ __sinit()
        __stream_max = sysconf(_SC_STREAM_MAX);
        __scounted = 3;                 /* std{in,out,err} already exists */
 
-#if !TARGET_OS_EMBEDDED
+#if !(TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
        /* Set _extra for the usual suspects. */
        for (i = 0; i < FOPEN_MAX - 3; i++) {
                usual[i]._extra = &usual_extra[i];
@@ -288,3 +301,4 @@ __sinit()
        }
 #endif
 }
+#pragma clang diagnostic pop