1 /* fpathconf -- adjusted for busybox
2    Copyright (C) 1991,95,96,98,99,2000,2001 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    <http://www.gnu.org/licenses/>.  */
18 
19 #include <errno.h>
20 #include <unistd.h>
21 #include <limits.h>
22 #include <stddef.h>
23 #include <fcntl.h>
24 #include <sys/stat.h>
25 #include <sys/statfs.h>
26 
27 #define STAT stat64
28 #define FSTAT fstat64
29 
30 #ifndef __USE_FILE_OFFSET64
31 extern int fstatfs (int __fildes, struct statfs *__buf)
32      __THROW __nonnull ((2));
33 #else
34 # ifdef __REDIRECT_NTH
35 	 extern int __REDIRECT_NTH (fstatfs, (int __fildes, struct statfs *__buf),
36 	                            fstatfs64) __nonnull ((2));
37 # else
38 #  define fstatfs fstatfs64
39 # endif
40 #endif
41 
42 extern __typeof(fstatfs) __libc_fstatfs;
43 
44 /* The Linux kernel headers mention this as a kind of generic value.  */
45 #define LINUX_LINK_MAX	127
46 
47 
48 /* Get file-specific information about descriptor FD.  */
fpathconf(int fd,int name)49 long int fpathconf(int fd, int name)
50 {
51     if (fd < 0)
52     {
53 	__set_errno (EBADF);
54 	return -1;
55     }
56 
57     if (name == _PC_LINK_MAX)
58     {
59 	/* Cut some corners */
60 #if 0
61 	struct statfs fsbuf;
62 
63 	/* Determine the filesystem type.  */
64 	if (__libc_fstatfs (fd, &fsbuf) < 0)
65 	{
66 	    if (errno == ENOSYS)
67 		/* not possible, return the default value.  */
68 		return LINUX_LINK_MAX;
69 
70 	    /* Some error occured.  */
71 	    return -1;
72 	}
73 
74 	switch (fsbuf.f_type)
75 	{
76 	    case EXT2_SUPER_MAGIC:
77 		return EXT2_LINK_MAX;
78 
79 	    case MINIX_SUPER_MAGIC:
80 	    case MINIX_SUPER_MAGIC2:
81 		return MINIX_LINK_MAX;
82 
83 	    case MINIX2_SUPER_MAGIC:
84 	    case MINIX2_SUPER_MAGIC2:
85 		return MINIX2_LINK_MAX;
86 
87 	    case XENIX_SUPER_MAGIC:
88 		return XENIX_LINK_MAX;
89 
90 	    case SYSV4_SUPER_MAGIC:
91 	    case SYSV2_SUPER_MAGIC:
92 		return SYSV_LINK_MAX;
93 
94 	    case COH_SUPER_MAGIC:
95 		return COH_LINK_MAX;
96 
97 	    case UFS_MAGIC:
98 	    case UFS_CIGAM:
99 		return UFS_LINK_MAX;
100 
101 	    case REISERFS_SUPER_MAGIC:
102 		return REISERFS_LINK_MAX;
103 
104 	    default:
105 		return LINUX_LINK_MAX;
106 	}
107 #else
108 	return LINUX_LINK_MAX;
109 #endif
110     }
111 
112     switch (name)
113     {
114 	default:
115 	    __set_errno (EINVAL);
116 	    return -1;
117 
118 	case _PC_MAX_CANON:
119 #ifdef	MAX_CANON
120 	    return MAX_CANON;
121 #else
122 	    return -1;
123 #endif
124 
125 	case _PC_MAX_INPUT:
126 #ifdef	MAX_INPUT
127 	    return MAX_INPUT;
128 #else
129 	    return -1;
130 #endif
131 
132 	case _PC_NAME_MAX:
133 #ifdef	NAME_MAX
134 	    {
135 		struct statfs buf;
136 		int save_errno = errno;
137 
138 		if (__libc_fstatfs (fd, &buf) < 0)
139 		{
140 		    if (errno == ENOSYS)
141 		    {
142 			errno = save_errno;
143 			return NAME_MAX;
144 		    }
145 		    return -1;
146 		}
147 		else
148 		{
149 #ifdef _STATFS_F_NAMELEN
150 		    return buf.f_namelen;
151 #else
152 # ifdef _STATFS_F_NAME_MAX
153 		    return buf.f_name_max;
154 # else
155 		    return NAME_MAX;
156 # endif
157 #endif
158 		}
159 	    }
160 #else
161 	    return -1;
162 #endif
163 
164 	case _PC_PATH_MAX:
165 #ifdef	PATH_MAX
166 	    return PATH_MAX;
167 #else
168 	    return -1;
169 #endif
170 
171 	case _PC_PIPE_BUF:
172 #ifdef	PIPE_BUF
173 	    return PIPE_BUF;
174 #else
175 	    return -1;
176 #endif
177 
178 	case _PC_CHOWN_RESTRICTED:
179 #ifdef	_POSIX_CHOWN_RESTRICTED
180 	    return _POSIX_CHOWN_RESTRICTED;
181 #else
182 	    return -1;
183 #endif
184 
185 	case _PC_NO_TRUNC:
186 #ifdef	_POSIX_NO_TRUNC
187 	    return _POSIX_NO_TRUNC;
188 #else
189 	    return -1;
190 #endif
191 
192 	case _PC_VDISABLE:
193 #ifdef	_POSIX_VDISABLE
194 	    return _POSIX_VDISABLE;
195 #else
196 	    return -1;
197 #endif
198 
199 	case _PC_SYNC_IO:
200 #ifdef	_POSIX_SYNC_IO
201 	    return _POSIX_SYNC_IO;
202 #else
203 	    return -1;
204 #endif
205 
206 	case _PC_ASYNC_IO:
207 #if defined _POSIX_ASYNC_IO
208 	    {
209 		/* AIO is only allowed on regular files and block devices.  */
210 		struct STAT st;
211 
212 		if (FSTAT (fd, &st) < 0 || (! S_ISREG (st.st_mode) && ! S_ISBLK (st.st_mode)))
213 		    return -1;
214 		else
215 		    return 1;
216 	    }
217 #else
218 	    return -1;
219 #endif
220 
221 	case _PC_PRIO_IO:
222 #ifdef	_POSIX_PRIO_IO
223 	    return _POSIX_PRIO_IO;
224 #else
225 	    return -1;
226 #endif
227 
228 	case _PC_SOCK_MAXBUF:
229 #ifdef	SOCK_MAXBUF
230 	    return SOCK_MAXBUF;
231 #else
232 	    return -1;
233 #endif
234 
235 	case _PC_FILESIZEBITS:
236 #ifdef FILESIZEBITS
237 	    return FILESIZEBITS;
238 #else
239 	    /* We let platforms with larger file sizes overwrite this value.  */
240 	    return 32;
241 #endif
242 
243 	    /* Be lazy -- skip these */
244 	case _PC_REC_INCR_XFER_SIZE:
245 	case _PC_REC_MAX_XFER_SIZE:
246 	case _PC_REC_MIN_XFER_SIZE:
247 	case _PC_REC_XFER_ALIGN:
248 	case _PC_ALLOC_SIZE_MIN:
249 	case _PC_SYMLINK_MAX:
250 	    return -1;
251     }
252 
253 }
254 
255