* 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 */
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 */
/* 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};
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
#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;
pthread_once(&__sdidinit, __sinit);
if (count) {
- if (__scounted >= __stream_max) {
- if (__scounted >= (__stream_max = sysconf(_SC_STREAM_MAX))){
+ 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;
}
}
- OSAtomicIncrement32(&__scounted);
+ /* Overflowing #streams beyond RLIMIT_INFINITY */
+ if (new < 0) {
+ errno = EOVERFLOW;
+ return NULL;
+ }
}
/*
* The list must be locked because a FILE may be updated.
__sfprelease(FILE *fp)
{
if (fp->_counted) {
- OSAtomicDecrement32(&__scounted);
+ OSAtomicDecrement64(&__scounted);
fp->_counted = 0;
}
* The name `_cleanup' is, alas, fairly well known outside stdio.
*/
void
-_cleanup()
+_cleanup(void)
{
/* (void) _fwalk(fclose); */
(void) _fwalk(__sflush); /* `cheating' */
* __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
__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];
}
#endif
}
+#pragma clang diagnostic pop