in ,

The Universe of Discourse: Another use for strace (isatty), Hacker News

The Universe of Discourse: Another use for strace (isatty), Hacker News



Another use for strace (isatty)

(This is a followup toan earlier article describing an interesting use ofstrace.)

A while back I was writing a talk about Unix internals and I wanted to discuss how thelscommand does a different display when talking to a terminal than otherwise:

lsto a terminal

lsnot to a terminal

How doeslsknow when it is talking to a terminal? I expect that is uses the standard POSIX functionisatty. But how doesisattyfind out?

I had written down my guess. Had I been programming in C, withoutisatty, I would have written something like this:

@statinfo=stat STDOUT;     if ($ statinfo [2] & 0060000==0020000         && ($ statinfo [6] & 0xff)==5) {say "Terminal"}     else {say "Not a terminal"}

(This is Perl, written as if it were C.) It usesfstat(exposed in Perl asstat) to get the mode bits ($ statinfo [2]) of the inode attached toSTDOUT, and then it masks out the bits the determine if the inode is a character device file. If so,$ statinfo [6]is the major and minor device numbers; if the major number (low byte) is equal to the magic number 5, the device is a terminal device. On mycurrentcomputers the magic number is actually 136. Obviously this magic number is nonportable. You may hear people claim that those bit operations are also nonportable. I believe that claim is mistaken.

The analogous code usingisattyis:

use POSIX 'isatty';     if (isatty (STDOUT)) {say "Terminal"}     else {say "Not a terminal"}

Isisattydoing what I wrote above? Or something else?

Let’s usestraceto find out. Here’s our test script:

% perl -MPOSIX=isatty -le ' print STDERR isatty (STDOUT)? "terminal": "nonterminal" '     terminal     % perl -MPOSIX=isatty -le 'print STDERR isatty (STDOUT)? "terminal": "nonterminal" '>/ dev / null     nonterminal

Now we usestrace:

% strace -o / tmp / isatty perl -MPOSIX=isatty -le 'print STDERR isatty (STDOUT)? "terminal": "nonterminal" '>/ dev / null     nonterminal     % less / tmp / isatty

We expect to see a long startup as Perl gets loaded and initialized, then whateverisattyis doing, the write ofnonterminal, and then a short teardown, so we start searching at the end and quickly discover, a couple of screens up:

ioctl (1, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7ffea 6840 a 58)=-1 ENOTTY (Inappropriate ioctl for device)     write (2, "nonterminal", 11)=11     write (2, " n", 1)=1

My guess aboutfstatwas totally wrong! Theactualmethod is thatisattymakes anioctlcall; this is a device-driver-specific command. TheTCGETSparameter says what command is, in this case “Get the terminal configuration”. If you do this on a non-device, or a non-terminal device, the call fails with the errorENOTTY. When theioctlcall fails, you know you don’t have a terminal. If you do have a terminal, theTCGETScommand has no effects, because it is a passive read of the terminal state. Here’s the successful call:

ioctl (1, SNDCTL_TMR_TIMEBASE or TCGETS, { B 38400 opost isig icanon echo ...})=0     write (2, "terminal", 8)=8     write (2, " n", 1)=1

TheB 38400 opost…stuff is the terminal configuration; 38400 is the baud rate.

(In the past the explanatory text forENOTTYwas the mystifying “Not a typewriter ”, even more mystifying because it tended to pop up when you didn’t expect it. Apparently Linux has revised the message to the possibly less mystifying “Inappropriate ioctl for device”.

(SNDCTL_TMR_TIMEBASEis mentioned because apparently someone decided to give theirSNDCTL_TMR_TIMEBASEoperation, whatever that is, the same numeric code asTCGETS, andstraceisn’t sure which one is being requested. It’s possible that if we figured out which device was expectingSNDCTL_TMR_TIMEBASE, and redirected standard output to that device, thatisattywould erroneously claim that it was a terminal.)

[ Addendum 20150415: Paul Bolle has found that theSNDCTL_TMR_TIMEBASEpertains to the old and possibly deprecated OSS(Open Sound System)It is conceivable thatisattywould yield the wrong answer whenpointed at the OSS/dev/dspor/dev/audiodevice or similar. Ifanyone is running OSS and willing to give it a try, please contact me at[email protected]. ]

[Other articles in category /Unix]permanent link


Brave Browser
Read More

What do you think?

Leave a Reply

Your email address will not be published.

GIPHY App Key not set. Please check settings

Shopify’s BFCM Live Map, Hacker News

Shopify’s BFCM Live Map, Hacker News

GDP growth falls below 5%, to 4.5%, lowest since March 2013 – Times of India, The Times of India

GDP growth falls below 5%, to 4.5%, lowest since March 2013 – Times of India, The Times of India