1/*
2 * Copyright (c) International Business Machines  Corp., 2001
3 *  07/2001 Ported by Wayne Boyer
4 *
5 * This program is free software;  you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY;  without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program;  if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20/*
21 * Testcase to check that creat(2) system call returns EMFILE.
22 */
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <errno.h>
27#include <sys/types.h>
28#include <sys/time.h>
29#include <sys/resource.h>
30#include <sys/stat.h>
31#include <fcntl.h>
32#include <linux/limits.h>
33#include <unistd.h>
34#include "tst_test.h"
35
36static int *opened_fds, num_opened_fds;
37
38static void verify_creat(void)
39{
40	TEST(creat("filename", 0666));
41
42	if (TEST_RETURN != -1) {
43		tst_res(TFAIL, "call succeeded unexpectedly");
44		SAFE_CLOSE(TEST_RETURN);
45		return;
46	}
47
48	if (TEST_ERRNO == EMFILE)
49		tst_res(TPASS, "creat() failed with EMFILE");
50	else
51		tst_res(TFAIL | TTERRNO, "Expected EMFILE");
52}
53
54static void setup(void)
55{
56	int max_open;
57	int fd;
58	char fname[PATH_MAX];
59
60	/* get the maximum number of files that we can open */
61	max_open = getdtablesize();
62	tst_res(TINFO, "getdtablesize() = %d", max_open);
63	opened_fds = SAFE_MALLOC(max_open * sizeof(int));
64
65	/* now open as many files as we can up to max_open */
66	do {
67		snprintf(fname, sizeof(fname), "creat05_%d", num_opened_fds);
68		fd = SAFE_CREAT(fname, 0666);
69		opened_fds[num_opened_fds++] = fd;
70	} while (fd < max_open - 1);
71
72	tst_res(TINFO, "Opened additional #%d fds", num_opened_fds);
73}
74
75static void cleanup(void)
76{
77	int i;
78
79	for (i = 0; i < num_opened_fds; i++) {
80		if (close(opened_fds[i])) {
81			tst_res(TWARN | TERRNO, "close(%i) failed",
82				opened_fds[i]);
83		}
84	}
85
86	free(opened_fds);
87}
88
89static struct tst_test test = {
90	.tid = "creat05",
91	.test_all = verify_creat,
92	.needs_tmpdir = 1,
93	.setup = setup,
94	.cleanup = cleanup,
95};
96