
In June I wrote about how to use SQL to check if a file existed in the IFS. I received a communication from Rich Diedrich offering an alternative, using the access C procedure. I have taken his code and developed it into this example.
I created an external procedure that I made into a service program to perform the checking, and then wrote a small RPG program to call it to validate if certain files exist.
I am going to start by showing the source code for the external procedure, which resides in a module I called TESTMOD1.
01 **free 02 ctl-opt nomain reqprexp(*no) ; 03 dcl-pr access int(10) extproc('access') ; 04 *n pointer value options(*string) ; 05 *n int(10) value ; 06 end-pr ; 07 dcl-proc IFS_File_Exist export; 08 dcl-pi *n char(10) ; 09 inPathName varchar(100) const; 10 end-pi; 11 if (access(inPathName : 0) < 0) ; 12 return 'Not found' ; 13 else ; 14 return 'Found' ; 15 endif ; 16 end-proc; |
Line 2: The NOMAIN control option stops anyone from compiling this into a program. I find I am using the REQPREXP(*NO) more often as it removes the need for me to have to code procedure prototypes for the procedures in the modules.
Lines 3 – 6: I need a procedure prototype to call the C function, access, that will do the checking if the file exists in the IFS. I need to give the EXTPROC so that the compiler will be able to find this C procedure. It has two parameters:
- Path to check, this needs to be a pointer data type
- The access I want to check. I won't go into the details of how this could be used as it is irrelevant, as we just want to check if the file exists
Line 7: The start of the procedure to check if the file exists.
Lines 8 – 10: The path name is passed to this procedure as a variable character data type, and the procedure returns a ten character value.
Line 11: I am calling access in the If statement. I am passing it the path name that was passed to this procedure, and zero. The value zero will not bother to check if I have Read, Write, or eXecute authority, it will just check if the file exists. If the returned value from access is less than zero then the file in the path could not be found.
Line 12: As the file was not found I am returning "Not found" to whatever called this procedure.
Line 14: If the file was found I am returning "Found".
Having explained what the procedure does I can now show you the source of the program that calls it:
01 **free 02 ctl-opt main(Main) actgrp(*new) bnddir('TESTBNDDIR') ; 03 dcl-pr IFS_File_Exist char(10) ; 04 *n varchar(100) const ; 05 end-pr ; 06 dcl-proc Main ; 07 dcl-s Found char(10) ; 08 dcl-s Path varchar(100) ; 09 Path = '/home/MyFolder/test.txt' ; 10 Found = IFS_File_Exist(Path) ; 11 dsply ('1. ' + Found) ; 12 Path = '/home/MyFolder/does_not_exist.txt' ; 13 Found = IFS_File_Exist(Path) ; 14 dsply ('2. ' + Found) ; 15 return ; 16 end-proc ; |
Lime 2: This program has a Main procedure. I have included the name of binding directory that contains the service program that IFS_File_Exists is in.
Lines 3 – 5: I need this procedure prototype so I can call IFS_File_Exist. As I said before the path name is passed to it.
Line 6: Start of the Main procedure.
Lines 7 and 8: Variable definitions for Found, what will return what is returned from the procedure, and Path, that contains the file's path.
Line 9: This file does exist.
Line 10: Call the procedure, and receive the returned value into Found.
Line 11: Use the Display operation code, DSPLY, to show what was returned.
Line 12: This file, as its name suggest, does not exist.
Lines 13 and 14: These are the same as lines 10 and 11.
After compiling the program, I call it and the following is displayed:
DSPLY 1. Found DSPLY 2. Not found |
This is a good alternative to the SQL version I showed in my previous post. Thank you Rich for sharing this.
This article was written for IBM i 7.6, and should work for some earlier releases too.
Thank you for showing my example. One addition I would like to make is that the RPGLE copy file for IFS in QSYSINC is well done and I would recommend using it for IFS prototypes. The copy statement:
ReplyDelete/copy qsysinc/qrpglesrc,ifs
makes accessing IFS simple in RPGLE.