Blog Archive

RPGLE Check IFS Object Existence - Use API access() check Read, Write and Execute authority

CHKOBJ allows you to check if the file exists, and also allows you to optionally check if you have authority to use it. For the IFS we use access() API. Access() can be used to check two things: whether the file exists, and whether it's accessible for reading, writing or execution.The C-language prototype for the access() API looks like this:

int access(const char *path, int amode);


Here is how we define the prototype in RPGLE
daccess           PR            10I 0 extproc('access')       
dpathptr1                         *   value                   
dmode1                          10I 0 value              

The access API returns an integer which can either be 0 if the file is accessible otherwise -1.

The definition of the first parameter specifies “a pointer to the null-terminated path name.” In RPG, we are used to fixed-length strings (for example, we predefine the maximum length of character fields), but in C, the length of a string is indeterminate, and the length is based on what the content of the string is. C strings are terminated with a null value to indicate the end of the string, which you must take into account when you call C functions from RPG. Use OPTIONS(*STRING) on the definition of the parameter in the prototype, and use the %STR built in function to retrieve a string returned from a C function.

The definition of the second parameter reads a lot more complicated then it actually is. A lot of the APIs written in C use a method of setting bits in a byte to indicate certain requirements. The different permutation and combination of bits are defined as named constants. The documentation tells you that the values you can specify for the second parameter are represented by one of the named constants (F_OK, R_OK, W_OK or X_OK), which are defined in the member unistd.h.


********************************************************************** 
      * Access mode flags for access()                                       
      *                                                                      
      *   F_OK = File Exists                                                 
      *   R_OK = Read Access                                                 
      *   W_OK = Write Access                                                
      *   X_OK = Execute or Search                                           
      ********************************************************************** 
     D F_OK            C                   0                                 
     D R_OK            C                   4                                 
     D W_OK            C                   2                                 
     D X_OK            C                   1      

RPGLE Sample program to check existence of an IFS Object and its Read, Write and Execute authority.

h option(*nodebugio) dftactgrp(*NO)                                 
 *                                                                  
daccess           PR            10I 0 extproc('access')             
dpathptr1                         *   value                         
dmode1                          10I 0 value                         
 *                                                                  
 * IFS API Constants                                                
 *                                                                  
DF_OK             S             10I 0 inz(0)                        
DR_OK             S             10I 0 inz(4)                        
DW_OK             S             10I 0 inz(2)                        
DX_OK             S             10I 0 inz(1)                        
 *                                                                  
 * Working variables                                                
 *                                                         
dFile_exists      S             10I 0                          
dpathptr          S               *                            
dpathname         S            101                             
                                                               
d$filename        s            100A                            
d$path            s             50A                            
d$file            s             50A                            
d$found           s              1A                            
d$read            s              1A                            
d$write           s              1A                            
d$execute         s              1A                            
 *                                                             
 * Main ---                                                    
 *                                                             
c     *entry        plist                                      
c                   parm                    $path            50
c                   parm                    $file            50
c                   parm                    $found            1
c                   parm                    $read             1
c                   parm                    $write            1
c                   parm                    $execute          1
                                                               

 * Set a character pointer to the file name string             
c                   eval      $filename = %trim($path)+'/'+%trim($file) 
c                   eval      pathname = %trim($filename)+x'00'         
c                   eval      pathptr = %addr(pathname)                 
c                   eval      $found = 'N'                              
c                   eval      $read  = 'N'                              
c                   eval      $write = 'N'                              
c                   eval      $execute = 'N'                            
                                                                        
 * Call the IFS API                                                     
c                   eval      File_Exists = access(pathptr:F_OK)        
 * Did we find it?                                                      
c     File_exists   ifeq      0                                         
c                   eval      $found = 'Y'                              
c                   endif                                               
                                                                        
 * If file is found !                                                   
c                   if        $found = 'Y'                              
 * Call the IFS API                                                     
c                   eval      File_Exists = access(pathptr:R_OK)        
 * Do we have Read access ?                                             
c     File_exists   ifeq      0                                         
c                   eval      $read = 'Y'                               
c                   endif                                                
* Call the IFS API                                             
c                   eval      File_Exists = access(pathptr:W_OK)
 * Do we have Write access ?                                    
c     File_exists   ifeq      0                                 
c                   eval      $write = 'Y'                      
c                   endif                                       
 * Call the IFS API                                             
c                   eval      File_Exists = access(pathptr:X_OK)
 * Do we have Execute access ?                                  
c     File_exists   ifeq      0                                 
c                   eval      $execute = 'Y'                    
c                   endif                                       
                                                                
c                   endif                                       
                                                                
c                   move      *on           *inlr               
c                   return                                

How to Call this sample program ?
// To Check for a file
d$path            s             50A         inz('/Mydir')                  
d$file            s             50A         inz('filename.ext')                           
d$found           s              1A                                           
d$read            s              1A                                           
d$write           s              1A                                           
d$execute         s              1A                                           
                                                                              
c                   call      'CHKIFS'                                        
c                   parm                    $path                             
c                   parm                    $file                             
c                   parm      *blanks       $found                            
c                   parm      *blanks       $read                             
c                   parm      *blanks       $write                            
c                   parm      *blanks       $execute                          
                                                                              
c                   eval      *inlr = *on                               

//To Check a folder or directory
d$path            s             50A         inz('/Mydir/Folder')                  
d$file            s             50A         inz('')                           
d$found           s              1A                                           
d$read            s              1A                                           
d$write           s              1A                                           
d$execute         s              1A                                           
                                                                              
c                   call      'CHKIFS'                                        
c                   parm                    $path                             
c                   parm                    $file                             
c                   parm      *blanks       $found                            
c                   parm      *blanks       $read                             
c                   parm      *blanks       $write                            
c                   parm      *blanks       $execute                          
                                                                              
c                   eval      *inlr = *on                                           
Reference: IBM Redbooks and Scottklement.com

No comments :

Post a Comment