jonathanstowe / TermReadKey

Character mode terminal access for Perl
12 stars 27 forks source link

"make test" stops and fails if it runs as a background process #34

Closed skaji closed 3 years ago

skaji commented 4 years ago

SetControlChars() may internally call tcsetattr(3). If a background process calls tcsetattr(3) to the control terminal, it gets stopped by the SIGTTOU signal.

This can be easily seen by running perl -MTerm::ReadKey -e SetControlChars in background:

❯ perl -MTerm::ReadKey -e SetControlChars &
[1] 35956
[1]  + suspended (tty output)  perl -MTerm::ReadKey -e SetControlChars

❯ fg
[1]  + continued  perl -MTerm::ReadKey -e SetControlChars
Unable to write terminal settings in SetControlChars at -e line 1.

As a result, "make test" stops and fails if it runs as a background process:

❯ make test &
[1] 36818
"/Users/skaji/env/plenv/versions/5.30.3/bin/perl" -MExtUtils::Command::MM -e 'cp_nonempty' -- ReadKey.bs blib/arch/auto/Term/ReadKey/ReadKey.bs 644
"/Users/skaji/env/plenv/versions/5.30.3/bin/perl" "-Iblib/arch" "-Iblib/lib" ReadKey.pm.PL ReadKey.pm
Creating ReadKey.pm
Bootstrapping the XS for blockoptions: 5
Done
Skip blib/arch/Term/ReadKey.pm (unchanged)
PERL_DL_NONLAZY=1 "/Users/skaji/env/plenv/versions/5.30.3/bin/perl" "-MExtUtils::Command::MM" "-MTest::Harness" "-e" "undef *Test::Harness::Switches; test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/01_basic.t ............... ok
t/02_terminal_functions.t .. 1/7
[1]  + suspended (tty output)  make test

❯ fg
[1]  + continued  make test
t/02_terminal_functions.t .. 6/7
#   Failed test 'Validate SetControlChars function'
#   at t/02_terminal_functions.t line 93.
#          got: 'Unable to write terminal settings in SetControlChars at t/02_terminal_functions.t line 91.
# '
#     expected: ''
# Looks like you failed 1 test of 7.
t/02_terminal_functions.t .. Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/7 subtests

Test Summary Report
-------------------
t/02_terminal_functions.t (Wstat: 256 Tests: 7 Failed: 1)
  Failed test:  7
  Non-zero exit status: 1
Files=2, Tests=8,  2 wallclock secs ( 0.02 usr  0.01 sys +  0.07 cusr  0.01 csys =  0.11 CPU)
Result: FAIL
Failed 1/2 test programs. 1/8 subtests failed.
make: *** [test_dynamic] Error 1

I think it is nice to skip SetControlChars() test if the test runs as a background process. And I think we can check whether the process is in foreground or in background:

my $foreground = eval {
    my $foreground_pgid = POSIX::tcgetpgrp(fileno IN);
    my $current_pgid = getpgrp;
    return $foreground_pgid == $current_pgid;
};