Loading...
--- Libc/Libc-1725.40.4/tests/stdio.c
+++ Libc/Libc-1353.11.2/tests/stdio.c
@@ -3,132 +3,64 @@
 #include <errno.h>
 #include <unistd.h>
 #include <sys/resource.h>
-#include <stdlib.h>
-#include <sys/sysctl.h>
 
 #include <darwintest.h>
 
-#define FILE_LIMIT 15
+#define FILE_LIMIT 100
 
-/*
- * Validate the maximum number of fds allowed open per process
- * implemented by the kernel matches what sysconf expects:
- *  32 bit: OPEN_MAX
- *  64 bit: RLIM_INFINITY
- */
-T_DECL(stdio_PR_63187147_SC_STREAM_MAX, "_SC_STREAM_MAX test")
+T_DECL(stdio_PR_22813396, "STREAM_MAX is affected by changes to RLIMIT_NOFILE")
 {
-	struct rlimit rlim;
-	long stream_max, saved_stream_max;
-	int maxfilesperproc, err;
-	size_t maxfilesperproc_size = sizeof(maxfilesperproc);
+	struct rlimit theLimit;
+	getrlimit( RLIMIT_NOFILE, &theLimit );
+	theLimit.rlim_cur = FILE_LIMIT;
+	setrlimit( RLIMIT_NOFILE, &theLimit );
 
-	T_SETUPBEGIN;
+	long stream_max = sysconf(_SC_STREAM_MAX);
+	T_EXPECT_EQ_LONG(stream_max, (long)FILE_LIMIT, "stream_max = FILE_LIMIT");
 
-	saved_stream_max = sysconf(_SC_STREAM_MAX);
-	T_LOG("Initial stream_max %ld", saved_stream_max);
+	FILE *f;
+	for(int i = 3; i < stream_max; i++) {
+		if((f = fdopen(0, "r")) == NULL) {
+			T_FAIL("Failed after %d streams", i);
+		}
+	}
 
-	/*
-	 * Determine the maximum number of fds allowed by the kernel
-	 */
-	err = sysctlbyname("kern.maxfilesperproc", &maxfilesperproc, &maxfilesperproc_size, NULL, 0);
-	T_EXPECT_POSIX_SUCCESS(err, "sysctlbyname(\"kern.maxfilesperproc\") returned %d", err);
-	T_LOG("kern.maxfilesperproc %d", maxfilesperproc);
+	f = fdopen(0, "r");
+	T_EXPECT_NULL(f, "fdopen fail after stream_max streams");
 
-	/*
-	 * Raise RLIMIT_NOFILE to RLIM_INFINITY
-	 */
-	err = getrlimit(RLIMIT_NOFILE, &rlim);
-	T_EXPECT_POSIX_SUCCESS(err, "getrlimit(RLIMIT_NOFILE)");
-	T_LOG("Initial RLIMIT_NOFILE rlim.cur: 0x%llx", rlim.rlim_cur);
-	rlim.rlim_cur = RLIM_INFINITY;
-	err = setrlimit(RLIMIT_NOFILE, &rlim);
-	T_EXPECT_POSIX_SUCCESS(err, "setrlimit(RLIMIT_NOFILE) to RLIM_INFINITY");
-	err = getrlimit(RLIMIT_NOFILE, &rlim);
-	T_EXPECT_POSIX_SUCCESS(err, "New RLIMIT_NOFILE rlim_cur: 0x%llx", rlim.rlim_cur);
+	theLimit.rlim_cur = FILE_LIMIT + 1;
+	setrlimit( RLIMIT_NOFILE, &theLimit );
 
-	T_SETUPEND;
-
-	/*
-	 * The largest value sysconf returns for _SC_STREAM_MAX is
-	 * OPEN_MAX (32 bit) or RLIM_INFINITY (64 bit)
-	 */
-	stream_max = sysconf(_SC_STREAM_MAX);
-	T_EXPECT_NE_LONG((long)-1, stream_max, "stream_max %ld", stream_max);
-#if __LP64__
-	T_EXPECT_EQ((long)RLIM_INFINITY, stream_max, "sysconf returned 0x%lx", stream_max);
-#else
-	T_EXPECT_EQ((long)OPEN_MAX, stream_max, "sysconf returned 0x%lx", stream_max);
-#endif
+	f = fdopen(0, "r");
+	T_EXPECT_NOTNULL(f, "fdopen succeed after RLIMIT_NOFILE increased");
 }
 
-/*
- * Verify that a) {STREAM_MAX} reflects RLIMIT_NOFILE, b) we cannot open
- * more than {STREAM_MAX} streams (taking into account the pre-existing
- * stdin, stdout, stderr) and c) raising RLIMIT_NOFILE after hitting the
- * limit immediately lets us open additional streams up to the new limit.
- */
-T_DECL(stdio_PR_22813396, "STREAM_MAX is affected by changes to RLIMIT_NOFILE")
+T_DECL(stdio_PR_22813396_close, "STREAM_MAX is enforced properly after fclose")
 {
-	struct rlimit rlim;
-	long i, stream_max;
+	struct rlimit theLimit;
+	getrlimit( RLIMIT_NOFILE, &theLimit );
+	theLimit.rlim_cur = FILE_LIMIT;
+	setrlimit( RLIMIT_NOFILE, &theLimit );
+
+	long stream_max = sysconf(_SC_STREAM_MAX);
+	T_EXPECT_EQ_LONG(stream_max, (long)FILE_LIMIT, "stream_max = FILE_LIMIT");
+
 	FILE *f;
+	for(int i = 3; i < stream_max - 1; i++) {
+		if((f = fdopen(0, "r")) == NULL) {
+			T_FAIL("Failed after %d streams", i);
+		}
+	}
 
-	T_SETUPBEGIN;
-	T_ASSERT_POSIX_NOTNULL(f = fdopen(dup(0), "r"), "opening initial stream");
-	T_ASSERT_POSIX_ZERO(getrlimit(RLIMIT_NOFILE, &rlim), "getting file limit");
-	T_ASSERT_POSIX_SUCCESS(stream_max = sysconf(_SC_STREAM_MAX),
-	    "getting stream limit");
-	T_ASSERT_EQ_ULLONG((unsigned long long)stream_max, rlim.rlim_cur,
-	    "stream limit equals file limit");
-	rlim.rlim_cur = FILE_LIMIT;
-	T_ASSERT_POSIX_ZERO(setrlimit(RLIMIT_NOFILE, &rlim), "setting file limit");
-	T_ASSERT_POSIX_SUCCESS(stream_max = sysconf(_SC_STREAM_MAX),
-	    "refreshing stream limit");
-	T_ASSERT_EQ_LONG(stream_max, (long)FILE_LIMIT,
-	    "stream limit equals file limit");
-	T_SETUPEND;
-	for (i = 4; i < stream_max; i++)
-		T_EXPECT_POSIX_NOTNULL(fdopen(0, "r"), "opening stream within limit");
-	T_EXPECT_NULL(fdopen(0, "r"), "opening stream beyond limit");
-	T_SETUPBEGIN;
-	rlim.rlim_cur = FILE_LIMIT + 1;
-	T_ASSERT_POSIX_ZERO(setrlimit(RLIMIT_NOFILE, &rlim), "raising file limit");
-	T_SETUPEND;
-	T_EXPECT_POSIX_NOTNULL(fdopen(0, "r"), "opening stream after raising limit");
-	T_EXPECT_NULL(fdopen(0, "r"), "opening stream beyond raised limit");
+	// the last stream is for dup(0), it needs to be fclose'd
+	FILE *dupf = NULL;
+	T_EXPECT_NOTNULL(dupf = fdopen(dup(0), "r"), NULL);
+
+	T_EXPECT_NULL(f = fdopen(0, "r"), "fdopen fail after stream_max streams");
+
+	T_EXPECT_POSIX_ZERO(fclose(dupf), "fclose succeeds");
+
+	f = fdopen(0, "r");
+	T_WITH_ERRNO; T_EXPECT_NOTNULL(f, "fdopen succeed after fclose");
 }
 
-/*
- * Verify that a) {STREAM_MAX} reflects RLIMIT_NOFILE, b) we cannot open
- * more than {STREAM_MAX} streams (taking into account the pre-existing
- * stdin, stdout, stderr) and c) closing a stream after hitting the limit
- * immediately lets us open exactly one other.
- */
-T_DECL(stdio_PR_22813396_close, "STREAM_MAX is enforced properly after fclose")
-{
-	struct rlimit rlim;
-	long i, stream_max;
-	FILE *f;
-
-	T_SETUPBEGIN;
-	T_ASSERT_POSIX_NOTNULL(f = fdopen(dup(0), "r"), "opening initial stream");
-	T_ASSERT_POSIX_ZERO(getrlimit(RLIMIT_NOFILE, &rlim), "getting file limit");
-	T_ASSERT_POSIX_SUCCESS(stream_max = sysconf(_SC_STREAM_MAX),
-	    "getting stream limit");
-	T_ASSERT_EQ_ULLONG((unsigned long long)stream_max, rlim.rlim_cur,
-	    "stream limit equals file limit");
-	rlim.rlim_cur = FILE_LIMIT;
-	T_ASSERT_POSIX_ZERO(setrlimit(RLIMIT_NOFILE, &rlim), "setting file limit");
-	T_ASSERT_POSIX_SUCCESS(stream_max = sysconf(_SC_STREAM_MAX),
-	    "refreshing stream limit");
-	T_ASSERT_EQ_LONG(stream_max, (long)FILE_LIMIT,
-	    "stream limit equals file limit");
-	T_SETUPEND;
-	for (i = 4; i < stream_max; i++)
-		T_EXPECT_POSIX_NOTNULL(fdopen(0, "r"), "opening stream within limit");
-	T_EXPECT_NULL(fdopen(0, "r"), "opening stream beyond limit");
-	T_EXPECT_POSIX_ZERO(fclose(f), "closing a stream");
-	T_EXPECT_POSIX_NOTNULL(fdopen(0, "r"), "opening stream after closing another");
-	T_EXPECT_NULL(fdopen(0, "r"), "opening second stream after closing only one");
-}