The takedescriptor() and getdescriptor() APIs require that you know the internal job ID of the job that you wish to pass a descriptor to. This topic discusses the QUSRJOBI (Retrieve Job Information) API which we will use to determine the Internal Job Identifier.
The QUSRJOBI API is an 'Work Management API' (most of the other APIs we've worked with have been 'Unix-Type APIs', which makes it somewhat different.
The IBM manual page for QUSRJOBI is located here: http://publib.boulder.ibm.com/pubs/html/as400/v4r5/ic2924/info/apis/qusrjobi.htm
The prototype listed on this page isn't in C format, but rather is in a somewhat 'language-neutral' format. It looks like this:
Parm# | Description | Usage | Data Type |
---|---|---|---|
1 | Receiver variable | Output | Char (*) |
2 | Length of receiver variable | Input | Binary (4) |
3 | Format name | Input | Char (8) |
4 | Qualified job name | Input | Char (26) |
5 | Internal job identifier | Input | Char (16) |
Optional parameter: | |||
6 | Error code | I/O | Char (*) |
QUSRJOBI is actually a program on the system that we need to call (as opposed to a procedure in a service program) The 2nd column of the parameter group listing above tells us whether the parameter is used for "Output" from the API, "Input" to the API, or "I/O" for both input and output.
The Last column explains the data type of the variable used, and that data type's length. A (*) under length indicates that the length can vary, otherwise, the length is the number of bytes to pass.
Since this is a "common gotcha" for people who are calling APIs, I'll say it again. The length is the number of bytes to pass . When it says "Binary(4)", this is NOT the RPG '4B 0' data type. In RPG, '4B 0' means a 4 digit binary number. But, a 4-digit binary number is only 2 bytes long! Instead, a '9B 0' should be passed, or much better yet, a '10I 0' should be passed. In general, the RPG 'I' data type works better for anything called 'binary' than the legacy 'B' data type.
So, the prototype for the QUSRJOBI API will look like this:
D RtvJobInf PR ExtPgm('QUSRJOBI') D RcvVar 32766A options(*varsize) D RcvVarLen 10I 0 CONST D Format 8A CONST D JobName 26A CONST D IntJobID 16A CONST D ErrorCode 32766A options(*varsize)
Note: Each parameter that's to be 'Input' only to the API is marked as 'CONST'. This is always a good idea, as it protects your program from accidental changes, helps to document the usage of the API, and allows you to substitute expressions for the parameters.
The parameters that can vary in size we used the "options(*varsize)" keyword with. This allows us to call the API using different sized variables for each call.
You'll note that QUSRJOBI return's all of it's data in the 'RcvVar' parm, so we need an idea of what format the data will be in. In fact, most APIs can return data in more than one format, and this format is determined by the 'FORMAT' parameter.
Reading more of the IBM manual page tells us that there are many different formats. Since we only need one that returns the internal job id, we can use any of the formats that it allows. The shortest, and best performing format is called 'JOBI0100', so why don't we use that?
The manual tells us that the format of the returned data for QUSRJOBI looks like this:
Offset | |||
---|---|---|---|
Dec | Hex | Type | Field |
0 | 0 | BINARY(4) | Number of bytes returned |
4 | 4 | BINARY(4) | Number of bytes available |
8 | 8 | CHAR(10) | Job name |
18 | 12 | CHAR(10) | User name |
28 | 1C | CHAR(6) | Job number |
34 | 22 | CHAR(16) | Internal job identifier |
50 | 32 | CHAR(10) | Job status |
60 | 3C | CHAR(1) | Job type |
61 | 3D | CHAR(1) | Job subtype |
62 | 3E | CHAR(2) | Reserved |
64 | 40 | BINARY(4) | Run priority |
68 | 44 | BINARY(4) | Time slice |
72 | 48 | BINARY(4) | Default wait |
76 | 4C | CHAR(10) | Purge |
So, we'll make a data structure to use as our receiver variable. That'll help us by separating all of the fields listed above when we get our returned data from the API.
Here's what this data structure should look like:
D dsJobI0100 DS D JobI_ByteRtn 10I 0 D JobI_ByteAvl 10I 0 D JobI_JobName 10A D JobI_UserID 10A D JobI_JobNbr 6A D JobI_IntJob 16A D JobI_Status 10A D JobI_Type 1A D JobI_SbType 1A D JobI_Reserv1 2A D JobI_RunPty 10I 0 D JobI_TimeSlc 10I 0 D JobI_DftWait 10I 0 D JobI_Purge 10A
And, finally, the 'Error Code' data structure. This is used in a lot of different APIs, and is a convienient way to get returned error info.
It looks like this:
D dsEC DS D dsECBytesP 1 4I 0 INZ(256) D dsECBytesA 5 8I 0 INZ(0) D dsECMsgID 9 15 D dsECReserv 16 16 D dsECMsgDta 17 256
Since this prototype & data struct definition don't (directly) have anything to do with sockets, I decided to make a new header file for this API, called 'JOBINFO_H'
If you want to download my copy of JOBINFO_H, you can get it here: http://www.scottklement.com/rpg/socktut/qrpglesrc.jobinfo_h
You call the QUSRJOBI API like this:
C callp RtvJobInf(dsJOBI0100: %size(dsJOBI0100): C 'JOBI0100': '*': *BLANKS: dsEC) c if dsECBytesA > 0 C** Error occurred. Error message number is in dsECMsgID C endif