Discussion:
[ast-developers] Ksh stops reading stdin and hangs
Vladimir Marek
2013-12-04 21:39:27 UTC
Permalink
Hi,

What a coincidence, I just stumbled upon another issue. I don't have fix
for this though ...

The test script:

$ cat c
#!/bin/ksh

trap 'exit' EXIT

(
yes | while read A; do
echo "$A"
STDERR=$(</dev/null)
done
)

It should write infinite number of characters 'y'. But in reality it only
writes one 'y' and ten empty lines only.

Also if you run the script as

$ ./c | head

It hangs. I don't know whether the two things (not reading and hanging) are
just a single issue or two different ones.

I can reproduce this on both linux and solaris. On linux the ksh says

$ echo $KSH_VERSION
Version AJM 93u+ 2012-08-01

On Solaris
Version JM 93u 2011-02-08

I'm just having a bad luck lately I guess ...

Cheers
--
Vlad
Roland Mainz
2013-12-04 21:51:01 UTC
Permalink
On Wed, Dec 4, 2013 at 10:39 PM, Vladimir Marek
Post by Vladimir Marek
Hi,
What a coincidence, I just stumbled upon another issue. I don't have fix
for this though ...
$ cat c
#!/bin/ksh
trap 'exit' EXIT
(
yes | while read A; do
echo "$A"
STDERR=$(</dev/null)
done
)
It should write infinite number of characters 'y'. But in reality it only
writes one 'y' and ten empty lines only.
Also if you run the script as
$ ./c | head
It hangs. I don't know whether the two things (not reading and hanging) are
just a single issue or two different ones.
I can reproduce this on both linux and solaris. On linux the ksh says
$ echo $KSH_VERSION
Version AJM 93u+ 2012-08-01
On Solaris
Version JM 93u 2011-02-08
I'm just having a bad luck lately I guess ...
I can reproduce the same issue with the following reduced testcase on
Illumos B151a7/AMD64 with ast-ksh.2013-10-10/AMD64/64bit:
-- snip --
(
for ((;;)) ; do print y ; done | while read A; do
printf "%s\n" "$A"
STDERR=$(</dev/null)
done
)
-- snip --

It seems to be an issue with the non-|fork()|'ing subshell code... if
I force the code to use |fork()| for a subshell using the ulimit(1)
builtin I get the correct output:
-- snip --
$ cat c.sh
(
ulimit -c 0

for ((;;)) ; do print y ; done | while read A; do
printf "%s\n" "$A"
STDERR=$(</dev/null)
done
)
$ ~/bin/ksh c.sh | head
y
y
y
y
y
y
y
y
y
y
-- snip --

I can't reproduce the issue with piping the output to head(1) with
ast-ksh.2013-10-10 ...

----

Bye,
Roland
--
__ . . __
(o.\ \/ /.o) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)
Roland Mainz
2013-12-04 22:02:11 UTC
Permalink
Post by Roland Mainz
On Wed, Dec 4, 2013 at 10:39 PM, Vladimir Marek
Post by Vladimir Marek
What a coincidence, I just stumbled upon another issue. I don't have fix
for this though ...
$ cat c
#!/bin/ksh
trap 'exit' EXIT
(
yes | while read A; do
echo "$A"
STDERR=$(</dev/null)
done
)
It should write infinite number of characters 'y'. But in reality it only
writes one 'y' and ten empty lines only.
Also if you run the script as
$ ./c | head
It hangs. I don't know whether the two things (not reading and hanging) are
just a single issue or two different ones.
I can reproduce this on both linux and solaris. On linux the ksh says
$ echo $KSH_VERSION
Version AJM 93u+ 2012-08-01
On Solaris
Version JM 93u 2011-02-08
I'm just having a bad luck lately I guess ...
I can reproduce the same issue with the following reduced testcase on
-- snip --
(
for ((;;)) ; do print y ; done | while read A; do
printf "%s\n" "$A"
STDERR=$(</dev/null)
done
)
-- snip --
It seems to be an issue with the non-|fork()|'ing subshell code... if
I force the code to use |fork()| for a subshell using the ulimit(1)
-- snip --
$ cat c.sh
(
ulimit -c 0
for ((;;)) ; do print y ; done | while read A; do
printf "%s\n" "$A"
STDERR=$(</dev/null)
done
)
$ ~/bin/ksh c.sh | head
y
y
y
y
y
y
y
y
y
y
-- snip --
[snip]

Another workaround is to replace the $( < file ) construct with $( cat
< file ) ... note that ${ < file } has the same issues as $( < file )
in a subshell...

----

Bye,
Roland
--
__ . . __
(o.\ \/ /.o) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)
Vladimir Marek
2013-12-04 22:04:41 UTC
Permalink
Post by Roland Mainz
Another workaround is to replace the $( < file ) construct with $( cat
< file ) ... note that ${ < file } has the same issues as $( < file )
in a subshell...
Yes, there are many workarounds, sorry I should have written that
earlier.

- remove the trap
- make the trap empty or just ':'
- don't use subshell ( ... ) for the while loop
- read the /dev/null via STDERR=$(cat /dev/null)

Thank you
--
Vlad
Loading...