1 /* Test that values of pathconf and fpathconf are consistent for a file.
2    Copyright (C) 2013-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 <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <sys/stat.h>
25 
26 
27 static void prepare (void);
28 #define PREPARE(argc, argv) prepare ()
29 
30 static int do_test (void);
31 #define TEST_FUNCTION do_test ()
32 
33 #include "../test-skeleton.c"
34 
35 static int dir_fd;
36 static char *dirbuf;
37 
38 static void
prepare(void)39 prepare (void)
40 {
41   size_t test_dir_len = strlen (test_dir);
42   static const char dir_name[] = "/tst-pathconf.XXXXXX";
43 
44   size_t dirbuflen = test_dir_len + sizeof (dir_name);
45   dirbuf = xmalloc (dirbuflen);
46 
47   snprintf (dirbuf, dirbuflen, "%s%s", test_dir, dir_name);
48   if (mkdtemp (dirbuf) == NULL)
49     {
50       printf ("Cannot create temporary directory: %s\n", strerror (errno));
51       exit (1);
52     }
53 
54   add_temp_file (dirbuf);
55 
56   dir_fd = open (dirbuf, O_RDONLY);
57   if (dir_fd == -1)
58     {
59       printf ("Cannot open directory: %s\n", strerror (errno));
60       exit (1);
61     }
62 }
63 
64 
65 static int
do_test(void)66 do_test (void)
67 {
68   int ret = 0;
69   static const char *fifo_name = "some-fifo";
70 
71   size_t filenamelen = strlen (dirbuf) + strlen (fifo_name) + 2;
72   char *filename = xmalloc (filenamelen);
73 
74   snprintf (filename, filenamelen, "%s/%s", dirbuf, fifo_name);
75 
76   /* Create a fifo in the directory.  */
77   int e = mkfifo (filename, 0777);
78   if (e == -1)
79     {
80       printf ("fifo creation failed (%s)\n", strerror (errno));
81       ret = 1;
82       goto out_nofifo;
83     }
84 
85   long dir_pathconf = pathconf (dirbuf, _PC_PIPE_BUF);
86 
87   if (dir_pathconf < 0)
88     {
89       printf ("pathconf on directory failed: %s\n", strerror (errno));
90       ret = 1;
91       goto out_nofifo;
92     }
93 
94   long fifo_pathconf = pathconf (filename, _PC_PIPE_BUF);
95 
96   if (fifo_pathconf < 0)
97     {
98       printf ("pathconf on file failed: %s\n", strerror (errno));
99       ret = 1;
100       goto out_nofifo;
101     }
102 
103   int fifo = open (filename, O_RDONLY | O_NONBLOCK);
104 
105   if (fifo < 0)
106     {
107       printf ("fifo open failed (%s)\n", strerror (errno));
108       ret = 1;
109       goto out_nofifo;
110     }
111 
112   long dir_fpathconf = fpathconf (dir_fd, _PC_PIPE_BUF);
113 
114   if (dir_fpathconf < 0)
115     {
116       printf ("fpathconf on directory failed: %s\n", strerror (errno));
117       ret = 1;
118       goto out;
119     }
120 
121   long fifo_fpathconf = fpathconf (fifo, _PC_PIPE_BUF);
122 
123   if (fifo_fpathconf < 0)
124     {
125       printf ("fpathconf on file failed: %s\n", strerror (errno));
126       ret = 1;
127       goto out;
128     }
129 
130   if (fifo_pathconf != fifo_fpathconf)
131     {
132       printf ("fifo pathconf (%ld) != fifo fpathconf (%ld)\n", fifo_pathconf,
133 	      fifo_fpathconf);
134       ret = 1;
135       goto out;
136     }
137 
138   if (dir_pathconf != fifo_pathconf)
139     {
140       printf ("directory pathconf (%ld) != fifo pathconf (%ld)\n",
141 	      dir_pathconf, fifo_pathconf);
142       ret = 1;
143       goto out;
144     }
145 
146   if (dir_fpathconf != fifo_fpathconf)
147     {
148       printf ("directory fpathconf (%ld) != fifo fpathconf (%ld)\n",
149 	      dir_fpathconf, fifo_fpathconf);
150       ret = 1;
151       goto out;
152     }
153 
154 out:
155   close (fifo);
156 out_nofifo:
157   close (dir_fd);
158 
159   if (unlink (filename) != 0)
160     {
161       printf ("Could not remove fifo (%s)\n", strerror (errno));
162       ret = 1;
163     }
164 
165   return ret;
166 }
167