Handling Errors on IFS using RPGLE |
We can handle the errors while working with ifs. Errors can occur while accessing a file, opening, writing, reading and closing a ifs stream file.
There are two C apis used to get error number and the corresponding message for error handling.
- _errno
- strerror
The C language prototype of __errno in RPGLE
int *__errno(void);
The procedure is called __errno, and this is the error number, usually errno. It returns a ("int *") pointer to an integer. The "void" signifies that there are no parameters.
RPGLE prototype of __errno
D errorifs PR * ExtProc('__errno')
We will use extproc keyword to call the C api __errno by naming it errorifs. In RPGLE program, instead of __errno we will call it as errorifs.
The C language prototype of strerror in RPGLE
char *strerror(int errnum)
strerror() returns a pointer to the char string, that contains an error message for a given errnum, which may be overwritten by a subsequent call to strerror() and errnum refers to an error number that you want to retrieve the error message for.
Please note that error number is returned from __errno procedure and then we pass this returned error number to strerror procedure to get the message corresponds to that error number for better understanding what is the error.
RPGLE prototype of strerror
D strerror PR * ExtProc('strerror') D error_num 10I 0 value
RPGLE program for Handling Errors on IFS
We already create an "IFS Hello World" application. Click here to visit IFS Hello world application in RPGLE. Now, we will do error handling in the same "Hello World" application using the IFS C apis __errno and strerror.
HDFTACTGRP(*NO) D errorifs PR * ExtProc('__errno') D strerror PR * ExtProc('strerror') D error_num 10I 0 value D close PR 10i 0 extproc('close') * D fileds 10i 0 value *file descriptor D write PR 10i 0 extproc('write') * 32 bit, no. of byt D fileds 10i 0 value *file descriptor D buffer * value * pointer to byte D noofbytes 10U 0 value * 32 bits D open PR 10I 0 extproc('open') D ifspath * value options(*string) *ifs path D oflag 10I 0 value *string of 32 bits D mode 10U 0 value options(*nopass) * 9 bits D codepage 10U 0 value options(*nopass) * * <-----oflag----> D O_readonly C 1 D O_writeonly C 2 D O_readwrite C 4 D O_createfileifnotexist... D C 8 D O_exclusivecreate... D C 16 D O_truncateto0bytes... D C 64 D O_appendtofile C 256 D O_converttextbycodepage... D C 8388608 D O_openintextmode... D C 16777216 * * <-----mode----> * owner,group,other (RWX) * owner authority D M_readowner C 256 D M_writeowner C 128 D M_executeowner C 64 * group authority D M_readgroup C 32 D M_writegroup C 16 D M_executegroup C 8 * other people D M_readother C 4 D M_writeother C 2 D M_executeother C 1 * Difspath s 512a Doflag s 10I 0 Dmode s 10U 0 Dcodepage s 10U 0 Dfiledescriptor s 10i 0 Difsdata s 11a inz Dreturn_write s 10i 0 inz Dreturn_close s 10i 0 inz Derror_ptr S * Derror_num S 10I 0 based(error_ptr) Derrormsg_ptr S * Derror_msg S 500a based(errormsg_ptr) C EVAL ifspath = '/home/easyclass/helloworld' C EVAL oflag = O_readwrite + C O_createfileifnotexist C EVAL mode = M_executeowner C EVAL filedescriptor = open(%trim(ifspath): C oflag: C mode) C IF filedescriptor < 0 C EVAL error_ptr = errorIFS() C EVAL errormsg_ptr = strerror(error_num) C RETURN C ENDIF C EVAl ifsdata = 'HELLO WORLD' C EVAL return_write = write(filedescriptor: C %addr(ifsdata):%size(ifsdata)) C IF return_write < %size(ifsdata) C EVAL error_ptr = errorIFS() C EVAL errormsg_ptr = strerror(error_num) C RETURN C ENDIF C EVAL return_close = close(filedescriptor) C IF return_close = -1 C EVAL error_ptr = errorIFS() C EVAL errormsg_ptr = strerror(error_num) C RETURN C ENDIF C EVAL *INLR = *ON C RETURN
HDFTACTGRP(*NO) D errorifs PR * ExtProc('__errno') D strerror PR * ExtProc('strerror') D error_num 10I 0 value D close PR 10i 0 extproc('close') * D fileds 10i 0 value *file descriptor D write PR 10i 0 extproc('write') * 32 bit, no. of byt D fileds 10i 0 value *file descriptor D buffer * value * pointer to byte D noofbytes 10U 0 value * 32 bits D open PR 10I 0 extproc('open') D ifspath * value options(*string) *ifs path D oflag 10I 0 value *string of 32 bits D mode 10U 0 value options(*nopass) * 9 bits D codepage 10U 0 value options(*nopass) * * <-----oflag----> D O_readonly C 1 D O_writeonly C 2 D O_readwrite C 4 D O_createfileifnotexist... D C 8 D O_exclusivecreate... D C 16 D O_truncateto0bytes... D C 64 D O_appendtofile C 256 D O_converttextbycodepage... D C 8388608 D O_openintextmode... D C 16777216 * * <-----mode----> * owner,group,other (RWX) * owner authority D M_readowner C 256 D M_writeowner C 128 D M_executeowner C 64 * group authority D M_readgroup C 32 D M_writegroup C 16 D M_executegroup C 8 * other people D M_readother C 4 D M_writeother C 2 D M_executeother C 1 * Difspath s 512a Doflag s 10I 0 Dmode s 10U 0 Dcodepage s 10U 0 Dfiledescriptor s 10i 0 Difsdata s 11a inz Dreturn_write s 10i 0 inz Dreturn_close s 10i 0 inz Derror_ptr S * Derror_num S 10I 0 based(error_ptr) Derrormsg_ptr S * Derror_msg S 500a based(errormsg_ptr) /free ifspath = '/home/easyclass/helloworld'; oflag = O_writeonly + O_createfileifnotexist; mode = M_executeowner; filedescriptor = open(%trim(ifspath): oflag: mode); if filedescriptor < 0; error_ptr = errorIFS(); errormsg_ptr = strerror(error_num); return; endif; ifsdata = 'HELLO WORLD'; return_write = write(filedescriptor:%addr(ifsdata):%size(ifsdata)); if return_write < %size(ifsdata); error_ptr = errorIFS(); errormsg_ptr = strerror(error_num); return; endif; return_close = close(filedescriptor); if return_close = -1; error_ptr = errorIFS(); errormsg_ptr = strerror(error_num); return; endif; *inlr = *on; return; /end-free
**FREE CTL-OPT DFTACTGRP(*NO); DCL-PR errorifs pointer EXTPROC('__errno'); END-PR; DCL-PR strerror pointer EXTPROC('strerror'); error_num int(10) VALUE; END-PR; DCL-PR close int(10) EXTPROC('close'); fileds int(10) VALUE; END-PR; DCL-PR write int(10) EXTPROC('write'); fileds int(10) VALUE; buffer pointer VALUE; noofbytes uns(10) VALUE; END-PR; DCL-PR open int(10) EXTPROC('open'); ifspath pointer VALUE options(*string); oflag int(10) VALUE; mode uns(10) VALUE options(*nopass); codepage uns(10) VALUE options(*nopass); END-PR; // * <-----oflag----> DCL-C O_readonly 1; DCL-C O_writeonly 2; DCL-C O_readwrite 4; DCL-C O_createfileifnotexist 8; DCL-C O_exclusivecreate 16; DCL-C O_truncateto0bytes 64; DCL-C O_appendtofile 256; DCL-C O_converttextbycodepage 8388608; DCL-C O_openintextmode 16777216; // * <-----mode----> // * owner,group,other (RWX) // * owner authority DCL-C M_readowner 256; DCL-C M_writeowner 128; DCL-C M_executeowner 64; // * group authority DCL-C M_readgroup 32; DCL-C M_writegroup 16; DCL-C M_executegroup 8; // * other people DCL-C M_readother 4; DCL-C M_writeother 2; DCL-C M_executeother 1; DCL-S ifspath CHAR(512); DCL-S oflag int(10); DCL-S mode uns(10); DCL-S codepage uns(10); DCL-S filedescriptor int(10); DCL-S return_close int(10) inz; DCL-S ifsdata char(500) inz; DCL-S return_write int(10) inz; DCL-S error_ptr pointer; DCL-S error_num int(10) based(error_ptr); DCL-S errormsg_ptr pointer; DCL-S error_msg char(500) based(errormsg_ptr); ifspath = '/home/easyclass/helloworld'; oflag = O_writeonly + O_createfileifnotexist; mode = M_executeowner; filedescriptor = open(%trim(ifspath): oflag: mode); if filedescriptor < 0; error_ptr = errorIFS(); errormsg_ptr = strerror(error_num); return; endif; ifsdata = 'HELLO WORLD'; return_write = write(filedescriptor:%addr(ifsdata):%size(ifsdata)); if return_write < %size(ifsdata); error_ptr = errorIFS(); errormsg_ptr = strerror(error_num); return; endif; return_close = close(filedescriptor); if return_close = -1; error_ptr = errorIFS(); errormsg_ptr = strerror(error_num); return; endif; *inlr = *on; return;
We will call the errorifs() procedure i.e. _errno C api followed by strerror(error_number) procedure call with the open(), write() and close() api call in the above example code to retrieve the error number and error message for the error number if any error occurs during open, write and close ifs stream file.
DCL-S error_ptr pointer; DCL-S error_num int(10) based(error_ptr);
error_ptr = errorIFS();
Just take a look at the calls to these error handling apis. When we call errorIFS() procedure i.e. (_errno) we get the pointer wich gets recieved in error_ptr varibale and integer variable error_num is based on this error_ptr variable. Therefore, we recieved error number in the error_num integer variable by the procedure.
DCL-S errormsg_ptr pointer; DCL-S error_msg char(500) based(errormsg_ptr);
errormsg_ptr = strerror(error_num);
Once we get the error number using errorIFS() procedure i.e. (_errno) we pass this error_num to the procedure strerror() as an input parameter and we then recieve a pointer errormsg_ptr from this call and character variable error_msg is based on this pointer variable errormsg_ptr. Therefore, we recieve the actual error message corresponding to ther error number.