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

I would like to intercept Ctrl-S/Ctrl-Q from STDIN, so I can pass them on to child processes.

I wrote a simple test program to attached routines to all the signals available so as to explore if a signal was available. But it seems Ctrl-S/Ctrl-Q is trapped before it gets to STDIN.

For the parent process, the normal flow control works just fine with output, Ctrl-S stops the output flow and the program, and Ctrl-Q resumes the output.

My main requirement is having the ability for a parent process to temporary halt a child process. The old fashion XOFF/XON or Ctrl-S/Ctrl-Q seems the natural choice, plus its built-in, if I can detect the chars to send to the child process.

Thanks for any help.

PS. This is on Windows

  • Comment on How to intercept ctrl-S/ctrl-Q characters from STDIN

Replies are listed 'Best First'.
Re: How to intercept ctrl-S/ctrl-Q characters from STDIN
by BrowserUk (Patriarch) on Aug 20, 2008 at 21:55 UTC

    What are you trying to achieve?

    If the user is controlling this via the keyboard, then they must be able to see the output on the screen. And if the output from the child process is going to the screen, Ctrl-S will pause and resume it without the parent process needing to do anything. If you are capturing the output from the child in the parent and then printing it to the screen, then Ctrl-S will work just as it always does.

    If the output isn't going to the screen, then how would then user decide when to pause or resume?

    The point is that Ctrl-S doesn't "signal" the program in anyway at all. It simply causes the console device to stop accepting output. The program continues running until the output buffer is full, and then the print blocks until the buffer gets emptied.

    BTW. Ctrl-Q is a misnomer here. After a Ctrl-S pause, any key* will resume output.

    *Except Ctrl-C or ctrl-Break which would interupt the program.

    However, if no console output is involved and your purpose is simply to have the parent process pause and resume the child process (ie. without user interaction), then use Win32::Process to start the child and use its Suspend() & Resume() methods.

    I guess the third possibility is that your parent process is capturing the output from the child process via a pipe and you want to be able to tell the child to stop producing output temporarially. And then the answer is to just stop reading. The pipe buffer will fill and the child will effectively be suspended until you start reading again.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      BrowserUk,

      Thanks for your response (plus the others). Your feedback got me thinking and I switched my output monitoring from the Parent to the Child window and got Ctrl-S/Q to work fine.

      I am using a socket connection between the Child/Parent to passing info back to parent. I launched the child with a 'system 1, ...' to get an async relationship between the two processes. I would like to eventually still trap the Ctrl-S/Q (from the parent) and halt all child processes, so your comments on Win32:Process were helpful and later I plan on experimenting there.

      Thanks very much,

      John B

      BTW. Ctrl-Q is a misnomer here. After a Ctrl-S pause, any key* will resume output.

      Pressing Ctrl-Q ("resume" or "xon") is how it works in Linux (and presumably any *nix system). Pressing any key instead seems to be shell specific as it doesn't work in Bash.
Re: How to intercept ctrl-S/ctrl-Q characters from STDIN
by FunkyMonk (Bishop) on Aug 20, 2008 at 21:31 UTC
    Is this the sort of thing you're after?
    use Term::ReadKey; print "Press SPACE to exit\n"; ReadMode 4; while ( 1 ) { my $c = ReadKey(-1); next unless $c; last if $c eq ' '; printf "%02x ", ord $c; } END { ReadMode 1; }

    I think Term::ReadKey works on windows.


    Unless I state otherwise, all my code runs with strict and warnings