From: Robert on
The problem: I want to run a Unix command, program or script from Cobol and get its return
code. For example, I want to test whether /usr/tmp is a valid directory. On a shell
command line, I can say 'test -d /usr/tmp' (or ksh shortcut [ -d /usr/tmp ]) followed by
'echo $?'. The result will be 0 if valid, 1 if invalid. When I say the same in a Cobol
program ..

call 'system' using 'test -d /usr/tmp'
if return-code not = zero
display '/usr/tmp is not a valid directory'
set fatal-error to true
end-if

... the return-code is alswya zero.

The solution:

call 'system' using 'test -d /usr/tmp; exit $?'

System() forks a child process, execs it to the default shell (usually sh), feeds it your
command line and waits for it to terminate. It is functionally the same as saying:
sh -c 'test -d /usr/tmp'
The sh shell is supposed to exit by default with the last return code ($?), and system()
is supposed to do the same. There is a bug in one of the two causing that to not work, but
it does work when your command does an explicit exit.

This question came up here two years ago, without a conclusive answer. I opined the return
code should be passed back, Richard thought it was fundamentally impossible for a child
process to pass anything back to its parent. This solution shows I was right.

A further complication is that the system() surrogate supplied Micro Focus Server Express
4.1 running on HP-UX shifts the return code left 8 bits. Thus,
call 'system' using 'exit 123'
returns 31,488, which is 123*256. The 1 returned by the above directory test comes back as
256. At least it's not zero, which is all you care about.
From: Richard on
On Jan 12, 2:53 pm, Robert <n...(a)e.mail> wrote:
> The problem: I want to run a Unix command, program or script from Cobol and get its return
> code. For example, I want to test whether /usr/tmp is a valid directory. On a shell
> command line, I can say 'test -d /usr/tmp' (or ksh shortcut [ -d /usr/tmp ]) followed by
> 'echo $?'. The result will be 0 if valid, 1 if invalid. When I say the same in a Cobol
> program ..
>
> call 'system' using 'test -d /usr/tmp'
> if return-code not = zero
> display '/usr/tmp is not a valid directory'
> set fatal-error to true
> end-if
>
> .. the return-code is alswya zero.
>
> The solution:
>
> call 'system' using 'test -d /usr/tmp; exit $?'
>
> System() forks a child process, execs it to the default shell (usually sh), feeds it your
> command line and waits for it to terminate. It is functionally the same as saying:
> sh -c 'test -d /usr/tmp'
> The sh shell is supposed to exit by default with the last return code ($?), and system()
> is supposed to do the same. There is a bug in one of the two causing that to not work, but
> it does work when your command does an explicit exit.
>
> This question came up here two years ago, without a conclusive answer. I opined the return
> code should be passed back, Richard thought it was fundamentally impossible for a child
> process to pass anything back to its parent. This solution shows I was right.

see * below

> A further complication is that the system() surrogate supplied Micro Focus Server Express
> 4.1 running on HP-UX shifts the return code left 8 bits. Thus,
> call 'system' using 'exit 123'
> returns 31,488, which is 123*256. The 1 returned by the above directory test comes back as
> 256. At least it's not zero, which is all you care about.

The "system() surrogate supplied Micro Focus" is not "system" but is
"SYSTEM" (upper case). CALL "system" is likely to use the C library
routine.

The return from "system" is implementor defined. In Linux this is
defined as being in the "format specified in wait(2)".

I cannot find anything in MF manuals that say what the return from
"SYSTEM" is.


* I looked "two years ago" and found this:

RW> Call SYSTEM to run a script containing two entries: make followed
by
RW> export rc=$?
RW> Then you can interrogate rc to get the compiler's return code.

RP> No, you cannot do that, it will not and does not work.

RP> The 'system' call creates a new shell below the current one. Any
RP> 'export' only changes what is in that new shell and this is
destroyed
RP> before the 'system' returns to the program.

What "will not work" was your 'export=$?' that you expected to survive
the exit and be put into the shell above the Cobol program.


> I opined the return code should be passed back,

It would not be passed back by that mechanism.

> Richard thought it was fundamentally impossible for a child
> process to pass anything back to its parent.

No, you are wrong, yet again. I made no comment at all whether a
return code could be passed back by some means to its parent, I simply
pointed out that the mechanism you described would not, and provably
did not, work.

> This solution shows I was right.

Wrong then, wrong again. Did you not read the rest of the thread where
several people _demonstrated_ that you were wrong.


From: Robert on
On Fri, 11 Jan 2008 22:53:22 -0800 (PST), Richard <riplin(a)azonic.co.nz> wrote:

>On Jan 12, 2:53 pm, Robert <n...(a)e.mail> wrote:
>> The problem: I want to run a Unix command, program or script from Cobol and get its return
>> code. For example, I want to test whether /usr/tmp is a valid directory. On a shell
>> command line, I can say 'test -d /usr/tmp' (or ksh shortcut [ -d /usr/tmp ]) followed by
>> 'echo $?'. The result will be 0 if valid, 1 if invalid. When I say the same in a Cobol
>> program ..
>>
>> call 'system' using 'test -d /usr/tmp'
>> if return-code not = zero
>> display '/usr/tmp is not a valid directory'
>> set fatal-error to true
>> end-if
>>
>> .. the return-code is alswya zero.
>>
>> The solution:
>>
>> call 'system' using 'test -d /usr/tmp; exit $?'
>>
>> System() forks a child process, execs it to the default shell (usually sh), feeds it your
>> command line and waits for it to terminate. It is functionally the same as saying:
>> sh -c 'test -d /usr/tmp'
>> The sh shell is supposed to exit by default with the last return code ($?), and system()
>> is supposed to do the same. There is a bug in one of the two causing that to not work, but
>> it does work when your command does an explicit exit.
>>
>> This question came up here two years ago, without a conclusive answer. I opined the return
>> code should be passed back, Richard thought it was fundamentally impossible for a child
>> process to pass anything back to its parent. This solution shows I was right.
>
>see * below
>
>> A further complication is that the system() surrogate supplied Micro Focus Server Express
>> 4.1 running on HP-UX shifts the return code left 8 bits. Thus,
>> call 'system' using 'exit 123'
>> returns 31,488, which is 123*256. The 1 returned by the above directory test comes back as
>> 256. At least it's not zero, which is all you care about.
>
>The "system() surrogate supplied Micro Focus" is not "system" but is
>"SYSTEM" (upper case). CALL "system" is likely to use the C library routine.

I used lower case.

>The return from "system" is implementor defined. In Linux this is
>defined as being in the "format specified in wait(2)".

Which is a pid_t: an integer containing the child's process id. What I get back is
WEXITSTATUS() in the left byte and zero in the right byte.

>I cannot find anything in MF manuals that say what the return from
>"SYSTEM" is.

I assume it's the same as the C function.

>* I looked "two years ago" and found this:
>
>RW> Call SYSTEM to run a script containing two entries: make followed
>by
>RW> export rc=$?
>RW> Then you can interrogate rc to get the compiler's return code.
>
>RP> No, you cannot do that, it will not and does not work.
>
>RP> The 'system' call creates a new shell below the current one. Any
>RP> 'export' only changes what is in that new shell and this is
>destroyed
>RP> before the 'system' returns to the program.
>
>What "will not work" was your 'export=$?' that you expected to survive
>the exit and be put into the shell above the Cobol program.

You're correct about that.

>> I opined the return code should be passed back,
>
>It would not be passed back by that mechanism.

Yes, but it should be passed back by the wait() mechanism, which is used by system().

>> Richard thought it was fundamentally impossible for a child
>> process to pass anything back to its parent.
>
>No, you are wrong, yet again. I made no comment at all whether a
>return code could be passed back by some means to its parent, I simply
>pointed out that the mechanism you described would not, and provably
>did not, work.

True, but not helpful. The number of things that don't work is infinity minus 1. It can be
made to work by coding an explicit exit.

>> This solution shows I was right.
>
>Wrong then, wrong again. Did you not read the rest of the thread where
>several people _demonstrated_ that you were wrong.

That discussion was about running the make program to do a compilation. It would have been
helpful if someone had pointed out how to add .cbl to the suffix list, which would enable
writing a rule to compile all Cobol programs. It is done like this:

targets=prog1.so prog2.so prog3.so
..SUFFIXES:.cbl .so

..cbl.so: cob -z $< # this is a rule

$(targets) # this line compiles all stale targets
From: Richard on


Robert wrote:
> On Fri, 11 Jan 2008 22:53:22 -0800 (PST), Richard <riplin(a)azonic.co.nz> wrote:
>
> >On Jan 12, 2:53 pm, Robert <n...(a)e.mail> wrote:
> >> The problem: I want to run a Unix command, program or script from Cobol and get its return
> >> code. For example, I want to test whether /usr/tmp is a valid directory. On a shell
> >> command line, I can say 'test -d /usr/tmp' (or ksh shortcut [ -d /usr/tmp ]) followed by
> >> 'echo $?'. The result will be 0 if valid, 1 if invalid. When I say the same in a Cobol
> >> program ..
> >>
> >> call 'system' using 'test -d /usr/tmp'
> >> if return-code not = zero
> >> display '/usr/tmp is not a valid directory'
> >> set fatal-error to true
> >> end-if
> >>
> >> .. the return-code is alswya zero.
> >>
> >> The solution:
> >>
> >> call 'system' using 'test -d /usr/tmp; exit $?'
> >>
> >> System() forks a child process, execs it to the default shell (usually sh), feeds it your
> >> command line and waits for it to terminate. It is functionally the same as saying:
> >> sh -c 'test -d /usr/tmp'
> >> The sh shell is supposed to exit by default with the last return code ($?), and system()
> >> is supposed to do the same. There is a bug in one of the two causing that to not work, but
> >> it does work when your command does an explicit exit.
> >>
> >> This question came up here two years ago, without a conclusive answer. I opined the return
> >> code should be passed back, Richard thought it was fundamentally impossible for a child
> >> process to pass anything back to its parent. This solution shows I was right.
> >
> >see * below
> >
> >> A further complication is that the system() surrogate supplied Micro Focus Server Express
> >> 4.1 running on HP-UX shifts the return code left 8 bits. Thus,
> >> call 'system' using 'exit 123'
> >> returns 31,488, which is 123*256. The 1 returned by the above directory test comes back as
> >> 256. At least it's not zero, which is all you care about.
> >
> >The "system() surrogate supplied Micro Focus" is not "system" but is
> >"SYSTEM" (upper case). CALL "system" is likely to use the C library routine.
>
> I used lower case.
>
> >The return from "system" is implementor defined. In Linux this is
> >defined as being in the "format specified in wait(2)".
>
> Which is a pid_t: an integer containing the child's process id.

While the format is a pid_t, as I said, the content need not be a pid.

> What I get back is
> WEXITSTATUS() in the left byte and zero in the right byte.

If the return is bigendian, then will a S9(4) COMP-5 give it correctly
by reversing the bytes ?

> >I cannot find anything in MF manuals that say what the return from
> >"SYSTEM" is.
>
> I assume it's the same as the C function.

I don't know why you would make such assumptions. "SYSTEM" does much
more than "system" because it adjusts the ADIS settings. What it
returns is entirely dependent on what MF want it to, and as far as I
can tell, they haven't said.

> >* I looked "two years ago" and found this:
> >
> >RW> Call SYSTEM to run a script containing two entries: make followed
> >by
> >RW> export rc=$?
> >RW> Then you can interrogate rc to get the compiler's return code.
> >
> >RP> No, you cannot do that, it will not and does not work.
> >
> >RP> The 'system' call creates a new shell below the current one. Any
> >RP> 'export' only changes what is in that new shell and this is
> >destroyed
> >RP> before the 'system' returns to the program.
> >
> >What "will not work" was your 'export=$?' that you expected to survive
> >the exit and be put into the shell above the Cobol program.
>
> You're correct about that.

So, you agree then that your: "Richard thought it was fundamentally
impossible for a child process to pass anything back to its parent."
was wrong and was gross misrepresentation, and that your: "This
solution shows I was right." was complete nonsense.


> >> I opined the return code should be passed back,
> >
> >It would not be passed back by that mechanism.
>
> Yes, but it should be passed back by the wait() mechanism, which is used by system().

That was not even discussed.

> >> Richard thought it was fundamentally impossible for a child
> >> process to pass anything back to its parent.
> >
> >No, you are wrong, yet again. I made no comment at all whether a
> >return code could be passed back by some means to its parent, I simply
> >pointed out that the mechanism you described would not, and provably
> >did not, work.
>
> True, but not helpful. The number of things that don't work is infinity minus 1. It can be
> made to work by coding an explicit exit.

What was entirely unhelpful at the time was your proposed mechanism
which had no hope of working, and your assurance that you had done it
many times:

RW>> I could swear on a stack of manuals I've done it many times.


> >> This solution shows I was right.
> >
> >Wrong then, wrong again. Did you not read the rest of the thread where
> >several people _demonstrated_ that you were wrong.
>
> That discussion was about running the make program to do a compilation. It would have been
> helpful if someone had pointed out how to add .cbl to the suffix list, which would enable
> writing a rule to compile all Cobol programs. It is done like this:

You had ample opportunity to do that at the time, but, in fact, it was
unrequired. The requirement was to compile a single program on each
iteration and I had outlined a simple makefile which was sufficient.
The point at issue was entirely how to determine if the compile worked
or not.


> targets=prog1.so prog2.so prog3.so
> .SUFFIXES:.cbl .so
>
> .cbl.so: cob -z $< # this is a rule
>
> $(targets) # this line compiles all stale targets

More of your usual deflection.

From: Robert on
On Sat, 12 Jan 2008 13:37:20 -0800 (PST), Richard <riplin(a)azonic.co.nz> wrote:
>Robert wrote:
>> On Fri, 11 Jan 2008 22:53:22 -0800 (PST), Richard <riplin(a)azonic.co.nz> wrote:
>>
>> >On Jan 12, 2:53 pm, Robert <n...(a)e.mail> wrote:
>> >> The problem: I want to run a Unix command, program or script from Cobol and get its return
>> >> code. For example, I want to test whether /usr/tmp is a valid directory. On a shell
>> >> command line, I can say 'test -d /usr/tmp' (or ksh shortcut [ -d /usr/tmp ]) followed by
>> >> 'echo $?'. The result will be 0 if valid, 1 if invalid. When I say the same in a Cobol
>> >> program ..
>> >>
>> >> call 'system' using 'test -d /usr/tmp'
>> >> if return-code not = zero
>> >> display '/usr/tmp is not a valid directory'
>> >> set fatal-error to true
>> >> end-if
>> >>
>> >> .. the return-code is alswya zero.
>> >>
>> >> The solution:
>> >>
>> >> call 'system' using 'test -d /usr/tmp; exit $?'
>> >>
>> >> System() forks a child process, execs it to the default shell (usually sh), feeds it your
>> >> command line and waits for it to terminate. It is functionally the same as saying:
>> >> sh -c 'test -d /usr/tmp'
>> >> The sh shell is supposed to exit by default with the last return code ($?), and system()
>> >> is supposed to do the same. There is a bug in one of the two causing that to not work, but
>> >> it does work when your command does an explicit exit.
>> >>
>> >> This question came up here two years ago, without a conclusive answer. I opined the return
>> >> code should be passed back, Richard thought it was fundamentally impossible for a child
>> >> process to pass anything back to its parent. This solution shows I was right.
>> >
>> >see * below
>> >
>> >> A further complication is that the system() surrogate supplied Micro Focus Server Express
>> >> 4.1 running on HP-UX shifts the return code left 8 bits. Thus,
>> >> call 'system' using 'exit 123'
>> >> returns 31,488, which is 123*256. The 1 returned by the above directory test comes back as
>> >> 256. At least it's not zero, which is all you care about.
>> >
>> >The "system() surrogate supplied Micro Focus" is not "system" but is
>> >"SYSTEM" (upper case). CALL "system" is likely to use the C library routine.
>>
>> I used lower case.
>>
>> >The return from "system" is implementor defined. In Linux this is
>> >defined as being in the "format specified in wait(2)".
>>
>> Which is a pid_t: an integer containing the child's process id.
>
>While the format is a pid_t, as I said, the content need not be a pid.

I think there are backward compatibility issues with old (pre-POSIX) versions of system().
Returning the pid of a process that no longer exists has no utility. It appears that,
under certain conditions, you get the 'status' word, which contains the return code. Under
the covers, it is doing wait(&status), which is equivalent to waitpid(-1, &status, 0);

>> What I get back is
>> WEXITSTATUS() in the left byte and zero in the right byte.
>
>If the return is bigendian, then will a S9(4) COMP-5 give it correctly
>by reversing the bytes ?

I was using return-code, rather than a user-defined variable, to eliminate that
complication. HP-UX is a bigendian (bassackwards) operating system. The underlying PA
processor can go either way; when it's running HP-UX, it's bigendian.

I no longer use COMP-n. Instead, I use BINARY, which lets the compiler deal with
endianness. I'm not interested in that petty squabble.

>> >I cannot find anything in MF manuals that say what the return from
>> >"SYSTEM" is.
>>
>> I assume it's the same as the C function.
>
>I don't know why you would make such assumptions. "SYSTEM" does much
>more than "system" because it adjusts the ADIS settings. What it
>returns is entirely dependent on what MF want it to, and as far as I
>can tell, they haven't said.

I'll do an ldd to find out for sure whether I'm calling the C library "system" or the MF
surrogate "SYSTEM". Generally, MF likes to uppercase the names of programs it does not
recognize. All user defined programs are uppercased.

>> >* I looked "two years ago" and found this:
>> >
>> >RW> Call SYSTEM to run a script containing two entries: make followed
>> >by
>> >RW> export rc=$?
>> >RW> Then you can interrogate rc to get the compiler's return code.
>> >
>> >RP> No, you cannot do that, it will not and does not work.
>> >
>> >RP> The 'system' call creates a new shell below the current one. Any
>> >RP> 'export' only changes what is in that new shell and this is
>> >destroyed
>> >RP> before the 'system' returns to the program.
>> >
>> >What "will not work" was your 'export=$?' that you expected to survive
>> >the exit and be put into the shell above the Cobol program.
>>
>> You're correct about that.
>
>So, you agree then that your: "Richard thought it was fundamentally
>impossible for a child process to pass anything back to its parent."
>was wrong and was gross misrepresentation, and that your: "This
>solution shows I was right." was complete nonsense.

Will you agree that I try to be helpful while you're a curmudgeon?

>> >> I opined the return code should be passed back,
>> >
>> >It would not be passed back by that mechanism.
>>
>> Yes, but it should be passed back by the wait() mechanism, which is used by system().
>
>That was not even discussed.

It should have been, because that's how a return code is passed back.

>> >> Richard thought it was fundamentally impossible for a child
>> >> process to pass anything back to its parent.
>> >
>> >No, you are wrong, yet again. I made no comment at all whether a
>> >return code could be passed back by some means to its parent, I simply
>> >pointed out that the mechanism you described would not, and provably
>> >did not, work.
>>
>> True, but not helpful. The number of things that don't work is infinity minus 1. It can be
>> made to work by coding an explicit exit.
>
>What was entirely unhelpful at the time was your proposed mechanism
>which had no hope of working, and your assurance that you had done it
>many times:
>
>RW>> I could swear on a stack of manuals I've done it many times.

I HAD done it many times. Now I realize it must have been in functions within the same
script.

>> >> This solution shows I was right.
>> >
>> >Wrong then, wrong again. Did you not read the rest of the thread where
>> >several people _demonstrated_ that you were wrong.
>>
>> That discussion was about running the make program to do a compilation. It would have been
>> helpful if someone had pointed out how to add .cbl to the suffix list, which would enable
>> writing a rule to compile all Cobol programs. It is done like this:
>
>You had ample opportunity to do that at the time, but, in fact, it was
>unrequired. The requirement was to compile a single program on each
>iteration and I had outlined a simple makefile which was sufficient.
>The point at issue was entirely how to determine if the compile worked
>or not.

In that case, they didn't need make, they could have just shelled to the compiler. In
either case, the trick to getting a return code was an explicit exit statement.

call 'system' using 'cob prog.cbl' *> always returns zero
call 'system' using 'cob prog.cbl; exit $?' *> returns non-zero for failure

That's the answer they were looking for.
 |  Next  |  Last
Pages: 1 2 3 4 5 6
Prev: mainframe material
Next: Quick responses to Judson