Midrange News for the IBM i Community

IBM Finally Ships a Few API Prototypes for RPG IV Published by: Bob Cozzi on 19 Apr 2011 view comments
© 2011 Robert Cozzi, Jr. All rights reserved.

© Robert Cozzi, Jr. All rights reserved. Reproduction/Redistribution prohibited.
A midrangeNews.com Publication

API Prototypes by IBM - WTH?

20 Years Late? Better Late than Never

Could it be? After 20+ years of APIs on this platform, IBM has decided to provide a taste of what it would be like if they supplied prototypes in RPG IV for a handful of these interfaces? Turns out, they have! Starting with V6R1, IBM began shipping what amounts to a teaser of API prototypes written in RPG IV.

When I started working on the APIs with the Ron Fess and the late Dick Baines back in the 1980s, RPG IV wasn't even on the drawing board. We did have "System C" a high-speed, low-level interface to the MI language. To allow any of the APIs to work with "System C" IBM had to write prototypes. But for RPGIII, there was no such animal.

Jump ahead to V2R3 and the introduction of ILE (Integrated Language Environment) where IBM attempted to get things like COBOL, and ILE C/400 (which was different from "System C") to run faster--they also wanted the program-to-program CALL interface to run faster. So they built ILE. In the beginning, program-to-program CALLs were faster, however, the extra start-up of the Activation Group (a key part of ILE) actually caused ILE program-to-program CALLs to be slower than the old method. Top that off with the fact that ILE programs were 4 to 6 times larger than the original RPGIII programs when compiled, well, you can see why some 18 years later, we still have shops that haven't moved to RPGIV (aka "ILE RPG").

But the days of expensive 300MB disk drives is over--DASD is cheap, relatively speaking, and no one seems to care if a program is 100k or 1MB in size anymore. But just over a decade ago, that was a huge issue.

Sponsored by: RPG xTools

Enjoy Programming Again! RPG xTools is a collection of subprocedures written by RPG IV author Bob Cozzi. Just add the binding directory and a /COPY statement and you'll have access to more than 200 RPG IV and CGI (that's right Web) subprocedures. Everything from converting a database record to CSV format within RPG, to uploading a photo from a webpage--it all works, time-tested.

Get a 30-day free, no obligation trial of RPG xTools here.

API Usage Flourished

At a COMMON Conference in the late 1980s, IBM Rochester ask me to do a session on "Openness APIs". It was a pretty typical sized crowd from one of my sessions back then, about 600 people attended. Today, you barely have that many paid attendees at a conference.

But the title of that session stuck, and the feature known as "Openness APIs" became important to the evolution of CPF, OS/400 and now "IBM i" operating system. So much so, that IBM started shipping "Openness Includes" as an installation option with the operating system. Most shops know about this option and install it when they upgrade their OS. Some, however don't know, largely because they never page down on the install screen, to see Option 11, "Openness Includes".

Openness Includes

When you selected the System Openness Includes (option 13) during an operating system install/upgrade it installs the QSYSINC library onto your system. That library contains source files (no executable objects) that may be used when creating programs that use any of the vast library of APIs.

To RPGIII developers this means it includes data structures in its QRPGSRC file that can be used to receive data returned from the various APIs.

To C developers it not only contains all the data structures for every API, but it also includes a corresponding prototype for every API and exposed C runtime function.

To RPG IV developers, until V6R1, it meant the same data structures used for RPGIII where available to RPG IV. In fact, it looked like IBM simply ran the data structures through the CVTRPGSRC command and published them. Not "fixing" them of Integer variables instead of the incorrect "B" data-types. They also left in the from/to column notation for good measure. #FAIL.

Enter V6R1 API Prototypes for RPG IV

After 20+ years of APIs and nearly 18 years of RPG IV, some smart person at IBM finally realized that most application code written for this platform is written with RPG IV and shipping prototypes in RPG IV is a good idea. Yes, IBM is shipping API Prototypes in RPG IV syntax beginning with V6R1, but only for a handful of interfaces--interfaces that are really C runtime functions. But who cares? They're useful to RPG IV and that's great news.

The first batch of APIs to ship with RPG IV prototypes include:

  • IFS Interfaces
  • Date/Time Runtime Functions
  • Threaded/Semaphore Programming

The first two classes of interfaces, IFS and date/time functions have been prototyped in RPG IV for years. I've included them in so many different downloads that I have probably forgotten some of the locations. The current group of available, free downloads of prototypes includes the RPGxTools.com and RPGOpen.com websites. When I say they include prototypes for these APIs, they are not limited to the APIs for which IBM now provides RPG IV prototypes.

The third set of API Prototypes IBM is provided is for multi-threaded programming. This type of programming is so rare, and so specialized that if you know about it, you don't need me to explain it to you. If you don't know about it, you probably need to go buy a book on the subject because I'm not expert. The most multithreaded development I've done is writing CodeStudio, a Windows-based RPG, DDS and CL editor that did background uploads and compiles of source code--similar to what RDi/RDp does today.

Let's go over the first two sets of API Prototypes that are now provided by IBM as of IBM i V6R1.

Useful IFS API Prototypes

A popular presentation I've been giving at User Group meetings recently is my "Simplified IFS APIs" session. This session covers the basic IFS APIs--giving you the kind of information you need to start using the OPEN/READ/WRITE/CLOSE IFS interfaces immediately. I started doing this session in response to conference attendees complaining that (A) they wished I would do a session on the IFS because (B) the others who were giving sessions on IFS seemed to be more interested in showing "how much smarter they are than you" instead of trying to teach people about the IFS.

Psst, here is a secret about some 3rd-party seminars: They give the same sessions year after year, changing little more than the session title and in some cases, rotate the instructor. All this in hope you won't notice that nothing has really changed. But I digress.

The basic IFS interfaces: open, read, write, and close are really all you need to get started using the IFS, but they are not all the APIs for the IFS. There are a couple of others, such as opendir, readdir, rewinddir, and closedir that allow you to process a list of files in an IFS directory; there are also APIs that allow you to delete, rename, link to, retrieve information about and grant/revoke authority to IFS objects.

It is great to see IBM shipping IFS APIs with V6R1 and later. To see if you have them installed on your system, bring up PDM or RDi and navigate to the QSYSINC library and open a member list for the QRPGLESRC source file. Navigate to the source member in QRPGLESRC named "IFS" and open it. If it contains the following lines of code, and you are running at least V6R1, you have the prototypes installed on your system.


There are no prototypes in the IFS source member itself, but rather it includes nested /COPY statements. If you include the IFS source member in your own code, as follows, your programs will have access to the IBM-supplied IFS prototypes. Here's how it might look in your own code:


If you are using embedded SQL, you may want to change the above /COPY to a /INCLUDE directive. I tend to only use /INCLUDE lately, as I use a lot of RPG IV with embedded SQL, and this really helps avoid some SQL precompiler limitations.

Remember, beginning with V6R1, you no longer need to specify BNDDIR('QC2LE') when using a C runtime library function. You can still included it, so there's no reason to worry about changing code you already have, but removing it or avoiding it is also okay.

The IFS file APIs are spread out among 3 of the included source members. While this is a disappointment it was probably done to provide a level of compatibility with how the C runtime is shipped. Fortunately we can include just the IFS source member and we get everything we need, and that is a nice feature.

The FCNTL source member has most of the named constants and prototypes you need to make the IFS APIs work. Just having all those named constants finally declared for us is a huge benefit, in my opinion. The rest of the IFS File APIs are spread out among the other source members. I've provided a quick summary of the IFS-related prototypes and their parent source member below:

FCNTL API Prototypes

API Description
creat Create a file on the IFS
open Open an IFS file
QlgCreat Create an IFS file using national language support
QlgOpen Open an IFS file using national language support
Qp0lOpen Open an IFS file using the Unix-style API

The FCNTL and UNISTD source members have the core IFS API prototypes stored in them. FCNTL has the open API, while UNISTD has the read, write and close prototypes.

UNISTD API Prototypes

API Description
chdir Change Current Directory (same as CD or CHDIR CL commands)
chown Change Object Owner(same as CHGOWN CL command)
close Close IFS file
read Read data from an IFS file previously opened with open or open64
write Write to an IFS file

As you can see, in addition to the basic IFS API prototypes, there are several other supporting API prototypes included in these source members. Functions such as change current directory, change owner, and a host of others are included, particularly in UNISTD. UNISTD contains not only these IFS API prototypes, it also contains a slew of other often-used C runtime functions, including:  sleep, getdomainname, link, lseek, rmdir, and unlink.

The SYSSTAT source member has another set of prototypes, including: lstat, and mkdir, while ERRNO contains the prototypes and other declarations for C runtime errors, including: __errno and perror and a host of named constants representing the C runtime error numbers. On errno-related API for which they do not provide a prototype is strerror. This API converts that numeric errno value into a text string--sort of the C version of message text. I use it often to write the message in plain words out to the joblog or to store it into a variable for viewing while in debug. The prototype for strerror follows:

     D strerror        PR              *   extProc('strerror') 
     D  errno                        10I 0 Value

The strerror function converts the error number returned by errno into its text message. However, if you only want to write the error message to the joblog, then the perror API (the prototype for which is provided by IBM in the ERRNO source member) is a better choice. Rather than call errno and then convert it to a string using strerror, you may simply write the error message text to the joblog by calling perror directly. The perror API adds a colon to the text you pass to it and then includes the message text for the most current errno. For example, if an open to an IFS file fails, you might code something like the following:

	   fd = open('/home/cozzi/sales.xml');
	   if (fd < 0);
	      perror("Could not open SALES.XML file"); 

I've never seen the perror API actually produce anything in the joblog, so I tend to stick with strerror and then call the JOBLOG subprocedure in RPG xTools or RPG Open.

The final source member that contains IFS-related stuff is SYSTYPES. It contains the declarations for named constants and data structures you would need for some of the other C runtime APIs.

Time Prototypes

Unlike the IFS API Prototypes, the TIME APIs are consolidated in the TIME source member, again in QRPGLESRC in the QSYSINC library. To include them in your own program, specify the following /COPY statement up in your Definition specifications:


The prototypes provided in this source member are for the C runtime library date and time functions. These are mostly useful when doing web/CGI programming where you need to convert the time from some non-RPG style format to a true date or time data-type. They also provide the tools you need to convert the other way--from a true date or time value into something more textual in nature (such as GMT for time stamping a browser Cookie).

The TIME source member includes the definition of the tm structure from the C language. It properly declares its subfields as 10i0 values, but names the structure STRUCT_TM instead of "TM" or perhaps the RPG IV-standardized "TM_T". Hopefully as new structures are introduced this will be a standard naming convention and not a "whatever the develop felt like using this week" naming standard.

The other important structured used in many of the C time APIs is the time_t structure. That structure is defined in the SYSTYPES source member, and is /COPY'd into the TIME source member. So including the TIME source member into your own RPG IV code is all you need to do.

To avoid name conflicts, IBM choose to declare the time_t and more than a dozen other C language structures within a data structure named SYS_TYPES in the SYSTYPES source member. However, that structure is not QUALIFIED, therefore those subfields are not contained/scoped to the SYS_TYPES data structure. So I'm not sure why they did it this way. Scoping it to SYS_TYPES.TIME_T would make sense, but you actually have to specify it as TIME_T when referring to it. So that's a design point that is lost on me.

The good news is that a TIME_T structure is simply a 10I0 value anyway, so replicating it yourself isn't rocket science.

STRFTIME Prototype

One of the APIs I've used in RPG xTools for more than a decade now, is the strftime C runtime function. This function merges a date/time value with a text formatting pattern to produce a nicely formatted string that contains your own text and the date/time value. It can convert the date/time value to words or numbers and has proven to be very useful in both web/CGI programming and regular old green screen project. Here is an example of what you can get from strftime function:

"Last sign on was on Tuesday, 19 April 2011 at 1402 hours"
"Order is scheduled to ship on Wed, April 20th 2011 at 3:00 PM"

It really is a powerful API and I'm happy IBM is including this prototype on every system running V6R1 or later.

Quality of the IBM Prototypes

It appears to me that the author of these prototypes was learning as they were writing them; some have the contemporary *CWIDEN associated with them even though that keyword is not needed, and then others, presumably written later, do not have *CWIDEN. The only time *CWIDEN is needed in an RPG prototype is when a 5i0 or 5u0 or character parameter or return value is declared; and only when a subprocedure (i.e., not a *PGM API) is called. Most (all?) of the APIs associated with the IFS and date/time interfaces use 10i0 values, so *CWIDEN doesn't apply. The good news is its use here is benign.

The bottom line, if you are running IBM i version 6.1 or later, use: /COPY QSYSINC/QRPGLESRC,IFS to include the RPG IV IFS prototypes, or to include the RPG IV C Date/Time functions' prototypes  provide by IBM. They're good enough. If you don't have V6R1 on your system or later, download the free RPGOpen service program, it contains many of the RPG Prototypes for these C runtime functions. And of course, if you have a license for RPG xTools, you also already have most of these prototypes on your system. 

You're welcome!

Call Me

Bob Cozzi accepts your questions for use in future RPG Report articles or content for midrangeNews.com. Topics of interest include: RPG IV, Web development with RPG IV, APIs, C/C++ or anything else IBM i development related (except subfiles, data areas and RPGII/III because Bob doesn't care about that stuff) write your questions using the Feedback link on the midrangeNews.com website. 

You can subscribe to RPG Report (we call it "follow") by visiting the RPG Report page on midrangeNews.com and then click the FOLLOW link in the table of contents for that page. To unsubscribe, simply click that same link. You must be signed up and signed in to midrangeNews.com to start following RPG Report.

Follow Bob Cozzi on Twitter

Return to midrangenews.com home page.
Sort Ascend | Descend