Using %PROC in an ON-EXIT Routine
Bad Joke of the Month
What can you find shivering at the bottom of the ocean?
A nervous wreck.
Using %PROC in an ON-EXIT Routine
With the Fall 2024 enhancements to RPG, you can now use the %PROC builtin function to get the name of the procedure with the code for an ON-EXIT routine. This was a problem prior to this update because under the covers, IBM implements the ON-EXIT code by generating a subprocedure under-the-covers. Since a subprocedure has a separate procedure name, it didn’t return the name you had in your source code.
In this post, we’ll look at how that is fixed with the Fall 2024 updates.
Background
The ON-EXIT opcode isn’t new, but I will give a brief explanation of it, since I know that many people aren’t using it yet. It allows you to write code that always occurs before a subprocedure ends. The code is run whether the procedure ends successfully (by reaching its end or by using the RETURN opcode) but also runs if the procedure ends with an error.
Typically, you use it to clean up resources or any other work that must be done, regardless of whether the procedure succeeded or failed. For example, suppose you have an application that sets a flag in a data area to indicate that it is running. You need to unset the flag when the code ends, regardless of whether it ends successfully, or whether there’s an error.
**free
ctl-opt dftactgrp(*no) main(MAINPROC);
dcl-s INPROGRESS char(1) dtaara;
dcl-s x int(10);
dcl-s y int(10) inz(0);
dcl-proc MAINPROC;
in *lock INPROGRESS;
INPROGRESS = ‘Y’;
out INPROGRESS;
// do whatever
x = x / y;
on-exit;
in *lock INPROGRESS;
INPROGRESS = ‘N’;
out INPROGRESS;
end-proc;
In this example, I’ve deliberately created a divide-by zero error, but the INPROGRESS data area will be set to N regardless of the fact that the program crashes. If I change the program so that it doesn’t crash, it’ll also set INPROGRESS to N. That flag will always be set properly when it ends.
The Problem
Under-the-covers, IBM implements ON-EXIT by creating a subprocedure named _QRNI_ON_EXIT_xxxxx where xxxxx is the name of the procedure where the on-exit routine was coded. This creates ambiguity with %PROC. Did you want the name of the generated subprocedure? Or did you want the name of the one in the source code where you coded the ON-EXIT?
The Solution
With this new feature, IBM adds keywords of *ONEXIT and *OWNER. When the *ONEXIT keyword is passed to %PROC, it will provide the name of the generated subprocedure. When *OWNER is passed, it will be the subprocedure in your source where you coded the ON-EXIT, or to phrase it differently, the subproedure that “owns” the on-exit routine.
To demonstrate, lets just add some messages to the above ON-EXIT example:
on-exit;
in *lock INPROGRESS;
INPROGRESS = ‘N’;
out INPROGRESS;
snd-msg ‘The generated on-exit code is running as ‘ + %PROC(*ONEXIT);
snd-msg ‘It is coded in the ‘ + %PROC(*OWNER) + ‘ procedure in your source’;
end-proc;
In this case, it will send these messages:
The generated on-exit code is running as _QRNI_ON_EXIT_MAINPROC
It is coded in the MAINPROC procedure in your source
Availability
This feature was added to RPG in Fall 2024. You must be running IBM i 7.5 or 7.4 to use it, and you will need to install the appropriate PTFs to get the Fall 2024 enhancements. You can get the PTF numbers and other details from the RPG Café website, here: https://ibm.biz/rpgcafe_fall_2024_bif_proc_in_on_exit

Scott Klement
Development and Solutions Architect
Scott Klement is an IT professional with a passion for both programming and mentoring. He joined Midrange Dynamics at the beginning of October 2022. He formerly was the Director of Product Development and Support at Profound Logic and the IT Manager and Senior Programmer at Klement’s Sausage Co., Inc. Scott also serves on the Board of Directors of COMMON, where he represents the Education, Innovation, and Certification teams. He is an IBM Champion for Power Systems.