Skip to content

OMake redirects stdout' and stderr' even for simple commands. #112

Description

@cspiel

For example if you use less(1) to page a file from OMake as in

.PHONY: mirar
mirar:
        less /etc/motd

you loose all of the controlling terminal's capabilities. Also try:

        diff --color=auto old-file new-file

or my favorite, w3m(1), which degenerates to a fancy cat(1)

        w3m index.html

in the rule body instead of less(1).

No shell redirects stdout or stderr for simple commands, not even
osh(1)! Try

osh -c 'less /etc/motd'

to verify that it really works.

I wrote the tiny tool is-a-tty to investigate the situation. The program
inquires the TTY's name (ttyname(3)) and whether the standard file
descriptors are connected to a TTY (isatty(3)). Here are the results:

bash(1):

$ ./is-a-tty
isatty("stdin", 0 => /dev/pts/1)?  true
isatty("stdout", 1 => /dev/pts/1)?  true
isatty("stderr", 2 => /dev/pts/1)?  true

OK - all three descriptors are conneted to a TTY.

$ ./is-a-tty 2> err.out
isatty("stdin", 0 => /dev/pts/1)?  true
isatty("stdout", 1 => /dev/pts/1)?  true
is-a-tty: isatty("stderr"): Inappropriate ioctl for device
is-a-tty: ttyname("stderr"): Inappropriate ioctl for device
isatty("stderr", 2 => <no tty name>)?  false

OK - we redirected stderr to err.out.

osh(1):

% ./is-a-tty
isatty("stdin", 0 => /dev/pts/1)?  true
isatty("stdout", 1 => /dev/pts/1)?  true
isatty("stderr", 2 => /dev/pts/1)?  true

OK - all three descriptors are connected to a TTY.

% ./is-a-tty >& err.out
% cat err.out
isatty("stdin", 0 => /dev/pts/1)?  true
is-a-tty: isatty("stdout"): Inappropriate ioctl for device
is-a-tty: ttyname("stdout"): Inappropriate ioctl for device
isatty("stdout", 1 => <no tty name>)?  false
is-a-tty: isatty("stderr"): Inappropriate ioctl for device
is-a-tty: ttyname("stderr"): Inappropriate ioctl for device
isatty("stderr", 2 => <no tty name>)?  false

OK - >& redirects both stdout and stderr to err.out.

omake(1) with an OMakefile containing

.PHONY: is-a-tty
is-a-tty:
        $(HOME)/src/c/is-a-tty

yields:

$ omake is-a-tty
- build bug-always-redirect-stdout-stderr <is-a-tty>
+ /home/cspiel/src/c/is-a-tty
isatty("stdin", 0 => /dev/pts/0)?  true
is-a-tty: isatty("stdout"): Inappropriate ioctl for device
is-a-tty: ttyname("stdout"): Inappropriate ioctl for device
isatty("stdout", 1 => <no tty name>)?  false
is-a-tty: isatty("stderr"): Inappropriate ioctl for device
is-a-tty: ttyname("stderr"): Inappropriate ioctl for device
isatty("stderr", 2 => <no tty name>)?  false

Not OK - both stdout and stderr are implicitly redirected.

Obviously the redirection only kicks in inside of OMake,
not plain osh(1).

This quirk is most annoying when using any kind of pager in a rule
body, but also disables automatic technicolor error messages from
modern compilers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions