Question

From my COBOL program, I'm calling my C module which itself makes calls to a proprietary library. This library insists on writing to stderr, although there's no stderr available since the main program is written in COBOL. Consequently, the program aborts with this message:

cannnot open stderr


The support guys at HP advised me to issue

PARAM SAVE-ENVIRONMENT ON

in TACL before running the program. This indeed solved my problem. However, my program will be used by several people in a number of scripts and I don't want to force them to issue PARAM SAVE-ENVIRONMENT ON prior to running the program.

Is there some COBOL85 directive which allows me to properly run the program without changing any parameters manually? Something like

?PARAM SAVE-ENVIRONMENT ON

would be great...

EDIT:

Since I'm able to modify the C module (not the library), I'd be completely satisfied with a C-based solution. However, simply opening stderr before calling the library didn't solve my problem.

Was it helpful?

Solution 3

PARAM SAVE-ENVIRONMENT ON makes HP COBOL-programs save environment variables (which they receive as messages at startup from Guardian) for future calls to getenv() from C modules.

Actually, the library I'm using tries to open stderr because it can't read environment variables. One solution is to set the PARAM SAVE-ENVIRONMENT to ON, so getenv() will properly function again. This has to be done in each TACL session.

Unless: you use the ?SAVE STARTUP- or ?SAVE ALL-directive in your COBOL program to achieve the same effect.

Lessons learned:

  • Don't mix COBOL and C.
  • Don't use COBOL at all.

OTHER TIPS

If you can execute TACL commands from Cobol, that could do it.

Can you open a file in Cobol assinged to stderr? Perhaps discovering exactly what PARAM SAVE-ENVIRONMENT ON does might help as well.

Most of the C contributors are not going to know the operating system on the HP/Tandem, which is going to impact the worth of answers. I have no idea if you can "shell out" from your C program to issue a TACL command or run a TACL script.

A bit of research with your Cobol, TACL, and C manuals for the HP/Tandem might lead you to answers, perhaps a google or two as well.

What is the problem with including the statement in their scripts anyway? If they want the program to work?

Not being an HP NonStop developer, I have some questions. stderr is a special symbol in C. File channel 2 (0 standard in, 1 standard out, 2 standard error), but those are low level channel numbers. stderr is a default pointer to a FILE structure. Falling back to GNU/Linux, /usr/include/stdio.h defines them as

/* Standard streams.  */
extern struct _IO_FILE *stdin;          /* Standard input stream.  */
extern struct _IO_FILE *stdout;         /* Standard output stream.  */
extern struct _IO_FILE *stderr;         /* Standard error output stream.  */
/* C89/C99 say they're macros.  Make them happy.  */
#define stdin stdin
#define stdout stdout
#define stderr stderr

Opening a file named "stderr" isn't the same thing. Any process that is created should have 0, 1, and 2 already open. Should not matter what programming language is used for main. Is HP NonStop that much different than other POSIX-ey systems? stderr (the FILE pointer) is usually global to any code that includes stdio.h

As an aside, coming from an OpenCOBOL and GNU/Linux fanboy: Regarding your other comment on lessons learned,

  • DO mix COBOL and C (and Fortran, and Ada, and Vala, and Python, and Java and ...)
  • DO use COBOL
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top