Check output device is a terminal: Difference between revisions
(→Tcl: Added demonstration) |
(→{{header|Tcl}}: Extended solution) |
||
Line 54: | Line 54: | ||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
To detect whether output is going to a terminal in Tcl, you check whether the <code>stdout</code> channel looks like a serial line (as those are indistinguishable from terminals). The simplest way of doing that is to see whether you can read the <tt>-mode</tt> channel |
To detect whether output is going to a terminal in Tcl, you check whether the <code>stdout</code> channel looks like a serial line (as those are indistinguishable from terminals). The simplest way of doing that is to see whether you can read the <tt>-mode</tt> or <code>-xchar</code> channel options, which are only present on serial channels: |
||
<lang tcl>set toTTY [dict exists [fconfigure stdout] -mode] |
<lang tcl>set toTTY [dict exists [fconfigure stdout] -mode] |
||
puts [expr {$toTTY ? "Output goes to tty" : "Output doesn't go to tty"}]</lang> |
puts [expr {$toTTY ? "Output goes to tty" : "Output doesn't go to tty"}]</lang> |
||
At the system call level, when Tcl is setting up the channels that correspond to the underlying <tt>stdout</tt> (and <tt>stdin</tt> and <tt>stderr</tt>) file descriptors, it checks whether the channels are network sockets (with <code>getsockname()</code>) or serial lines (with <code>isatty()</code>). This allows Tcl scripts to find out information about their calling environment (e.g., when they are run from <tt>inetd</tt>) with minimal code. |
|||
{{out|Demonstrating}} |
{{out|Demonstrating}} |
||
Assuming that the above script is stored in the file <tt>istty.tcl</tt>: |
Assuming that the above script is stored in the file <tt>istty.tcl</tt>: |
||
Line 63: | Line 64: | ||
$ tclsh8.5 istty.tcl | cat |
$ tclsh8.5 istty.tcl | cat |
||
Output doesn't go to tty</pre> |
Output doesn't go to tty</pre> |
||
===Channel type discovery with older Tcl versions=== |
|||
Before Tcl 8.4, this discovery process is impossible; <code>stdout</code> always looks like it is going to a file. With 8.4, you can discover the channel type but you need slightly different (and less efficient, due to the thrown error in the non-tty case) code to do it. |
|||
<lang tcl>set toTTY [expr {![catch {fconfigure stdout -mode}]}]</lang> |
Revision as of 09:23, 28 March 2013
In this task, the job is to check whatever output filehandle exits to the terminal and mention whatever output goes to it or not.
C
Use isatty()
on file descriptor to determine if it's a TTY. To get the file descriptor from a FILE*
pointer, use fileno
:
<lang c>#include <unistd.h> // for isatty()
- include <stdio.h> // for fileno()
int main() {
puts(isatty(fileno(stdout)) ? "stdout is tty" : "stdout is not tty"); return 0;
}</lang>
- Output:
$ ./a.out stdout is tty $ ./a.out > tmp $ cat tmp stdout is not tty $ ./a.out | cat stdout is not tty
OCaml
<lang ocaml>let () =
print_endline ( if Unix.isatty Unix.stdout then "Output goes to tty." else "Output doesn't go to tty." )</lang>
Testing in interpreted mode:
$ ocaml unix.cma istty.ml Output goes to tty. $ ocaml unix.cma istty.ml > tmp $ cat tmp Output doesn't go to tty. $ ocaml unix.cma istty.ml | cat Output doesn't go to tty.
Tcl
To detect whether output is going to a terminal in Tcl, you check whether the stdout
channel looks like a serial line (as those are indistinguishable from terminals). The simplest way of doing that is to see whether you can read the -mode or -xchar
channel options, which are only present on serial channels:
<lang tcl>set toTTY [dict exists [fconfigure stdout] -mode]
puts [expr {$toTTY ? "Output goes to tty" : "Output doesn't go to tty"}]</lang>
At the system call level, when Tcl is setting up the channels that correspond to the underlying stdout (and stdin and stderr) file descriptors, it checks whether the channels are network sockets (with getsockname()
) or serial lines (with isatty()
). This allows Tcl scripts to find out information about their calling environment (e.g., when they are run from inetd) with minimal code.
- Demonstrating:
Assuming that the above script is stored in the file istty.tcl:
$ tclsh8.5 istty.tcl Output goes to tty $ tclsh8.5 istty.tcl | cat Output doesn't go to tty
Channel type discovery with older Tcl versions
Before Tcl 8.4, this discovery process is impossible; stdout
always looks like it is going to a file. With 8.4, you can discover the channel type but you need slightly different (and less efficient, due to the thrown error in the non-tty case) code to do it.
<lang tcl>set toTTY [expr {![catch {fconfigure stdout -mode}]}]</lang>