1 | /* Test for /proc/self/fd (or /dev/fd) pathname construction. |
2 | Copyright (C) 2020-2022 Free Software Foundation, Inc. |
3 | This file is part of the GNU C Library. |
4 | |
5 | The GNU C Library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2.1 of the License, or (at your option) any later version. |
9 | |
10 | The GNU C Library 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 the GNU |
13 | Lesser General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, see |
17 | <https://www.gnu.org/licenses/>. */ |
18 | |
19 | #include <fcntl.h> |
20 | #include <fd_to_filename.h> |
21 | #include <stdio.h> |
22 | #include <support/check.h> |
23 | #include <support/xunistd.h> |
24 | |
25 | /* Run a check on one value. */ |
26 | static void |
27 | check (int value) |
28 | { |
29 | if (value < 0) |
30 | /* Negative descriptor values violate the precondition. */ |
31 | return; |
32 | |
33 | struct fd_to_filename storage; |
34 | char *actual = __fd_to_filename (descriptor: value, storage: &storage); |
35 | char expected[100]; |
36 | snprintf (s: expected, maxlen: sizeof (expected), FD_TO_FILENAME_PREFIX "%d" , value); |
37 | TEST_COMPARE_STRING (actual, expected); |
38 | } |
39 | |
40 | /* Check various ranges constructed around powers. */ |
41 | static void |
42 | check_ranges (int base) |
43 | { |
44 | unsigned int power = 1; |
45 | do |
46 | { |
47 | for (int factor = 1; factor < base; ++factor) |
48 | for (int shift = -1000; shift <= 1000; ++shift) |
49 | check (value: factor * power + shift); |
50 | } |
51 | while (!__builtin_mul_overflow (power, base, &power)); |
52 | } |
53 | |
54 | /* Check that it is actually possible to use a the constructed |
55 | name. */ |
56 | static void |
57 | check_open (void) |
58 | { |
59 | int pipes[2]; |
60 | xpipe (pipes); |
61 | |
62 | struct fd_to_filename storage; |
63 | int read_alias = xopen (path: __fd_to_filename (descriptor: pipes[0], storage: &storage), O_RDONLY, 0); |
64 | int write_alias = xopen (path: __fd_to_filename (descriptor: pipes[1], storage: &storage), O_WRONLY, 0); |
65 | |
66 | /* Ensure that all the descriptor numbers are different. */ |
67 | TEST_VERIFY (pipes[0] < pipes[1]); |
68 | TEST_VERIFY (pipes[1] < read_alias); |
69 | TEST_VERIFY (read_alias < write_alias); |
70 | |
71 | xwrite (write_alias, "1" , 1); |
72 | char buf[16]; |
73 | TEST_COMPARE_BLOB ("1" , 1, buf, read (pipes[0], buf, sizeof (buf))); |
74 | |
75 | xwrite (pipes[1], "2" , 1); |
76 | TEST_COMPARE_BLOB ("2" , 1, buf, read (read_alias, buf, sizeof (buf))); |
77 | |
78 | xwrite (write_alias, "3" , 1); |
79 | TEST_COMPARE_BLOB ("3" , 1, buf, read (read_alias, buf, sizeof (buf))); |
80 | |
81 | xwrite (pipes[1], "4" , 1); |
82 | TEST_COMPARE_BLOB ("4" , 1, buf, read (pipes[0], buf, sizeof (buf))); |
83 | |
84 | xclose (write_alias); |
85 | xclose (read_alias); |
86 | xclose (pipes[1]); |
87 | xclose (pipes[0]); |
88 | } |
89 | |
90 | static int |
91 | do_test (void) |
92 | { |
93 | check_ranges (base: 2); |
94 | check_ranges (base: 10); |
95 | |
96 | check_open (); |
97 | |
98 | return 0; |
99 | } |
100 | |
101 | #include <support/test-driver.c> |
102 | |