long sysconf(int name);
long pathconf(const char* pathname, int name);
long fpathconf(int filedes, int name);
#include<errno.h>
#include<limits.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
static void pr_sysconf(char *mesg, int name);
static void pr_pathconf(char *mesg, char *path, int name);
void err_quit(const char* msg)
{
printf("%s\n", msg);
exit(1);
}
void err_sys(const char* msg)
{
printf("%s\n", msg);
exit(127);
}
int main(int argc, char *argv[])
{
if(argc != 2)
err_quit("usage: unix_limit.out <dirname>");
// Test the compile limits in current system
// We are testing following 3 constants
// _ARG_MAX, _POSIX_THREAD_THREADS_MAX, LOGIN_NAME_MAX
#ifdef ARG_MAX
printf("ARG_MAX defined to be %d\n", ARG_MAX+0);
#else
printf("no symbol for ARG_MAX\n");
#endif
#ifdef _POSIX_THREAD_THREADS_MAX
printf("_POSIX_THREAD_THREADS_MAX defined to be %d\n", _POSIX_THREAD_THREADS_MAX+0);
#else
printf("no symbol for _POSIX_THREAD_THREADS_MAX\n");
#endif
#ifdef LOGIN_NAME_MAX
printf("LOGIN_NAME_MAX defined to be %d\n", LOGIN_NAME_MAX+0);
#else
printf("no symbol for LOGIN_NAME_MAX\n");
#endif
// Test the runtime limits: sysconf in current system
// We are testing following 3 constants:
// _SC_ARG_MAX(max length of arguments)
// _SC_CHILD_MAX, _SC_CLK_TCK(the number of clock ticks per second)
#ifdef _SC_ARG_MAX
pr_sysconf("ARG_MAX=", _SC_ARG_MAX);
#else
printf("no symbol for _SC_ARG_MAX\n");
#endif
#ifdef _SC_CHILD_MAX
pr_sysconf("CHILD_MAX=", _SC_CHILD_MAX);
#else
printf("no symbol for _SC_CHILD_MAX\n");
#endif
#ifdef _SC_CLK_TCK
pr_sysconf("CLOCK_TICK=", _SC_CLK_TCK);
#else
printf("no symbol for _SC_CLK_TCK\n");
#endif
// Test the runtime limits: pathconf in current system
// We are testing following 2 constants
// _PC_PATH_MAX, _PC_SYNC_IO
#ifdef _PC_PATH_MAX
pr_pathconf("PC_PATH_MAX=", argv[1], _PC_PATH_MAX);
#else
printf("no symbol for _PC_PATH_MAX\n");
#endif
#ifdef _PC_SYNC_IO
pr_pathconf("PC_SYNC_IO=", argv[1], _PC_SYNC_IO);
#else
printf("no symbol for PC_SYNC_IO\n");
#endif
exit(0);
}
static void pr_sysconf(char *mesg, int name)
{
long val;
fputs(mesg, stdout);
errno = 0;
// sysconf will return the real value for specificed configuration
// and will return -1 while changing the errno for error
// if it return -1 but not changed errno, then it indicated that
// there is no limits
// similar for pathconf
if((val = sysconf(name)) < 0) {
if(errno != 0) {
if (errno == EINVAL)
fputs(" (not supported)\n", stdout);
else
err_sys("sysconf error");
}
else {
fputs(" (no limit)\n", stdout);
}
}
else {
printf(" %ld\n", val);
}
}
static void pr_pathconf(char *mesg, char *path, int name)
{
long val;
fputs(mesg, stdout);
errno = 0;
// pathconf need to specify the path name to get the configuration
// associated with one path.
// For some configuration file, path must be terminal file: _PC_MAX_CANON, _PC_MAX_INPUT
// For some configuration file, path must be directory: _PC_PATH_MAX
// For some configuration file, path must be a pipe, FIFO etc: _PC_PIPE_BUF
// The only difference betwwen pathconf and fpathconf is: fpathconf need to provide
// the file descriptor instead of file path
if((val = pathconf(path, name)) < 0) {
if(errno != 0) {
if(errno == EINVAL)
fputs(" (not supported)\n", stdout);
else
err_sys("pathconf error");
}
else {
fputs(" (no limit)\n", stdout);
}
}
else {
printf(" %ld\n", val);
}
}
Result:
"Not supported" means that this is invalid name
"no limit" means that although this name is invalid, but it is indeterminate limit.
ubuntu@ip-172-31-23-227:~$ ./limits.out test
no symbol for ARG_MAX
_POSIX_THREAD_THREADS_MAX defined to be 64
LOGIN_NAME_MAX defined to be 256
ARG_MAX= 2097152
CHILD_MAX= 7862
CLOCK_TICK= 100
PC_PATH_MAX= 4096
PC_SYNC_IO= (no limit)
Explanation:
shell:
pathconf, fpathconf, and sysconf are defined at unistd.h
ubuntu@ip-172-31-23-227:~$ less /usr/include/unistd.h
......
/* Get the `_PC_*' symbols for the NAME argument to `pathconf' and `fpathconf';
the `_SC_*' symbols for the NAME argument to `sysconf';
and the `_CS_*' symbols for the NAME argument to `confstr'. */
#include <bits/confname.h>
/* Get file-specific configuration information about PATH. */
extern long int pathconf (const char *__path, int __name)
__THROW __nonnull ((1));
/* Get file-specific configuration about descriptor FD. */
extern long int fpathconf (int __fd, int __name) __THROW;
/* Get the value of the system variable NAME. */
extern long int sysconf (int __name) __THROW;
......
No comments:
Post a Comment