Monday, August 11, 2014

Unix Prog: Unix Standardization(3)

1. Indeterminate Run Time Limits -- pathname allocation

pathname.c:
 #include<errno.h>  
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
 #include<limits.h>  
   
 // If PATH_MAX is already defined, then we use pathmax, otherwises populate it with 0  
 // In current system, PATH_MAX is already defined, in order to test this feature,  
 // I undefine it now.  
 #undef PATH_MAX  
 #ifdef PATH_MAX  
 static int pathmax=PATH_MAX;  
 #else  
 static int pathmax=0;  
 #endif  
   
 // Define the default posix version as 0  
 #define SUSV3 200112L  
 static long posix_version = 0;  
   
 // If the PATH_MAX is indeterminate, will use following number as a guess  
 #define PATH_MAX_GUESS 1024  
   
 void err_sys(const char* msg)  
 {  
  printf("%s\n", msg);  
  exit(127);  
 }  
   
 // Define a function to allocate the memory for path name  
 // It will return the path name memory pointer, and populate the memory  
 // size from passed-in parameter  
 char* path_alloc(int *sizep)  
 {  
  char *ptr;  
  int size;  
   
  // constants whose name starting with the "_SC" is for sysconf
  if(posix_version == 0)  
   posix_version = sysconf(_SC_VERSION);  
   
  printf("posix_version: %ld\n", posix_version);  
  //Output: 200809  
   
  if(pathmax == 0) {  
   errno = 0; // we have to initialize errno every time when we use that  
   // constants whose name starting with "_PC" is for pathconf
   if((pathmax = pathconf("/", _PC_PATH_MAX)) < 0) {  
    if (errno == 0) // if not changed errno, meaning it is indeterminate  
     pathmax = PATH_MAX_GUESS;  
    else  
     err_sys("pathconf error for _PC_PATH_MAX");  
   }  
   else {  
    pathmax++; //since this is relative to root '/', add 1 for '/'  
   }  
  }  
   
  printf("pathmax: %d\n", pathmax);  
  //Output: 4097  
  // For system whose posix version is earlier than SUSV3,  
  // its pathmax doesn't include one final mandatory null character.  
  // add one char for them.  
  if(posix_version < SUSV3)  
   size = pathmax+1;  
  else  
   size = pathmax;  
   
  if((ptr = malloc(size)) == NULL)  
   err_sys("malloc error for pathname");  
   
  if(sizep != NULL)  
   *sizep= size;  
   
  return ptr;  
 }  
   
 int main(int argc, char* argv[])  
 {  
  int size;  
  path_alloc(&size);  
   
  printf("size of allocated pathname space: %d\n", size);  
   
  exit(0);  
 }  

Shell output:
 ubuntu@ip-172-31-23-227:~$ ./pathname.out  
 posix_version: 200809  
 pathmax: 4097  
 size of allocated pathname space: 4097  

2. Options
There are some optionally supported features in different implementations of unix, we need some way to get: for a specific option, whether it is supported or not.

1) compile-time options: defined as constants at <unistd.h>
2) runtime options that are not associated with a file or directory are identified with the sysconf(constants name starting with _SC)
3) runtime options that are associated with a file or directory are identified with the pathconf or the fpathconf(constants name starting with _PC)

Summary: options are very similar from limits, we can imagine them as another sets of constants with same rules as limits

Given a specific constants,
1) If it is defined as constants whose value greater than 0, then it is supported by current implementation
2) If it is defined as constants whose value less than 0, then it is not supported by current implementation
3) If it is defined as constants whose value is equal to 0 or not defined at all, then we need to call sysconf, pathconf, or fpathconf to determine.

shell:
1) Look for the "JOB_CONTROL" from all header files. And it indicates that _POSIX_JOB_CONTROL is already defined at /usr/include/unistd.h, but user can also use sysconf to get the value at the runtime, with _SC_JOB_CONTROL
This option indicates if the current system supports the job control
2) Look for the "READER_WRITER_LOCKS" from all header files. And it indicates that _POSIX_READER_WRITER_LOCKS is not defined, and what we can do is to use sysconf by using _SC_READER_WRITER_LOCKS
 ubuntu@ip-172-31-23-227:~$ sudo find /usr/include -name *.h | xargs grep JOB_CONTROL  
 /usr/include/unistd.h:  _POSIX_JOB_CONTROL       Job control is supported.  
 /usr/include/x86_64-linux-gnu/bits/confname.h:  _SC_JOB_CONTROL,  
 /usr/include/x86_64-linux-gnu/bits/confname.h:#define  _SC_JOB_CONTROL         _SC_JOB_CONTROL  
 /usr/include/x86_64-linux-gnu/bits/posix_opt.h:#define _POSIX_JOB_CONTROL   1  
 ubuntu@ip-172-31-23-227:~$ sudo find /usr/include -name *.h | xargs grep READER_WRITER_LOCKS  
 /usr/include/x86_64-linux-gnu/bits/confname.h:  _SC_READER_WRITER_LOCKS,  
 /usr/include/x86_64-linux-gnu/bits/confname.h:#define _SC_READER_WRITER_LOCKS      _SC_READER_WRITER_LOCKS  
 /usr/include/x86_64-linux-gnu/bits/posix_opt.h:#define _POSIX_READER_WRITER_LOCKS    200809L  

options.c
 #include<unistd.h>  
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<errno.h>  
   
 int main()  
 {  
  int option;  
  errno = 0;  
  if((option = sysconf(_SC_JOB_CONTROL)) < 0) {  
   if(errno == 0) {  
    printf("This option is not supported.\n");  
   }  
   else {  
    printf("sysconf error for _SC_JOB_CONTROL\n");  
   }  
  }  
  else {  
   printf(" value is: %d\n", option);  
  }  
 }  

Shell output:
Output being 1 means, this option is supported
 ubuntu@ip-172-31-23-227:~$ ./options.out  
  value is: 1  

No comments:

Post a Comment