Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Sometimes I pipe articles in tin(1) through a perl script that parses the output, does something and pipes it into less; when I quit less I'm back in tin and everything is fine. However, when I press ctrl-z (happens more often than I'd think) the terminal ends up in a strange state. The output is

Stopped. Type 'fg' to restart tin

but I have no shell:

ls (nothing)

entering "fg" doesn't take me back to tin. Killing the perl and/or less processes doesn't help either, nor does pressing 'q' (as command for less or tin).

A tin developer analysed the behaviour of tin for me: before popen(), tin does (feed.c:feed_articles() ~ line 616)

reset_shell_mode(3ncurses); endwin(3ncurses);

and after pclose() (feed.c:feed_articles() ~ line 855)

reset_prog_mode(3ncurses); set_keypad_on(3ncurses);

SIGTSTP causes (signal.c:handle_suspend())

set_keypad_off(3ncurses); set_xclick_off(3ncurses); reset_shell_mode(3ncurses); kill(0, SIGSTOP); reset_prog_mode(3ncurses); set_keypad_on(3ncurses); set_xclick_on(3ncurses);

The developer claims that the double reset_shell_mode shouldn't hurt and that this looks ok (I think so as well).

He reduced my test case to

cat|less

and pressing ^Z, which works nicely, however piping through

perl -ne 'print $_;'|less

and pressing ^Z confuses perl. This looks like a perl-specific problem.

Can someone shed more light on this?

Replies are listed 'Best First'.
Re: weird ctrl-z behaviour when piping from tin through perl
by ikegami (Patriarch) on Sep 11, 2009 at 20:03 UTC
Re: weird ctrl-z behaviour when piping from tin through perl
by Illuminatus (Curate) on Sep 11, 2009 at 20:46 UTC
    Also, what about just trying to stop a perl program by itself. Can you ^Z
    perl -pel
    (thx to ikegami for the brevity advice). If this also fails, then the problem may be your build of perl. I noticed a gcc-related problem reported against netbsd and perl signal handling that could possibly be relevant...

      If I pipe through perl -pel directly, then I can suspend and get a shell prompt. That's slightly different though, because the perl process has already finished by then and it's just the tin prompt Press <RETURN> to continue... that I'm suspending from (sorry, I'm not fast enough to interrupt perl justing printing its input).

      Thanks for the link; however, the NetBSD version comes with gcc (GCC) 4.1.3 20080202 prerelease (NetBSD nb1 20080202).

        Sorry, but that is not what I asked. Just type
        perl -pel
        from the shell prompt. This should simply allow you to type a line (with no echo), and see what you typed every time you hit enter. It should not end until you hit ctrl-C. At this point, what happens when you type ctrl-Z? If it suspends properly, then I would have to assume that it is some problem dealing with process-group signaling in NetBSD. If it does not suspend properly, then your build of perl is the problem.
Re: weird ctrl-z behaviour when piping from tin through perl
by ig (Vicar) on Sep 11, 2009 at 20:25 UTC

    When you say ^Z works nicely for cat|less, what do you mean? What happens?

    When you say ^Z confuses perl for perl -ne 'print $_;'|less, what do you mean? What happens?

    I tested on CentOS 5 and both of the above commands behave the same. ^Z suspends them and fg brings them back to the foreground.

      Gets a shell prompt vs gets a blank prompt that doesn't do anything apparent in response to Enter. (He's possibly feeding perl's <>.)
        That's correct in all counts (including the <>, I'm doing while (<>) in the script).
Re: weird ctrl-z behaviour when piping from tin through perl
by Illuminatus (Curate) on Sep 11, 2009 at 20:12 UTC
    Sorry, but I'm not seeing a problem on Linux. The whole
    perl -ne 'print $_;' | less
    may not work as expected, as this uses stdout, which is buffered. You could use
    perl -ne 'print STDERR $_;' | less
    to get the same behavior, however. When I ^Z either of these from the shell on linux, it gives me the shell prompt, and 'fg' returns me to the process, as expected.

    Do you see the same 'stopped' message for the simple case at the end as you do for the 'tin' command?

      I get Stopped. Type 'fg' to restart tin but no shell prompt.

      Btw, shell in this case is GNU bash, version 4.0.28(1)-release (x86_64--netbsd).

Re: weird ctrl-z behaviour when piping from tin through perl
by Anonymous Monk on Sep 11, 2009 at 19:38 UTC

    This is on NetBSD-5.99.16/amd64 with perl-5.10.0 from pkgsrc.

      Cannot reproduce on Linux 2.6.30-1-686 #1 SMP i686 GNU/Linux, perl v5.10.0 i486-linux-gnu-thread-multi

      perl -ne '$|=1;print $_;' | less

      Ctrl-Z gives prompt. GNU bash, version 4.0.28(1)-release (i486-pc-linux-gnu)

      $ jobs [1]+ Stopped perl -ne '$|=1;print $_;' | less
      print pack("A25",pack("V*",map{1919242272+$_}(34481450,-49737472,6228,0,-285028276,6979,-1380265972)))