Monday, August 11, 2014

Unix Prog: Unix Standardization(2)

1. Get the configuration file for current system:
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