* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
static char sccsid[] = "@(#)sysconf.c 8.2 (Berkeley) 3/20/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/gen/sysconf.c,v 1.20 2002/11/17 08:54:29 dougb Exp $");
+__FBSDID("$FreeBSD: lib/libc/gen/sysconf.c r168718 $");
#include <sys/param.h>
#include <sys/time.h>
quad_t qdvalue; /* for kern.sysv.shmmin */
size_t len;
int mib[3], sverrno, value;
- long defaultresult;
+ long lvalue, defaultresult;
const char *path;
- len = sizeof(value);
defaultresult = -1;
switch (name) {
case _SC_STREAM_MAX: /* assume fds run out before memory does */
if (getrlimit(RLIMIT_NOFILE, &rl) != 0)
return (-1);
- if (rl.rlim_cur == RLIM_INFINITY)
+#if __LP64__
+ /*
+ * In 64 bit world, sysconf is able to correctly represent
+ * rlim_t values (8 bytes).
+ */
+ if (rl.rlim_cur > RLIM_INFINITY)
return (-1);
if (rl.rlim_cur > LONG_MAX) {
errno = EOVERFLOW;
return (-1);
}
- return ((long)rl.rlim_cur);
+ lvalue = rl.rlim_cur;
+#else
+ /*
+ * In 32 bit world (watches), sysconf falls back to the
+ * old behavior: use (int) OPEN_MAX as max limit. Ideally
+ * we would use maxfilesperproc as max limit, which is a
+ * system value adjusted by the kernel based on available
+ * RAM size. This value defaults to OPEN_MAX for systems
+ * with less than 8G of RAM. So we use OPEN_MAX (defined
+ * in sys/syslimits.h) as max limit here in case
+ * applications with strict sandbox rules prevent libc
+ * from reading maxfilesperproc via sysctl.
+ */
+ if (rl.rlim_cur > OPEN_MAX)
+ lvalue = OPEN_MAX;
+ else
+ lvalue = (long)rl.rlim_cur;
+#endif
+ return lvalue;
case _SC_JOB_CONTROL:
return (_POSIX_JOB_CONTROL);
case _SC_SAVED_IDS:
do_NAME_MAX:
sverrno = errno;
errno = 0;
- value = pathconf(path, _PC_NAME_MAX);
- if (value == -1 && errno != 0)
+ lvalue = pathconf(path, _PC_NAME_MAX);
+ if (lvalue == -1 && errno != 0)
return (-1);
errno = sverrno;
- return (value);
+ return (lvalue);
case _SC_ASYNCHRONOUS_IO:
#if _POSIX_ASYNCHRONOUS_IO == 0
return (_POSIX_TIMERS);
#endif
case _SC_AIO_LISTIO_MAX:
+#if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_AIO_LISTIO_MAX)
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_AIO_LISTIO_MAX;
+#else
+ mib[0] = CTL_KERN;;
+ mib[1] = KERN_AIOMAX;
+#endif
+ break;
case _SC_AIO_MAX:
+#if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_AIO_MAX)
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_AIO_MAX;
+#else
mib[0] = CTL_KERN;;
mib[1] = KERN_AIOMAX;
+#endif
break;
-
case _SC_AIO_PRIO_DELTA_MAX:
#if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_AIO_PRIO_DELTA_MAX)
mib[0] = CTL_P1003_1B;
return (-1);
#endif
case _SC_SEM_NSEMS_MAX:
+#if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_RTSIG_MAX)
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_SEM_NSEMS_MAX;
+ goto yesno;
+#else
+ len = sizeof(value);
return (sysctlbyname("kern.sysv.semmns", &value, &len, NULL, 0) == -1 ? -1 : value);
+#endif
case _SC_SEM_VALUE_MAX:
#if SEM_VALUE_MAX == 0
return (-1);
#endif
-yesno: if (sysctl(mib, 2, &value, &len, NULL, 0) == -1)
+yesno:
+ len = sizeof(value);
+ if (sysctl(mib, 2, &value, &len, NULL, 0) == -1)
return (-1);
if (value == 0)
return (defaultresult);
- return (value);
+ return ((long)value);
+
case _SC_2_PBS:
case _SC_2_PBS_ACCOUNTING:
case _SC_2_PBS_CHECKPOINT:
case _SC_2_PBS_LOCATE:
case _SC_2_PBS_MESSAGE:
case _SC_2_PBS_TRACK:
- return -1;
+#if _POSIX2_PBS == 0
+#error "don't know how to determine _SC_2_PBS"
+ /*
+ * This probably requires digging through the filesystem
+ * to see if the appropriate package has been installed.
+ * Since we don't currently support this option at all,
+ * it's not worth the effort to write the code now.
+ * Figuring out which of the sub-options are supported
+ * would be even more difficult, so it's probably easier
+ * to always say ``no''.
+ */
+#else
+ return (_POSIX2_PBS);
+#endif
case _SC_ADVISORY_INFO:
#if _POSIX_ADVISORY_INFO == 0
#error "_POSIX_ADVISORY_INFO"
case _SC_PASS_MAX:
return (PASS_MAX);
+#ifdef _SC_PHYS_PAGES
+ case _SC_PHYS_PAGES:
+#ifdef __APPLE__
+ {
+ long memsize;
+ long pagesize;
+
+ len = sizeof(memsize);
+ if (sysctlbyname("hw.memsize", &memsize, &len, NULL, 0) == -1)
+ return (-1);
+
+ len = sizeof(pagesize);
+ if (sysctlbyname("hw.pagesize", &pagesize, &len, NULL, 0) == -1)
+ return (-1);
+
+ return (memsize / pagesize);
+ }
+#else
+ len = sizeof(lvalue);
+ if (sysctlbyname("hw.availpages", &lvalue, &len, NULL, 0) == -1)
+ return (-1);
+ return (lvalue);
+#endif
+#endif
+
default:
errno = EINVAL;
return (-1);
}
- return (sysctl(mib, 2, &value, &len, NULL, 0) == -1 ? -1 : value);
+ len = sizeof(value);
+ if (sysctl(mib, 2, &value, &len, NULL, 0) == -1)
+ value = -1;
+ return ((long)value);
}