2

Consider the following very basic program, which has appeared in many forms on other questions here.

#include <string.h>

int main() {
    char message[8];
    strcpy(message, "Hello, world!");
}

On my system, if I put this in a file called Classic.c, compile it with no special flags and run it, I get the following output.

$ gcc -o Classic Class.c 
$ ./Classic
*** stack smashing detected ***: ./Classic terminated
Aborted (core dumped)

Normally, program output goes to stderr or stdout, so I expected that the following would produce no output.

./Classic  2> /dev/null > /dev/null

However, the output is exactly the same, so I have three questions to this scenario.

  1. What stream is being printed to here?
  2. How could I write code that prints to this special stream (without smashing my stack deliberately).
  3. How can I redirect the output of this stream?

Note I am running on a Linux system. Specifically, Ubuntu 14.04.

merlin2011
  • 71,677
  • 44
  • 195
  • 329

1 Answers1

2

Since it's not stderr or stdout, there's only one remaining option: The controlling tty.

You can write to this with your code by opening /dev/tty.

Redirecting its output is intentionally very difficult (this is why /dev/tty is also used for password prompts). That said, if you really want to do it, expect can be used for this purpose, as can emPTY.


The easiest approach with expect is to use the included helper unbuffer, which will effectively redirect this content to stdout:

$ sh -c 'echo hello >/dev/tty' >/dev/null 2>&1
hello
$ unbuffer sh -c 'echo hello >/dev/tty' >/dev/null 2>&1
$
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • Can you elaborate on using `expect` for this purpose? – merlin2011 May 01 '15 at 00:40
  • I wonder why segmentation faults and float point exceptions could be redirected, but this one cannot? – Flying onion Jul 08 '19 at 08:42
  • @Flyingonion Redirecting a SIGSEGV notice isn't all that easy -- generally, `foo >out 2>err` doesn't work, and you have to use `{ foo; } >out 2>err` so that *the shell that's running it* (and thus printing logs from its signal handler) has its own stderr redirected. Whereas here the message is printed by the libc of the program being run (`foo` in my example), but it's that libc that's trying to grab a TTY handle when it can. – Charles Duffy Jul 08 '19 at 11:13
  • Well finally I found the solution [here](https://stackoverflow.com/questions/31301711/how-can-a-unix-program-display-output-on-screen-even-when-stdout-and-stderr-are) – Flying onion Jul 17 '19 at 07:16