Terrence J. Doyle
2015-02-02 23:33:47 UTC
I kicked up a couple bugs while testing the variations on the way
"read -p" is now handled. In the following example I start by testing
"read -p" for generating a prompt -- a rather poor prompt, but it's a
lead-up to what I'm showing later. There are no problems with "read -p"
in prompt mode. Next, I start a co-process and do several successful
variations on printing to the co-process. But, there are problems when I
try to read back what was printed. As the comments in the example
describe "read x <&p" and "read -px" (no space between the p and x) have
problems.
$ read -p x
x1
$ print $REPLY
1
$ read -px
x2
$ print $REPLY
2
$ while read -r line
$ print -up 'Testing'
$ print 1 >&p
$ print -p 2
$ print -p 3
$ read -up x
$ print $x
read: Testing
#
# The next read hangs. Control-C returns the shell prompt. The
# co-process pipe is not read ($x still has the value of the previous
# read). <&p works in ksh-20120612, but not in ksh-20140929.
#
$ read x <&p
^C$ print $x
read: Testing
$ read -p x
$ print $x
read: 1
$ #
$ # The next read hangs hard. The system load jumps. After a long pause
$ # (> 1 minute) the error message appears followed by the bus error.
$ # Debugging with gdb reveals that the optget() loop in b_read() is
$ # being called repeatedly to case 'p' (line 230 in
$ # src/cmd/ksh93/bltins/read.c) because of the argv-- at line 237. The
$ # behavior with ksh-20120612 was to declare x an invalid option
$ # without hanging and without dieing with a bus error.
$ #
$ read -px
^C
^\
^Z
ksh: read: -px: invalid variable name
Bus error
I also did some digging with gdb for the "read x <&p" problem. I set
a breakpoint at line 337 in src/cmd/kdh93/bltins/read.c, which looks
like this:
r=sh_readline(shp,argv,readfn,fd,flags,len,timeout);
Then, I ran the shell, created the co-process as in the example above,
did the same prints to the co-process and ran "read -up x". At the
breakpoint the variable, fd, was 5, the same as shp->cpipe[0]. Then, I
continued and ran "read x <&p". This time the variable, fd, was 0
(zero), while shp->cpipe[0] was, of course, still 5. So, the problem
here appears to be that <&p is associated with stdin instead of the
co-process pipe. After I continued the read hung as before. I typed
control-C and did a where in gdb. I attached the output of the where
command in read_hang_where.txt.
Terrence Doyle
"read -p" is now handled. In the following example I start by testing
"read -p" for generating a prompt -- a rather poor prompt, but it's a
lead-up to what I'm showing later. There are no problems with "read -p"
in prompt mode. Next, I start a co-process and do several successful
variations on printing to the co-process. But, there are problems when I
try to read back what was printed. As the comments in the example
describe "read x <&p" and "read -px" (no space between the p and x) have
problems.
$ read -p x
x1
$ print $REPLY
1
$ read -px
x2
$ print $REPLY
2
$ while read -r line
do
[[ "$line" == [Qq] ]] && break
print -r -- "$line" >> /tmp/test
print -r "read: $line"
done |&
[1] 40391[[ "$line" == [Qq] ]] && break
print -r -- "$line" >> /tmp/test
print -r "read: $line"
done |&
$ print -up 'Testing'
$ print 1 >&p
$ print -p 2
$ print -p 3
$ read -up x
$ print $x
read: Testing
#
# The next read hangs. Control-C returns the shell prompt. The
# co-process pipe is not read ($x still has the value of the previous
# read). <&p works in ksh-20120612, but not in ksh-20140929.
#
$ read x <&p
^C$ print $x
read: Testing
$ read -p x
$ print $x
read: 1
$ #
$ # The next read hangs hard. The system load jumps. After a long pause
$ # (> 1 minute) the error message appears followed by the bus error.
$ # Debugging with gdb reveals that the optget() loop in b_read() is
$ # being called repeatedly to case 'p' (line 230 in
$ # src/cmd/ksh93/bltins/read.c) because of the argv-- at line 237. The
$ # behavior with ksh-20120612 was to declare x an invalid option
$ # without hanging and without dieing with a bus error.
$ #
$ read -px
^C
^\
^Z
ksh: read: -px: invalid variable name
Bus error
I also did some digging with gdb for the "read x <&p" problem. I set
a breakpoint at line 337 in src/cmd/kdh93/bltins/read.c, which looks
like this:
r=sh_readline(shp,argv,readfn,fd,flags,len,timeout);
Then, I ran the shell, created the co-process as in the example above,
did the same prints to the co-process and ran "read -up x". At the
breakpoint the variable, fd, was 5, the same as shp->cpipe[0]. Then, I
continued and ran "read x <&p". This time the variable, fd, was 0
(zero), while shp->cpipe[0] was, of course, still 5. So, the problem
here appears to be that <&p is associated with stdin instead of the
co-process pipe. After I continued the read hung as before. I typed
control-C and did a where in gdb. I attached the output of the where
command in read_hang_where.txt.
Terrence Doyle