Discussion:
C errno from COBOL
(too old to reply)
Frank Swarbrick
2018-10-10 22:36:37 UTC
Permalink
Does anyone know of a simple way to retrieve the value of the C runtime's 'errno' variable after calling a C RTE function from Enterprise COBOL?

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Frank Swarbrick
2018-10-10 22:39:38 UTC
Permalink
I don't have a license to use the XL C compiler, by the way.

________________________________
From: IBM Mainframe Discussion List <IBM-***@LISTSERV.UA.EDU> on behalf of Frank Swarbrick <***@OUTLOOK.COM>
Sent: Wednesday, October 10, 2018 4:36 PM
To: IBM-***@LISTSERV.UA.EDU
Subject: C errno from COBOL

Does anyone know of a simple way to retrieve the value of the C runtime's 'errno' variable after calling a C RTE function from Enterprise COBOL?

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Charles Mills
2018-10-10 23:06:51 UTC
Permalink
Looking at errno.h, errno is #defined as the result of a function call that
you might be able to do from COBOL. I am not adept enough to make sense out
of the macro and say "this call is what you need to do." Perhaps someone
else on this list is. The macro logic is fairly long and convoluted and I am
reluctant to post that much Copyright IBM intellectual property here.

If I am reading it right, it defines _Gtab as a function that takes a 32-bit
signed integer and returns the address of an address.

Then errno is defined as a 32-bit integer at that second address after
calling _Gtab with a 0.

Others can probably do better, but you might try playing with that.

Charles


-----Original Message-----
From: IBM Mainframe Discussion List [mailto:IBM-***@LISTSERV.UA.EDU] On
Behalf Of Frank Swarbrick
Sent: Wednesday, October 10, 2018 3:39 PM
To: IBM-***@LISTSERV.UA.EDU
Subject: Re: C errno from COBOL

I don't have a license to use the XL C compiler, by the way.

________________________________
From: IBM Mainframe Discussion List <IBM-***@LISTSERV.UA.EDU> on behalf of
Frank Swarbrick <***@OUTLOOK.COM>
Sent: Wednesday, October 10, 2018 4:36 PM
To: IBM-***@LISTSERV.UA.EDU
Subject: C errno from COBOL

Does anyone know of a simple way to retrieve the value of the C runtime's
'errno' variable after calling a C RTE function from Enterprise COBOL?

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Charles Mills
2018-10-10 23:19:53 UTC
Permalink
_Gtab appears to be an LE internal function whose address is in the word at
CEELAA offset X'20'. Is that something you can work with?

Charles


-----Original Message-----
From: IBM Mainframe Discussion List [mailto:IBM-***@LISTSERV.UA.EDU] On
Behalf Of Charles Mills
Sent: Wednesday, October 10, 2018 4:06 PM
To: IBM-***@LISTSERV.UA.EDU
Subject: Re: C errno from COBOL

Looking at errno.h, errno is #defined as the result of a function call that
you might be able to do from COBOL. I am not adept enough to make sense out
of the macro and say "this call is what you need to do." Perhaps someone
else on this list is. The macro logic is fairly long and convoluted and I am
reluctant to post that much Copyright IBM intellectual property here.

If I am reading it right, it defines _Gtab as a function that takes a 32-bit
signed integer and returns the address of an address.

Then errno is defined as a 32-bit integer at that second address after
calling _Gtab with a 0.

Others can probably do better, but you might try playing with that.

Charles


-----Original Message-----
From: IBM Mainframe Discussion List [mailto:IBM-***@LISTSERV.UA.EDU] On
Behalf Of Frank Swarbrick
Sent: Wednesday, October 10, 2018 3:39 PM
To: IBM-***@LISTSERV.UA.EDU
Subject: Re: C errno from COBOL

I don't have a license to use the XL C compiler, by the way.

________________________________
From: IBM Mainframe Discussion List <IBM-***@LISTSERV.UA.EDU> on behalf of
Frank Swarbrick <***@OUTLOOK.COM>
Sent: Wednesday, October 10, 2018 4:36 PM
To: IBM-***@LISTSERV.UA.EDU
Subject: C errno from COBOL

Does anyone know of a simple way to retrieve the value of the C runtime's
'errno' variable after calling a C RTE function from Enterprise COBOL?

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Charles Mills
2018-10-11 14:13:57 UTC
Permalink
It occurs to me that you do not need ongoing access to the Z C compiler,
just "one time." The output of the compiler is not IBM licensed code, nor
would the below depend on the C compiler, just on LE.

Here, untested, is what you need:

int GetErrno()
{
return errno;
}

Get access to the Z C compiler, or befriend someone who has access to the Z
C compiler, create yourself the above little library routine, and you are
set "forever" with COBOL access to C errno. (Not me. I would have done it
for you a month ago but presently I am at a delicate moment with regard to
IP rights.)

I have no idea what your personal "legal environment" is -- that is, are you
in some big company that would lose its mind trying to understand the above
and the legalities involved.

Charles

-----Original Message-----
From: IBM Mainframe Discussion List [mailto:IBM-***@LISTSERV.UA.EDU] On
Behalf Of Frank Swarbrick
Sent: Wednesday, October 10, 2018 3:39 PM
To: IBM-***@LISTSERV.UA.EDU
Subject: Re: C errno from COBOL

I don't have a license to use the XL C compiler, by the way.

________________________________
From: IBM Mainframe Discussion List <IBM-***@LISTSERV.UA.EDU> on behalf of
Frank Swarbrick <***@OUTLOOK.COM>
Sent: Wednesday, October 10, 2018 4:36 PM
To: IBM-***@LISTSERV.UA.EDU
Subject: C errno from COBOL

Does anyone know of a simple way to retrieve the value of the C runtime's
'errno' variable after calling a C RTE function from Enterprise COBOL?

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Allan Kielstra
2018-10-11 19:21:23 UTC
Permalink
Hi Frank:

I'm not sure if this will work for all times and in all cases.

Here is my C program simulating a C API that sets errno:

#include <errno.h>

int cfunc()
{
errno = 8;
}

Compiled with no options with z/OS V2.3 XL C/C++

Here is a small COBOL program I wrote
CBL PGMNAME(LongMixed)
Identification Division.
program-id. "FS".
Data Division.
Working-Storage Section.
1 pointer-to-errno usage pointer.
Linkage Section.
1 errno pic S9(9) COMP-5.
Procedure Division.
Display "Calling dummy C API"
Call "cfunc"
Call "__errno" returning pointer-to-errno
Set Address Of errno To pointer-to-errno
Display "errno = " errno
stop run.
End program "FS".

I call my C program to simulate calling a C API. Then, I call __errno which appears to return the address of errno. I compiled this with V6.2 with no options other than what is in the CBL card. I compiled, bound and ran on USS. The result of the run is:

$ ./a.out
Calling dummy C API
errno = 0000000008
$

Try it and if it works, great but put in some comments that say that this relies on some implementation behaviour. (I'm Canadian and that's how we spell that last word.)

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Frank Swarbrick
2018-10-11 21:35:02 UTC
Permalink
Thanks Allan, that looks to do the trick!

I was going to ask how you found the __errno() function, but now I see it in errno.h:

#ifndef __NO_STATIC
#undef errno
extern int errno;
extern int *__errno(void);
#define errno (*__errno())
#endif

It's defined later than the stuff Charles was talking about, so both of us missed it.

Great!

Frank

________________________________
From: IBM Mainframe Discussion List <IBM-***@LISTSERV.UA.EDU> on behalf of Allan Kielstra <***@CA.IBM.COM>
Sent: Thursday, October 11, 2018 1:21 PM
To: IBM-***@LISTSERV.UA.EDU
Subject: Re: C errno from COBOL

Hi Frank:

I'm not sure if this will work for all times and in all cases.

Here is my C program simulating a C API that sets errno:

#include <errno.h>

int cfunc()
{
errno = 8;
}

Compiled with no options with z/OS V2.3 XL C/C++

Here is a small COBOL program I wrote
CBL PGMNAME(LongMixed)
Identification Division.
program-id. "FS".
Data Division.
Working-Storage Section.
1 pointer-to-errno usage pointer.
Linkage Section.
1 errno pic S9(9) COMP-5.
Procedure Division.
Display "Calling dummy C API"
Call "cfunc"
Call "__errno" returning pointer-to-errno
Set Address Of errno To pointer-to-errno
Display "errno = " errno
stop run.
End program "FS".

I call my C program to simulate calling a C API. Then, I call __errno which appears to return the address of errno. I compiled this with V6.2 with no options other than what is in the CBL card. I compiled, bound and ran on USS. The result of the run is:

$ ./a.out
Calling dummy C API
errno = 0000000008
$

Try it and if it works, great but put in some comments that say that this relies on some implementation behaviour. (I'm Canadian and that's how we spell that last word.)

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Frank Swarbrick
2018-10-11 22:06:20 UTC
Permalink
Looks like you can also use call '@@ERRNO' if you don't want to specify PGMNAME(LongMixed).

________________________________
From: IBM Mainframe Discussion List <IBM-***@LISTSERV.UA.EDU> on behalf of Frank Swarbrick <***@OUTLOOK.COM>
Sent: Thursday, October 11, 2018 3:34 PM
To: IBM-***@LISTSERV.UA.EDU
Subject: Re: C errno from COBOL

Thanks Allan, that looks to do the trick!

I was going to ask how you found the __errno() function, but now I see it in errno.h:

#ifndef __NO_STATIC
#undef errno
extern int errno;
extern int *__errno(void);
#define errno (*__errno())
#endif

It's defined later than the stuff Charles was talking about, so both of us missed it.

Great!

Frank

________________________________
From: IBM Mainframe Discussion List <IBM-***@LISTSERV.UA.EDU> on behalf of Allan Kielstra <***@CA.IBM.COM>
Sent: Thursday, October 11, 2018 1:21 PM
To: IBM-***@LISTSERV.UA.EDU
Subject: Re: C errno from COBOL

Hi Frank:

I'm not sure if this will work for all times and in all cases.

Here is my C program simulating a C API that sets errno:

#include <errno.h>

int cfunc()
{
errno = 8;
}

Compiled with no options with z/OS V2.3 XL C/C++

Here is a small COBOL program I wrote
CBL PGMNAME(LongMixed)
Identification Division.
program-id. "FS".
Data Division.
Working-Storage Section.
1 pointer-to-errno usage pointer.
Linkage Section.
1 errno pic S9(9) COMP-5.
Procedure Division.
Display "Calling dummy C API"
Call "cfunc"
Call "__errno" returning pointer-to-errno
Set Address Of errno To pointer-to-errno
Display "errno = " errno
stop run.
End program "FS".

I call my C program to simulate calling a C API. Then, I call __errno which appears to return the address of errno. I compiled this with V6.2 with no options other than what is in the CBL card. I compiled, bound and ran on USS. The result of the run is:

$ ./a.out
Calling dummy C API
errno = 0000000008
$

Try it and if it works, great but put in some comments that say that this relies on some implementation behaviour. (I'm Canadian and that's how we spell that last word.)

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
t***@gmail.com
2018-10-12 15:39:59 UTC
Permalink
As Frank mentioned, you can call '@@ERRNO' instead of '__errno' so you don't need to change the PGMNAME option. However, the call must be static as the run-time libraries don't include the module. Here's where >>CALLINTERFACE STATIC comes in handy.
Charles Mills
2018-10-11 22:15:35 UTC
Permalink
I remembered it as something like the below, simpler than the mess that I
found. That's why I went looking. But when I found what I did find I figured
that was what I recalled.

Charles


-----Original Message-----
From: IBM Mainframe Discussion List [mailto:IBM-***@LISTSERV.UA.EDU] On
Behalf Of Frank Swarbrick
Sent: Thursday, October 11, 2018 2:35 PM
To: IBM-***@LISTSERV.UA.EDU
Subject: Re: C errno from COBOL

Thanks Allan, that looks to do the trick!

I was going to ask how you found the __errno() function, but now I see it in
errno.h:

#ifndef __NO_STATIC
#undef errno
extern int errno;
extern int *__errno(void);
#define errno (*__errno())
#endif

It's defined later than the stuff Charles was talking about, so both of us
missed it.

Great!

Frank

________________________________
From: IBM Mainframe Discussion List <IBM-***@LISTSERV.UA.EDU> on behalf of
Allan Kielstra <***@CA.IBM.COM>
Sent: Thursday, October 11, 2018 1:21 PM
To: IBM-***@LISTSERV.UA.EDU
Subject: Re: C errno from COBOL

Hi Frank:

I'm not sure if this will work for all times and in all cases.

Here is my C program simulating a C API that sets errno:

#include <errno.h>

int cfunc()
{
errno = 8;
}

Compiled with no options with z/OS V2.3 XL C/C++

Here is a small COBOL program I wrote
CBL PGMNAME(LongMixed)
Identification Division.
program-id. "FS".
Data Division.
Working-Storage Section.
1 pointer-to-errno usage pointer.
Linkage Section.
1 errno pic S9(9) COMP-5.
Procedure Division.
Display "Calling dummy C API"
Call "cfunc"
Call "__errno" returning pointer-to-errno
Set Address Of errno To pointer-to-errno
Display "errno = " errno
stop run.
End program "FS".

I call my C program to simulate calling a C API. Then, I call __errno
which appears to return the address of errno. I compiled this with V6.2
with no options other than what is in the CBL card. I compiled, bound and
ran on USS. The result of the run is:

$ ./a.out
Calling dummy C API
errno = 0000000008
$

Try it and if it works, great but put in some comments that say that this
relies on some implementation behaviour. (I'm Canadian and that's how we
spell that last word.)

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Loading...