]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/unix/sysv/linux/pathconf.c
Better use of open in pathconf.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / pathconf.c
1 /* Get file-specific information about a file. Linux version.
2 Copyright (C) 1991,1995,1996,1998-2003,2008,2010,2011 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, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
19
20 #include <unistd.h>
21 #include <errno.h>
22
23 #include "pathconf.h"
24 #include "linux_fsinfo.h"
25 #include <not-cancel.h>
26
27 static long int posix_pathconf (const char *file, int name);
28
29 /* Define this first, so it can be inlined. */
30 #define __pathconf static posix_pathconf
31 #include <sysdeps/posix/pathconf.c>
32
33
34 /* Get file-specific information about FILE. */
35 long int
36 __pathconf (const char *file, int name)
37 {
38 struct statfs fsbuf;
39 int fd;
40 int flags;
41
42 switch (name)
43 {
44 case _PC_LINK_MAX:
45 return __statfs_link_max (__statfs (file, &fsbuf), &fsbuf);
46
47 case _PC_FILESIZEBITS:
48 return __statfs_filesize_max (__statfs (file, &fsbuf), &fsbuf);
49
50 case _PC_2_SYMLINKS:
51 return __statfs_symlinks (__statfs (file, &fsbuf), &fsbuf);
52
53 case _PC_CHOWN_RESTRICTED:
54 return __statfs_chown_restricted (__statfs (file, &fsbuf), &fsbuf);
55
56 case _PC_PIPE_BUF:
57 flags = O_RDONLY|O_NONBLOCK|O_NOCTTY;
58 #ifdef O_CLOEXEC
59 flags |= O_CLOEXEC;
60 #endif
61 fd = open_not_cancel_2 (file, flags);
62 if (fd >= 0)
63 {
64 long int r = __fcntl (fd, F_GETPIPE_SZ);
65 close_not_cancel_no_status (fd);
66 if (r > 0)
67 return r;
68 }
69 /* FALLTHROUGH */
70
71 default:
72 return posix_pathconf (file, name);
73 }
74 }
75
76
77 /* Used like: return statfs_link_max (__statfs (name, &buf), &buf); */
78 long int
79 __statfs_link_max (int result, const struct statfs *fsbuf)
80 {
81 if (result < 0)
82 {
83 if (errno == ENOSYS)
84 /* Not possible, return the default value. */
85 return LINUX_LINK_MAX;
86
87 /* Some error occured. */
88 return -1;
89 }
90
91 switch (fsbuf->f_type)
92 {
93 case EXT2_SUPER_MAGIC:
94 return EXT2_LINK_MAX;
95
96 case MINIX_SUPER_MAGIC:
97 case MINIX_SUPER_MAGIC2:
98 return MINIX_LINK_MAX;
99
100 case MINIX2_SUPER_MAGIC:
101 case MINIX2_SUPER_MAGIC2:
102 return MINIX2_LINK_MAX;
103
104 case XENIX_SUPER_MAGIC:
105 return XENIX_LINK_MAX;
106
107 case SYSV4_SUPER_MAGIC:
108 case SYSV2_SUPER_MAGIC:
109 return SYSV_LINK_MAX;
110
111 case COH_SUPER_MAGIC:
112 return COH_LINK_MAX;
113
114 case UFS_MAGIC:
115 case UFS_CIGAM:
116 return UFS_LINK_MAX;
117
118 case REISERFS_SUPER_MAGIC:
119 return REISERFS_LINK_MAX;
120
121 case XFS_SUPER_MAGIC:
122 return XFS_LINK_MAX;
123
124 default:
125 return LINUX_LINK_MAX;
126 }
127 }
128
129
130 /* Used like: return statfs_filesize_max (__statfs (name, &buf), &buf); */
131 long int
132 __statfs_filesize_max (int result, const struct statfs *fsbuf)
133 {
134 if (result < 0)
135 {
136 if (errno == ENOSYS)
137 /* Not possible, return the default value. */
138 return 32;
139
140 /* Some error occured. */
141 return -1;
142 }
143
144 switch (fsbuf->f_type)
145 {
146 case BTRFS_SUPER_MAGIC:
147 return 255;
148
149 case EXT2_SUPER_MAGIC:
150 case UFS_MAGIC:
151 case UFS_CIGAM:
152 case REISERFS_SUPER_MAGIC:
153 case XFS_SUPER_MAGIC:
154 case SMB_SUPER_MAGIC:
155 case NTFS_SUPER_MAGIC:
156 case UDF_SUPER_MAGIC:
157 case JFS_SUPER_MAGIC:
158 case VXFS_SUPER_MAGIC:
159 case CGROUP_SUPER_MAGIC:
160 return 64;
161
162 case MSDOS_SUPER_MAGIC:
163 case JFFS_SUPER_MAGIC:
164 case JFFS2_SUPER_MAGIC:
165 case NCP_SUPER_MAGIC:
166 case ROMFS_SUPER_MAGIC:
167 return 32;
168
169 default:
170 return 32;
171 }
172 }
173
174
175 /* Used like: return statfs_link_max (__statfs (name, &buf), &buf); */
176 long int
177 __statfs_symlinks (int result, const struct statfs *fsbuf)
178 {
179 if (result < 0)
180 {
181 if (errno == ENOSYS)
182 /* Not possible, return the default value. */
183 return 1;
184
185 /* Some error occured. */
186 return -1;
187 }
188
189 switch (fsbuf->f_type)
190 {
191 case ADFS_SUPER_MAGIC:
192 case BFS_MAGIC:
193 case CRAMFS_MAGIC:
194 case DEVPTS_SUPER_MAGIC:
195 case EFS_SUPER_MAGIC:
196 case EFS_MAGIC:
197 case MSDOS_SUPER_MAGIC:
198 case NTFS_SUPER_MAGIC:
199 case QNX4_SUPER_MAGIC:
200 case ROMFS_SUPER_MAGIC:
201 /* No symlink support. */
202 return 0;
203
204 default:
205 return 1;
206 }
207 }
208
209
210 /* Used like: return __statfs_chown_restricted (__statfs (name, &buf), &buf);*/
211 long int
212 __statfs_chown_restricted (int result, const struct statfs *fsbuf)
213 {
214 if (result < 0)
215 {
216 if (errno == ENOSYS)
217 /* Not possible, return the default value. */
218 return 1;
219
220 /* Some error occured. */
221 return -1;
222 }
223
224 int fd;
225 long int retval = 1;
226 switch (fsbuf->f_type)
227 {
228 case XFS_SUPER_MAGIC:
229 /* Read the value from /proc/sys/fs/xfs/restrict_chown. If we cannot
230 read it default to assume the restriction is in place. */
231 fd = open_not_cancel_2 ("/proc/sys/fs/xfs/restrict_chown", O_RDONLY);
232 if (fd != -1)
233 {
234 char buf[2];
235 if (TEMP_FAILURE_RETRY (read_not_cancel (fd, buf, 2)) == 2
236 && buf[0] >= '0' && buf[0] <= '1')
237 retval = buf[0] - '0';
238
239 close_not_cancel_no_status (fd);
240 }
241 break;
242
243 default:
244 break;
245 }
246
247 return retval;
248 }