4GL to Korn shell 2-way communication.

ron

Member
I'm working with Progress 9.1D and Unixware.

I want to have a 4GL program that acts as a "server". A Korn shell script will give it data requests - and the 4GL program will respond with the results.

I've experimented - but can't seem to find a way to get this to work. Can anyone suggest a solution, please?

(I could communicate using files - but I think that would be a bit slow.)

Cheers,
Ron.
 
Yep - named pipes are what I've been experimenting with - but without success. (BTW - I've used named pipes in the past between scripts without a problem.)

Here is what I've been playing with:

ksh script:

# cat test.ksh
#!/usr/bin/ksh93
export ASK=/tmp/ask
export REPLY=/tmp/reply
function isalive {
kill -0 $BKPID >/dev/null 2>/dev/null
STAT=$?
if [[ "x$STAT" != x0 ]]
then
echo "4GL program is dead"
else
echo "4GL program is alive"
fi
}
umask 000
rm -f $ASK
rm -f $REPLY
mknod $ASK p
mknod $REPLY p
chmod 777 $ASK $REPLY
set -x
/u0/dlc/bin/_progres -b -p /u0/DL/bin/test.p > /tmp/othertmp &
BKPID=$!
sleep 3
isalive
echo "abc" >> $ASK
isalive
read ANSA < $REPLY
isalive
print $ANSA
isalive
echo "def" >> $ASK
isalive
read ANSA < $REPLY
isalive
print $ANSA
isalive
echo "ghi" >> $ASK
read ANSA < $REPLY
print $ANSA

read PORZ



And here is the 4GL program:

# cat test.p
DEF VAR w_innod AS CHAR NO-UNDO.
DEF VAR w_outnod AS CHAR NO-UNDO.
DEF VAR w_reply AS CHAR NO-UNDO.
DEF STREAM indata.
DEF STREAM outdata.
DEF STREAM logdata.
ASSIGN w_innod = OS-GETENV("ASK")
w_outnod = OS-GETENV("REPLY").
OUTPUT STREAM logdata TO /tmp/tmplog.
PUT STREAM logdata "Started" SKIP.
INPUT STREAM indata FROM VALUE(w_innod) UNBUFFERED.
OUTPUT STREAM outdata TO VALUE(w_outnod).
PUT STREAM logdata "Streams opened" SKIP.
IMPORT STREAM indata UNFORMATTED w_reply.
EXPORT STREAM outdata "#1: " w_reply.
PUT STREAM logdata "First set done. w_reply:" w_reply FORMAT "x(60)" SKIP.
IMPORT STREAM indata UNFORMATTED w_reply.
EXPORT STREAM outdata "#2: " w_reply.
PUT STREAM logdata "Second set done. w_reply:" w_reply FORMAT "x(60)" SKIP.
IMPORT STREAM indata UNFORMATTED w_reply.
EXPORT STREAM outdata "#3: " w_reply.
INPUT STREAM indata CLOSE.
OUTPUT STREAM outdata CLOSE.

PUT STREAM logdata "Program done" SKIP.



When I execute the script, this is what is displayed:
# ./test.ksh
+ BKPID=6789
+ /u0/dlc/bin/_progres -b -p /u0/DL/bin/test.p
+ sleep 3
+ 1> /tmp/othertmp
+ isalive
4GL program is alive
+ echo abc
+ 1>> /tmp/ask
+ isalive
4GL program is alive
+ read ANSA
+ 0< /tmp/reply
+ isalive
4GL program is dead
+ print '"#1:' '"' '"abc"'
"#1: " "abc"
+ isalive
4GL program is dead
+ echo def


And at that point the script hangs.

The log from the 4GL code is:
# cat tmplog
Started
Streams opened
First set done. w_reply:abc

As you can see - the first send/receive has worked - but then the 4GL program dies - and I don't know why.

Any suggestions very welcome!

Ron. :(
 
It works if you add pauses (you may need additional pauses between each import/export, but this code works for me):

Code:
INPUT STREAM indata FROM VALUE(w_innod) UNBUFFERED.
IMPORT STREAM indata UNFORMATTED w_reply.
PAUSE 1.
OUTPUT STREAM outdata TO VALUE(w_outnod) UNBUFFERED.
EXPORT STREAM outdata "#1: " w_reply .

PAUSE 1.
IMPORT STREAM indata UNFORMATTED w_reply.
EXPORT STREAM outdata  "#2: " w_reply .

PAUSE 1.
IMPORT STREAM indata UNFORMATTED w_reply.
EXPORT STREAM outdata "#3: " w_reply.

INPUT STREAM indata CLOSE.
OUTPUT STREAM outdata CLOSE.
It seems that communicating with named pipes is time-depended and pauses allows to "synchronize" with script. According to KB #16374:

READING FROM THE PIPE
From the 4GL level, any command that modifies a variable can be
used to read from a pipe. For example:
IMPORT STREAM ipipe UNFORMATTED myvar1 NO-ERROR. This will read
one line at a time. The drawback, that is, CAVEAT, to using 4GL to
read from a named pipe is that if the reader is blocked waiting for
data, and the writer closes the named pipe, the reader is returned an
EOF status, and the reader closes the named pipe. This can result in
data loss. Either the reader must never be allowed to detect an EOF
status, or the reading should be done by a low level C routine
through HLI/HLC.

I think you should either create C routines to control pipes, place them in .so lib and use external procedures in 4GL or use C program instead of script to control pipes .
 
Thanks ... but I found the answer in the Progress manual "Progress External Program Interfaces "

The problem appears to be that Progress senses EOF after each receive (of a request) - which makes the current loop exit. So - you have to re-open the pipe each time, like this:

REPEAT:
INPUT STREAM indata FROM VALUE(w_innod) NO-ECHO.
REPEAT:
IMPORT STREAM indata UNFORMATTED w_reply NO-ERROR.
OUTPUT STREAM outdata TO VALUE(w_outnod) APPEND.
EXPORT STREAM outdata w_reply.
OUTPUT STREAM outdata CLOSE.
END.
INPUT STREAM indata CLOSE.
END.

I've changed to use the code as above - and it is now working.

Thanks for the suggestions!

Cheers,
Ron.
 
Back
Top