Chapter 3. Other simple, but helpful IFS commands

Table of Contents
3.1. Checking existence and permissions to files
3.2. Example of checking for an object in the IFS
3.3. Changing permissions on an existing IFS Object
3.4. Example of changing an IFS objects permissions
3.5. Retrieving Stream File Stats
3.6. Adding a *SAME option to the permission changer
3.7. Deleting IFS objects
3.8. Renaming IFS objects
3.9. Example of renaming and deleting IFS objects

3.1. Checking existence and permissions to files

In the last chapter, we covered the basics of how stream files work. It's all down hill from here!

One question that I've been asked many times is: "I use the CHKOBJ command in my CL programs. How can I do the same thing with a file in the IFS?"

The answer is the 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);

The prototype is quite simple, and I think by now you're already getting the hang of it, so without further ado, here's the RPG version:

 (1)     D access          PR            10I 0 ExtProc('access')
 (2)     D   Path                          *   Value Options(*string) 
 (3)     D   amode                       10I 0 Value 
   

Please add this to the IFSIO_H copy member, if you're typing it in yourself.

(1)
The access API returns an integer which can either be 0 if the file is accessible, or -1 if for some reason it is not.

Like most UNIX-type APIs, we can check errno after calling access to find out why the file wasn't accessible.

(2)
This is the path name of the IFS object that we want to check the accessibility of.
(3)
This is the access that we want to check. This is another one of those "bit flag" fields, similar to the ones we've been using in the open() API.

The amode parameter uses the rightmost 3 bits of the parameter to determine which access we want to check. If the right-most bit is on, access() checks for execute authority. The next bit to the left checks for write access, and the 3rd bit from the right checks for read access.

If none of the bits in the amode parameter are set, the API will only check to see if the object exists.

Just like we did for the other bit-flags that we've used, we will define named constants to both to make our code easier to follow, and also to match the constants that are already defined for the C programmers.

      ********************************************************************** 
      * 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                                 
   

Here's a sample of calling access() in an RPG program:

     c                   if        access(%trimr(myfile): F_OK) < 0          
     c                   eval      err = errno                               
     c                   if        err = ENOENT                              
     c                   callp     die('Errrm... can''t find that file!')    
     c                   else                                                
     c                   callp     die(%str(strerror(err)))                  
     c                   endif                                               
     c                   endif                                               
                                                                             
     c                   if        access(%trimr(myfile): R_OK) < 0          
     c                   eval      err = errno                               
     c                   if        err = EACCES                           
     c                   callp     die('It''s there, but YOU can''t read ' + 
     c                                'it!  Nyaahh! Nyaahh!')                
     c                   else                                                
     c                   callp     die(%str(strerror(err)))                  
     c                   endif                                               
     c                   endif