headers/bsd: Add sys/queue.h.
[haiku.git] / src / system / libroot / posix / unistd / conf.cpp
blobb05dab5364f288a1c269a939c4f2af4df55ac271
1 /*
2 * Copyright 2002-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
7 #include <unistd.h>
9 #include <errno.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <sys/resource.h>
14 #include <sys/statvfs.h>
16 #include <SupportDefs.h>
18 #include <directories.h>
19 #include <fs_info.h>
20 #include <posix/realtime_sem_defs.h>
21 #include <signal_defs.h>
22 #include <symbol_versioning.h>
23 #include <syscalls.h>
24 #include <thread_defs.h>
25 #include <user_group.h>
26 #include <user_timer_defs.h>
27 #include <vfs_defs.h>
29 #include <errno_private.h>
30 #include <libroot_private.h>
31 #include <time_private.h>
32 #include <unistd_private.h>
35 int
36 getdtablesize(void)
38 struct rlimit rlimit;
39 if (getrlimit(RLIMIT_NOFILE, &rlimit) < 0)
40 return OPEN_MAX;
42 return rlimit.rlim_cur;
46 long
47 __sysconf_beos(int name)
49 switch (name) {
50 case _SC_CLK_TCK:
51 return CLK_TCK_BEOS;
54 return __sysconf(name);
58 long
59 __sysconf(int name)
61 int err;
62 // TODO: This is about what BeOS does, better POSIX conformance would be
63 // nice, though
65 switch (name) {
66 case _SC_ARG_MAX:
67 return ARG_MAX;
68 case _SC_CHILD_MAX:
69 return CHILD_MAX;
70 case _SC_CLK_TCK:
71 return CLK_TCK;
72 case _SC_JOB_CONTROL:
73 return 1;
74 case _SC_NGROUPS_MAX:
75 return NGROUPS_MAX;
76 case _SC_OPEN_MAX:
77 return getdtablesize();
78 case _SC_SAVED_IDS:
79 return 1;
80 case _SC_STREAM_MAX:
81 return STREAM_MAX;
82 case _SC_TZNAME_MAX:
83 return TZNAME_MAX;
84 case _SC_VERSION:
85 return _POSIX_VERSION;
86 case _SC_GETGR_R_SIZE_MAX:
87 return MAX_GROUP_BUFFER_SIZE;
88 case _SC_GETPW_R_SIZE_MAX:
89 return MAX_PASSWD_BUFFER_SIZE;
90 case _SC_PAGE_SIZE:
91 return B_PAGE_SIZE;
92 case _SC_SEM_NSEMS_MAX:
93 return _POSIX_SEM_NSEMS_MAX;
94 case _SC_SEM_VALUE_MAX:
95 return _POSIX_SEM_VALUE_MAX;
96 case _SC_SEMAPHORES:
97 return _POSIX_SEMAPHORES;
98 case _SC_THREADS:
99 return _POSIX_THREADS;
100 case _SC_IOV_MAX:
101 return IOV_MAX;
102 case _SC_NPROCESSORS_CONF:
104 system_info info;
105 err = get_system_info(&info);
106 if (err < B_OK) {
107 __set_errno(err);
108 return -1;
110 return info.cpu_count;
112 case _SC_NPROCESSORS_ONLN:
114 system_info info;
115 unsigned int i;
116 int count = 0;
117 err = get_system_info(&info);
118 if (err < B_OK) {
119 __set_errno(err);
120 return -1;
122 for (i = 0; i < info.cpu_count; i++)
123 if (_kern_cpu_enabled(i))
124 count++;
125 return count;
127 case _SC_ATEXIT_MAX:
128 return ATEXIT_MAX;
129 case _SC_PASS_MAX:
130 break;
131 //XXX:return PASS_MAX;
132 case _SC_PHYS_PAGES:
134 system_info info;
135 err = get_system_info(&info);
136 if (err < B_OK) {
137 __set_errno(err);
138 return -1;
140 return info.max_pages;
142 case _SC_AVPHYS_PAGES:
144 system_info info;
145 err = get_system_info(&info);
146 if (err < B_OK) {
147 __set_errno(err);
148 return -1;
150 return info.max_pages - info.used_pages;
152 case _SC_MAPPED_FILES:
153 return _POSIX_MAPPED_FILES;
154 case _SC_THREAD_PROCESS_SHARED:
155 return _POSIX_THREAD_PROCESS_SHARED;
156 case _SC_THREAD_STACK_MIN:
157 return MIN_USER_STACK_SIZE;
158 case _SC_THREAD_ATTR_STACKADDR:
159 return _POSIX_THREAD_ATTR_STACKADDR;
160 case _SC_THREAD_ATTR_STACKSIZE:
161 return _POSIX_THREAD_ATTR_STACKSIZE;
162 case _SC_THREAD_PRIORITY_SCHEDULING:
163 return _POSIX_THREAD_PRIORITY_SCHEDULING;
164 case _SC_REALTIME_SIGNALS:
165 return _POSIX_REALTIME_SIGNALS;
166 case _SC_MEMORY_PROTECTION:
167 return _POSIX_MEMORY_PROTECTION;
168 case _SC_SIGQUEUE_MAX:
169 return MAX_QUEUED_SIGNALS;
170 case _SC_RTSIG_MAX:
171 return SIGRTMAX - SIGRTMIN + 1;
172 case _SC_MONOTONIC_CLOCK:
173 return _POSIX_MONOTONIC_CLOCK;
174 case _SC_DELAYTIMER_MAX:
175 return MAX_USER_TIMER_OVERRUN_COUNT;
176 case _SC_TIMER_MAX:
177 return MAX_USER_TIMERS_PER_TEAM;
178 case _SC_TIMERS:
179 return _POSIX_TIMERS;
180 case _SC_CPUTIME:
181 return _POSIX_CPUTIME;
182 case _SC_THREAD_CPUTIME:
183 return _POSIX_THREAD_CPUTIME;
185 // not POSIX (anymore)
186 case _SC_PIPE:
187 case _SC_SELECT:
188 case _SC_POLL:
189 return 1;
192 __set_errno(EINVAL);
193 return -1;
197 enum {
198 FS_BFS,
199 FS_FAT,
200 FS_EXT,
201 FS_UNKNOWN
205 static int
206 fstype(const char *fsh_name)
208 if (!strncmp(fsh_name, "bfs", B_OS_NAME_LENGTH))
209 return FS_BFS;
210 if (!strncmp(fsh_name, "dos", B_OS_NAME_LENGTH))
211 return FS_FAT;
212 if (!strncmp(fsh_name, "fat", B_OS_NAME_LENGTH))
213 return FS_FAT;
214 if (!strncmp(fsh_name, "ext2", B_OS_NAME_LENGTH))
215 return FS_EXT;
216 if (!strncmp(fsh_name, "ext3", B_OS_NAME_LENGTH))
217 return FS_EXT;
218 return FS_UNKNOWN;
223 static long
224 __pathconf_common(struct statvfs *fs, struct stat *st,
225 int name)
227 fs_info info;
228 int ret;
229 ret = fs_stat_dev(fs->f_fsid, &info);
230 if (ret < 0) {
231 __set_errno(ret);
232 return -1;
235 // TODO: many cases should check for file type from st.
236 switch (name) {
237 case _PC_CHOWN_RESTRICTED:
238 return _POSIX_CHOWN_RESTRICTED;
240 case _PC_MAX_CANON:
241 return MAX_CANON;
243 case _PC_MAX_INPUT:
244 return MAX_INPUT;
246 case _PC_NAME_MAX:
247 return fs->f_namemax;
248 //return NAME_MAX;
250 case _PC_NO_TRUNC:
251 return _POSIX_NO_TRUNC;
253 case _PC_PATH_MAX:
254 return PATH_MAX;
256 case _PC_PIPE_BUF:
257 return VFS_FIFO_ATOMIC_WRITE_SIZE;
259 case _PC_LINK_MAX:
260 return LINK_MAX;
262 case _PC_VDISABLE:
263 return _POSIX_VDISABLE;
265 case _PC_FILESIZEBITS:
267 int type = fstype(info.fsh_name);
268 switch (type) {
269 case FS_BFS:
270 case FS_EXT:
271 return 64;
272 case FS_FAT:
273 return 32;
275 // XXX: add fs ? add to statvfs/fs_info ?
276 return FILESIZEBITS;
279 case _PC_SYMLINK_MAX:
280 return SYMLINK_MAX;
282 case _PC_2_SYMLINKS:
284 int type = fstype(info.fsh_name);
285 switch (type) {
286 case FS_BFS:
287 case FS_EXT:
288 return 1;
289 case FS_FAT:
290 return 0;
292 // XXX: there should be an HAS_SYMLINKS flag
293 // to fs_info...
294 return 1;
297 case _PC_XATTR_EXISTS:
298 case _PC_XATTR_ENABLED:
300 #if 0
301 /* those seem to be Solaris specific,
302 * else we should return 1 I suppose.
303 * we don't yet map POSIX xattrs
304 * to BFS ones anyway.
306 if (info.flags & B_FS_HAS_ATTR)
307 return 1;
308 return -1;
309 #endif
310 __set_errno(EINVAL);
311 return -1;
314 case _PC_SYNC_IO:
315 case _PC_ASYNC_IO:
316 case _PC_PRIO_IO:
317 case _PC_SOCK_MAXBUF:
318 case _PC_REC_INCR_XFER_SIZE:
319 case _PC_REC_MAX_XFER_SIZE:
320 case _PC_REC_MIN_XFER_SIZE:
321 case _PC_REC_XFER_ALIGN:
322 case _PC_ALLOC_SIZE_MIN:
323 /* not yet supported */
324 __set_errno(EINVAL);
325 return -1;
329 __set_errno(EINVAL);
330 return -1;
334 long
335 fpathconf(int fd, int name)
337 struct statvfs fs;
338 struct stat st;
339 int ret;
340 if (fd < 0) {
341 __set_errno(EBADF);
342 return -1;
344 ret = fstat(fd, &st);
345 if (ret < 0)
346 return ret;
347 ret = fstatvfs(fd, &fs);
348 if (ret < 0)
349 return ret;
350 return __pathconf_common(&fs, &st, name);
354 long
355 pathconf(const char *path, int name)
357 struct statvfs fs;
358 struct stat st;
359 int ret;
360 if (path == NULL) {
361 __set_errno(EFAULT);
362 return -1;
364 ret = lstat(path, &st);
365 if (ret < 0)
366 return ret;
367 ret = statvfs(path, &fs);
368 if (ret < 0)
369 return ret;
370 return __pathconf_common(&fs, &st, name);
374 size_t
375 confstr(int name, char *buffer, size_t length)
377 size_t stringLength = 0;
378 const char *string = "";
380 if (!length || !buffer) {
381 __set_errno(EINVAL);
382 return 0;
385 switch (name) {
386 case _CS_PATH:
387 string = kSystemNonpackagedBinDirectory ":" kGlobalBinDirectory ":"
388 kSystemAppsDirectory ":" kSystemPreferencesDirectory;
389 break;
390 default:
391 __set_errno(EINVAL);
392 return 0;
395 if (buffer != NULL) {
396 stringLength = strlen(string) + 1;
397 strlcpy(buffer, string,
398 min_c(length - 1, stringLength));
401 return stringLength;
405 DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("__sysconf_beos", "sysconf@", "BASE");
407 DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("__sysconf", "sysconf@@", "1_ALPHA4");