Service Programs, signatures and RTVBNDSRC

I have talked about service programs in the past and, at the time, I mentioned that you need a binding source without really saying why. So, to revisit the subject, using the binding language allows you to change your service program without needing to recompile all of the programs that reference it.

It all comes down to signatures.

You can display the signature of a service program using the following command (adjust for your own library and service program, obviously):

DSPSRVPGM SRVPGM(LSCLIB/LSSUTIL) DETAIL(*SIGNATURE)

This will display a screen similar to the one below:

                      Display Service Program Information
                                                                 Display 1 of 1
 Service program  . . . . . . . . . . . . :   LSSUTIL
   Library  . . . . . . . . . . . . . . . :     LSCLIB
 Owner  . . . . . . . . . . . . . . . . . :   QPGMR
 Service program attribute  . . . . . . . :   RPGLE
 Detail . . . . . . . . . . . . . . . . . :   *SIGNATURE

                                  Signatures:

 62C9C0FAA16B653C4359413F3E9CEB81

Now take a look at any program that references the service program:

DSPPGM PGM(LSCLIB/LS0190R) DETAIL(*SRVPGM)

Will something like this:

                          Display Program Information
                                                                 Display 1 of 1
 Program  . . . . . . . :   LS0190R       Library  . . . . . . . :   LSCLIB
 Owner  . . . . . . . . :   QPGMR
 Program attribute  . . :   RPGLE
 Detail . . . . . . . . :   *SRVPGM


 Type options, press Enter.
   5=Display

      Service
 Opt  Program     Library     Activation  Signature
      LSSUTIL     *LIBL       *IMMED      62C9C0FAA16B653C4359413F3E9CEB81
      QRNXIE      QSYS        *IMMED      D8D9D5E7C9C540404040404040404040
      QRNXIO      QSYS        *IMMED      D8D9D5E7C9D640404040404040404040
      QLEAWI      QSYS        *IMMED      44F70FABA08585397BDF0CF195F82EC1

Note that the signqture of the service program needs to match the signature the referencing program expects, and if they don’t you will waste a day dealing with signature violation errors.

So if I want to add a procedure to a service program (which will change the service program’s signature) without having to identify and recompile every program that refers to it, I need to make use of the binder language.

I generally create the binder language source manually but, if you don’t have this, you can use the RTVBNDSRC command. To retrieve the source for service program LSSUTIL in library LSCLIB you would do this:

RTVBNDSRC SRVPGM(LSCLIB/LSSUTIL) SRCFILE(LSCLIB/QSRVSRC) MBROPT(*ADD)

Then go and look at your binder source and you will a listing of all your exported procedures in a format that looks see something like this:

STRPGMEXP PGMLVL(*CURRENT) SIGNATURE(X'62C9C0FAA16B653C4359413F3E9CEB81')
/********************************************************************/
/*   *MODULE      LSSUTIL      LSCLIB      08/02/18  10:49:27      */
/********************************************************************/
   EXPORT SYMBOL("GETCORRECTION")
   EXPORT SYMBOL("GETERRTEXT")
ENDPGMEXP

Just to tidy things up a bit, move the comment lines to the top and get rid of the SIGNATURE keyword (it’s the PGMLVL that you really need) so that the source now looks like this:

/********************************************************************/
/*   *MODULE      LSSUTIL      LSCLIB      08/02/18  10:49:27      */
/********************************************************************/
STRPGMEXP PGMLVL(*CURRENT)
  EXPORT SYMBOL("GETCORRECTION")
  EXPORT SYMBOL("GETERRTEXT")
ENDPGMEXP

Now you want to tell it that this is the old version and the new current version of the service program contains your shiny new procedure. This is how:

/********************************************************************/
/*   *MODULE      LSSUTIL      LSCLIB      08/02/18  10:49:27      */
/********************************************************************/
STRPGMEXP PGMLVL(*CURRENT)
  EXPORT SYMBOL("GETCORRECTION")
  EXPORT SYMBOL("GETERRTEXT")
  EXPORT SYMBOL("GETSHINY")
ENDPGMEXP
/********************************************************************/
STRPGMEXP PGMLVL(*PRV)
  EXPORT SYMBOL("GETCORRECTION")
  EXPORT SYMBOL("GETERRTEXT")
ENDPGMEXP
/********************************************************************/

Then create your service program using:

CRTSRVPGM SRVPGM(LSCLIB/LSSUTIL) MODULE(LSCLIB/LSSUTIL) SRCFILE(LSCLIB/QSRVSRC) SRCMBR(LSSUTIL)

And display the service program signatures:

DSPSRVPGM SRVPGM(LSCLIB/LSSUTIL) DETAIL(*SIGNATURE)

And here’s what you should have:

                      Display Service Program Information
                                                                 Display 1 of 1
 Service program  . . . . . . . . . . . . :   LSSUTIL
   Library  . . . . . . . . . . . . . . . :     LSCLIB
 Owner  . . . . . . . . . . . . . . . . . :   QPGMR
 Service program attribute  . . . . . . . :   RPGLE
 Detail . . . . . . . . . . . . . . . . . :   *SIGNATURE

                                  Signatures:

 2C9C0F7DED8A1897F656D6C9CBB17DDD
 62C9C0FAA16B653C4359413F3E9CEB81

The service program now has two signatures. The new one is at the top of the list and the previous one is below it. What’s more, I can specify PGMLVL(*PRV) as many times as I need to.

When a program uses the service program, it will look down the list until it finds a signature that matches to identify the list of modules it can use. And this means that you can change your service program as much and as many times as you like without needing to worry about any of the programs that uses it.

A final note

You only need to change your binding source when you change the list of exported procedures (generally by adding a new procedure). Changing an existing procedure won’t impact your signatures.

A final final note

When you do add a new procedure, always add it to the bottom.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.