[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[MiNT] Ammount of file descriptors per process



Hell

I've written a small test program. Small one, so I attached it to this mail.

It opens as much as possible files (at once) depending on information he can get.

The aim was to test both MiNTLib and the kernel.

There are 3 tests in this file:
1. Opening files using library call fopen(), the maximum ammount of files it tries to open is taken from FOPEN_MAX library constant.

2. Opening files using library call open(), the maximum ammount of files it tries to open is taken from RLIMIT_NOFILE library constant.

3. Opening (creating) files using system call Fcreate(), the maximum ammount of files it tries to open is taken from Sysconf(SYS_MAXFILES) system call.

And now the tests result.

Ad 1. FOPEN_MAX is 255, but the test fails whe there are 26 files opened.

Ad 2. RLIMIT_NOFILE is 6. Test passes.

Ad 3. Sysconf(SYS_MAXFILES) returns 32. Test fails after opening 26 files.

Conclusions:

At the beginning _process_that_does_nothing_ has 9 file descriptors opened (according to /kerm/*/fd). If 32 is a maximum ammount of file descriptors per process, then 26 + 9 = 35, so there is something wrong here.

On the other hand FOPEN_MAX is wrong, and can lead to hard to trace errors in ported software.

Or, if I'm wrong please correct me.

For everyone that would like to try it at home: test program assumes that there is a 'tmp' directory in CWD, wher it does its job. I take no other responsibility.

--
Semper Fidelis

Adam Klobukowski
atari@gabo.pl
/*
 * FreeMiNT Test Suite
 *
 * 1000000 Opened files test
 */
 
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/resource.h>
#include <osbind.h>
#include <mintbind.h>
#include <mint\sysctl.h>

void
remove_files(int count)
{
	int a, ret;
	char fname[FILENAME_MAX];

	for (a=0;a<count;a++)
	{
		sprintf(fname,"tmp/%10d",a);

		printf("Removing file %d ",a);

		ret = remove(fname);

		if (ret == 0) printf ("succes!\n");
		else
		{
			printf("failed! return value: %d errno: %d strerror(errno): %s\n", ret, errno, strerror(errno));
			break;
		}
	}
}

void
test1()
{
	FILE* f[FOPEN_MAX];
	int a, b;
	char fname[FILENAME_MAX];

	printf("Test 1. fopen(), FOPEN_MAX: %d\n", FOPEN_MAX);

	for (a=0;a<FOPEN_MAX;a++)
	{
		sprintf(fname,"tmp/%10d",a);

		printf("Opening file %d ", a);
		fflush(NULL);

		f[a] = fopen(fname, "w");

		if (f[a]) printf ("succes!\n");
		else
		{
			printf("failed! ferror: %d errno: %d strerror(errno): %s\n", ferror(f[a]), errno, strerror(errno));
			break;
		}

		fflush(NULL);
	}

	for (b=0;b<a;b++)
	{
		int ret;

		sprintf(fname,"tmp/%10d",b);

		printf("Closing file %d ", b);
		fflush(NULL);

		ret = fclose(f[b]);

		if(ret == 0) printf ("succes!\n");
		else
		{
			printf("failed! ferror: %d errno: %d strerror(errno): %s\n", ferror(f[b]), errno, strerror(errno));
			break;
		}

		fflush(NULL);
	}

	remove_files(a);
}

void
test2()
{
	int f[RLIMIT_NOFILE];
	int a, b;
	char fname[FILENAME_MAX];

	printf("Test 2. open(), RLIMIT_NOFILE: %d\n", RLIMIT_NOFILE);

	for (a=0;a<RLIMIT_NOFILE;a++)
	{
		sprintf(fname,"tmp/%10d",a);

		printf("Opening file %d ", a);
		fflush(NULL);

		f[a] = open(fname, O_WRONLY | O_CREAT);

		if (f[a] != -1) printf ("succes!\n");
		else
		{
			printf("failed! errno: %d strerror(errno): %s\n", errno, strerror(errno));
			break;
		}

		fflush(NULL);
	}

	for (b=0;b<a;b++)
	{
		int ret;

		sprintf(fname,"tmp/%10d",b);

		printf("Closing file %d ", b);
		fflush(NULL);

		ret = close(f[b]);

		if(ret != -1) printf ("succes!\n");
		else printf("failed! errno: %d strerror(errno): %s\n", errno, strerror(errno));

		fflush(NULL);
	}

	remove_files(a);	
}

void
test3()
{
	long int max_files;
	int * f;
	int a, b;

	char fname[FILENAME_MAX];

	max_files = Sysconf(2 /*SYS_MAXFILES*/);
	
	f = (int*)malloc(sizeof(long int) * max_files);
	
	printf("Test 3. Syscals, Sysconf(KERN_MAXFILES): %d\n", max_files);

	for (a=0;a<max_files;a++)
	{
		sprintf(fname,"tmp/%10d",a);

		printf("Opening file %d ", a);
		fflush(NULL);

		f[a] = Fcreate(fname, 0);

		if (f[a] > 0) printf ("succes!\n");
		else
		{
			printf("failed! return value: %d strerror(return value): %s\n", f[a], strerror(f[a]));
			break;
		}

		fflush(NULL);
	}

	for (b=0;b<a;b++)
	{
		int ret;

		sprintf(fname,"tmp/%10d",b);

		printf("Closing file %d ", b);
		fflush(NULL);

		ret = Fclose(f[b]);

		if(ret == 0) printf ("succes!\n");
		else printf("failed! return value: %d strerror(return value): %s\n", f[a], strerror(f[a]));

		fflush(NULL);
	}

	remove_files(a);

}

int
main()
{
//	test1();
//	test2();
	test3();

	return 0;
}