1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) International Business Machines Corp., 2002
4 * Ported from SPIE, section2/iosuite/dup1.c, by Airong Zhang
5 * Copyright (c) 2013 Cyril Hrubis <[email protected]>
6 * Copyright (c) Linux Test Project, 2003-2024
7 */
8
9 /*\
10 * [Description]
11 *
12 * Test for dup(2) syscall with max open file descriptors.
13 */
14
15 #include <stdlib.h>
16 #include "tst_test.h"
17
18 static int *pfildes;
19 static int minfd, maxfd, freefds;
20 static char pfilname[40];
21
cnt_free_fds(int maxfd)22 static int cnt_free_fds(int maxfd)
23 {
24 int freefds = 0;
25
26 for (maxfd--; maxfd >= 0; maxfd--)
27 if (fcntl(maxfd, F_GETFD) == -1 && errno == EBADF)
28 freefds++;
29
30 return freefds;
31 }
32
setup(void)33 static void setup(void)
34 {
35 minfd = getdtablesize(); /* get number of files allowed open */
36 maxfd = minfd + 5;
37 freefds = cnt_free_fds(minfd);
38 pfildes = SAFE_MALLOC(maxfd * sizeof(int));
39 memset(pfildes, -1, maxfd * sizeof(int));
40 sprintf(pfilname, "./dup06.%d\n", getpid());
41 }
42
cleanup(void)43 static void cleanup(void)
44 {
45 if (pfildes != NULL)
46 free(pfildes);
47 }
48
run(void)49 static void run(void)
50 {
51 int i;
52
53 pfildes[0] = SAFE_CREAT(pfilname, 0666);
54 for (i = 1; i < maxfd; i++) {
55 pfildes[i] = dup(pfildes[i - 1]);
56 if (pfildes[i] == -1)
57 break;
58 }
59 if (i < freefds)
60 tst_res(TFAIL, "Not enough files duped");
61 else if (i > freefds)
62 tst_res(TFAIL, "Too many files duped");
63 else
64 tst_res(TPASS, "Test passed");
65
66 SAFE_UNLINK(pfilname);
67
68 for (i = 0; i < maxfd; i++) {
69 if (pfildes[i] != 0 && pfildes[i] != -1)
70 SAFE_CLOSE(pfildes[i]);
71 }
72 }
73
74 static struct tst_test test = {
75 .needs_tmpdir = 1,
76 .test_all = run,
77 .setup = setup,
78 .cleanup = cleanup,
79 };
80