Avatar of anuar8080
anuar8080

asked on 

RPG Program to Check Existance of IFS Object

HI,

I am trying to write a RPG program to check of an existance of an object in the IFS . I manage find this program as a simple method to check if a file exists below but if still does not seem to work . It return that all objects are not found ? Could it be that the location of my directory and objects ?

I have attached a print screen as below as to the location of the objects . I am trying to check programaticlly if a particular object exists or not in that dir as the files will be refresh everyday .

Thanks

Thanks


Daccess           PR            10I 0 extproc('access')
Dpathptr1                         *   value
Dmode1                          10I 0 value
 *
 * IFS API Constants
 *
DF_OK             S             10I 0 inz(0)
 *
 * Some working environment for us
 *
DFile_exists      S             10I 0
Dpathptr          S               *
Dpathname         S             21
DExists           C                   'File Exists'
DNotExists        C                   'File does not exist'
 *
 * Main{}
 *
C     *entry        plist
C                   parm                    filename         20
 * Set a character pointer to the file name string
C                   eval      pathname = %trim(filename)+x'00'
C                   eval      pathptr = %addr(pathname)
 * Call the IFS API
C                   eval      File_Exists = access(pathptr:F_OK)
 * Did we find it?
C     File_exists   ifeq      0
C     Exists        dsply
C                   else
C     NotExists     dsply
C                   endif
 * That's all, folks
C                   move      *on           *inlr


FILE.JPG
Operating Systems

Avatar of undefined
Last Comment
Theo Kouwenhoven
Avatar of Theo Kouwenhoven
Theo Kouwenhoven
Flag of Netherlands image

Never did it that way, to test I use a CL. like this

PGM PARM(&OBJ &STAT)

DCL        VAR(&OBJ) TYPE(*CHAR) LEN(50)
DCL        VAR(&STAT) TYPE(*CHAR) LEN(1) VALUE('0')

MOV OBJ('/DCSDIR/GOESAN.TX') TOOBJ('/DCSDIR/GOESAN.TX')
MONMSG MSGID(CPFA085 CPFA093 CPFA0B2 CPFA0A9) +
EXEC(CHGVAR VAR(&STAT) VALUE('1'))                            

ENDPGM

Regards,
Murph



MOV OBJ('/DCSDIR/GOESAN.TX') TOOBJ('/DCSDIR/GOESAN.TX')
should be
MOV OBJ(&OBJ) TOOBJ(&OBJ)
Avatar of anuar8080
anuar8080

ASKER

Hi,

I need to used RPG because i need the program to embedded within another RPG program , because i need it to return a true or false value for further processing. Can i return a value from CL should i chose to embed it within a RPG program ?
Sure you can call the CL from rpg like:
assume the program before named CHECKIFS

Eval #OBJ = '/MyIFSFLDR/MYFILE/
Call 'CHECKIFS'
Parm      #OBJ
Parm      #STS             (o = found, 1 = not fond) see sample prog before.

   
I complied and tested your original RPG on my V5R4 machine, and it worked fine (as long as the path to the IFS object isn't longer than 20 bytes, that is!).

Verify the following:

1) At runtime, the program has authority to see the IFS object.
2) You are properly specifying the path to the object: '/myfile.txt'
3) The total path isn't longer than 20 bytes - that's all you have room for due to the "filename" parm.  If you set the current directory first, you can just specify the filename without the path, and that will work, too.
4) If you are in a case-sensitive file system (Qopensys), make sure the case matches!
5) Make sure your slashes are going the right way!  '/somefolder/somefile.txt', not '\somefolder\somefile'

-Gary Patterson
If you're doing a low volume of object testing, there's no harm in the CL method above.  

If you plan to make this a standard object existence routine for use in unknown volume situations, I'd use your original RPG solution, since it won't create the flurry of exceptions in a high-volume application like the CL approach will, and might perform somewhat better as a result.  In a high volume application, you can fill up job logs when you use exception-based testing like the CL approach above.

The only problem that I see with your code is the *PLIST parm that you are using for testing purposes is too small for practical use.

-Gary Patterson

anuar8080:

You have --

    Dpathname         S             21

But the shortest path that I can see in the .JPG you posted is some 33 bytes in length. Even if a relative path is used, the shortest is 24 bytes (plus an extra byte for the null-terminator makes 25.)

Unless you supply a much longer pathname, it looks like you will always get "not found" because you cannot supply the full names.

Tom
Avatar of anuar8080
anuar8080

ASKER

It will be used to process large volumes of data so i see RPG as the way to go... I have increased the size of the file name to 100 together with the Dpathname  also to 100 but still does not work, It always keeps returning not found...

In the example i always call

call pgm(MyPGM) PARM(/Ereport/List of Client Added.pdf')
the large volume will make no diference for RPG or CL

In your last example you typed :
call pgm(MyPGM) PARM(/Ereport/List of Client Added.pdf')
is that a typo? the original name is diferent.
EReport in stead of Ereport, I don't know if it's case sensitive.
I'm 100% sure that the CL option isn't case sensitive (just tried).




Avatar of anuar8080
anuar8080

ASKER

Yes, it was a typo error i have tried the CL method and it works but i just cannot figure out why the RPG program will not work..
ASKER CERTIFIED SOLUTION
Avatar of Gary Patterson, CISSP
Gary Patterson, CISSP
Flag of United States of America image

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
Murph.  No disrespect intended, but of course the CL method is much slower.  It relies on the CL exception handler, and that is a big code path.  At default job message queue settings, it also generates a huge job log if called repeatedly (for example in a server job that runs all day), and can hang the job if the message queue is not set to wrap or print.

I did a quick test.  I coded two little ILE programs:

One that called a bound CLLE module (no command logging) containing the CL code you supplied 100,000 times using a file name that doesn't exist;

The other an ILE RPG that does the same 100,000 static calls to the API.  

Code for both is below.  I submitted each program to batch on a relatively idle machine with default SBMJOB parameters.  Results:

ACCESSCLP ran for 21 seconds, used 21 seconds of CPU, and generated a 15385 page job log
ACCESSRPG ran for 2 seconds, used 1 second of CPU, and generated a 1 page job log

I also resubmitted the ACCESSCLP with *NOLIST job logging, and it ran for approximately the same 20-21 seconds, but of course no job log was generated.

Both programs ran in QILE activation group in the same batch subsystem on the same relatively-idle system.

-Gary Patterson
******ACCESSCLP***************
Daccess           PR                  extproc('ACCESS2')
Dpath                          100A                     
Drc                              1A                     
 *                                                      
DF_OK             S              1A                     
DX                S             10I 0 inz(0)            
Dfile             S            100A                     
 *                                                      
 * Call the CLLE module                                     
 /free                                                  
    file = '/mydir/notthere.txt';                    
    for X = 1 to 100000;                                
       access(file:F_OK);                               
    endfor;                                             
                                                        
    *inlr = *on;                                        
 /end-free                                                    
 
*******ACCESS2 CLLE*******
PGM PARM(&FILE &RC)                            
DCL &FILE *CHAR 100                            
DCL &RC *CHAR 1                                
MOV OBJ(&FILE) TOOBJ(&FILE)                    
MONMSG MSGID(CPFA085 CPFA093 CPFA0B2 CPFA0A9) +
EXEC(CHGVAR VAR(&RC) VALUE('1'))               
ENDPGM                                         
 
*******ACCESSRPG**********
Daccess           PR            10I 0 extproc('access')     
Dpathptr1                         *   value options(*string)
Dmode1                          10I 0 value                 
 *                                                          
 * IFS API Constants                                        
DF_OK             S             10I 0 inz(0)                
Drc               S             10I 0 inz(0)                
DX                S             10I 0 inz(0)                
 *                                                          
 * Call the IFS API                                         
 /free                                                      
    for X = 1 to 100000;                                    
       rc = access('/mydir/notthere.txt':F_OK);          
    endfor;                                                 
                                                            
    *inlr = *on;                                            
 /end-free                                                  

Open in new window

Just out of curiosity, did you also try simply calling access() directly from the CL? ...in a DOFOR loop, of course; not calling the CL thousands of times -- just looping around access().

I call it in various specific cases, but have never checked on a mass basis. Calling access() once in a job has trivial effect, so it doesn't bother me then. I'm not sure I'd ever see reason to do it thousands of times, but it'd still be interesting to know any result.

Tom
Hi Gary,

No disrespect intended. "....but of course the CL method is much slower"
Yes you are right but your guestimate of 21 seconds is not realistic I think.
On an model 820 it will takke a little bit longer to loop it within CL so the CL dont has to be loaded 100000 times.
The used time for that is not even near the 21 seconds.

Regards,
Murph
Murph,

I created a CLLE module, not a CL program, and bound it statically with the RPG module so that it just gets loaded once when the ILE program is loaded - it is a fast bound call, not a dynamic call.

21 seconds is not an estimate.  It is the actual runtime from on a nearly-idle 32-way 595.  I estimated the runtime on the NOLIST option since it didn't generate a joblog, but I timed it at 20 seconds - I could be off by a second either way, but no more.  The reason it takes so long isn't the CL loop or the bound call - it is the time spent handling the exceptions.

Calling the "access" API directly from a CLLE (or any ILE) will give almost identical performance results as the ILE RPG example - very fast.  The key is the use of the bound API call, rather than relying on an error message getting generated like the CL MOV + MONMSG technique.  The MOV+MONMSG technique is what I was referring to when I said "the CL method".  

The OS does a lot of work (executes a lot of lines of code) to handle every exception.

Part of my job is to do application performance analysis and remediation.  One of the things I do when I have programs with long runtimes (batch), poor transaction times or throughput (server) or poor response times (interactive) is to look at the joblog and see how many exceptions I see there, or to check exception counts on performance reports.  When I see big numbers of exceptions, I know that there is runtime to be saved.
 
Of course, if it just gets called once a day, it doesn't matter much.  The problem, though, is when poor-performing code gets copied and used in high volume applications.

Regards,

- Gary Patterson
Hi Gary,

"I created a CLLE module, not a CL program"

The CL program is looping 100,000 times within seconds that's not the problem,
but the MOV command take longer, and to my opionion that makes no diference
if you excute that from a program or a module.
Total time on a 820 to do the MOV of a non existing file 100,000 took rond 5 minutes.

I will try the module next monday, if the module makes that diference I will use modules more often. :)

Have a nice weekend,
Murph
Operating Systems
Operating Systems

Operating systems perform basic tasks, such as recognizing input from the keyboard, sending output to the display screen, keeping track of files and directories on the disk, and controlling peripheral devices such as disk drives and printers. For large systems, the operating system makes sure that different programs and users running at the same time do not interfere with each other. The operating system is also responsible for security, ensuring that unauthorized users do not access the system. Operating systems provide a software platform on top of which other programs, called application programs, can run.

37K
Questions
--
Followers
--
Top Experts
Get a personalized solution from industry experts
Ask the experts
Read over 600 more reviews

TRUSTED BY

IBM logoIntel logoMicrosoft logoUbisoft logoSAP logo
Qualcomm logoCitrix Systems logoWorkday logoErnst & Young logo
High performer badgeUsers love us badge
LinkedIn logoFacebook logoX logoInstagram logoTikTok logoYouTube logo