[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#761300: libc6: Printf("%c",'x') does not follow stdio



Control: retitle -1 libc6: putchar does not follow stdio

On 2014-09-12 09:10 -0700, Thomas D. Dean wrote:

> Package: libc6
> Version: 2.13-38+rpi2+deb7u3
> Severity: normal
>
> Dear Maintainer,
>
>    * What led up to the situation?
>
> Redirecting stdout in C code does not work for printf("%c",'x')
> I ssh into the system.  I want to redirect all output to stdout to
> the local terminal.  This works as expected for everything except
> when printing a single character.
>
>    * What exactly did you do (or not do) that was effective (or
>      ineffective)?
>
>   FILE *display_fp;
>   if ((display_fp = fopen("/dev/tty1","r+")) == NULL) {
>  perror("Open /dev/tty1");
>  return -1;
>   }
>   stdout = display_fp;
>
> Then,
>
> printf("%s","asdfasdf"); /* output to /dev/tty1 */
> printf("%c",'x'); /* output to original terminal */
>
>    * What was the outcome of this action?
>
> All the output except for the "%c" case went to /dev/tty1.  The
> output in the "%c" case went to the ssh terminal

It is actually a bit more subtle than that, as gcc has its own printf
builtin function which comes into play.  Compiling the program with
-fno-builtin in fact makes it work as intended (at least with glibc
2.27-6).

Looking closer, I found that with -fno-builtin

printf("%c",'x');   works
putc('x', stdout);  works
putchar('x');       exhibits the bug

This result is rather surprising.  After all, "putchar('x')" is supposed
to do the same as "putc('x', stdout)", but here it does not.

I'm attaching the whole program, so that future researchers have less to
copy and paste.

Cheers,
       Sven

#include <stdio.h>
#include <stdlib.h>

int main (int argc, char** argv)
{
  FILE *display_fp;
  if ((display_fp = fopen("/dev/tty1","r+")) == NULL) {
    perror("Open /dev/tty1");
    return -1;
  }
  stdout = display_fp;
  printf("%s","asdfasdf"); /* output to /dev/tty1 */
  putchar('x'); /* output to original terminal */
}

Reply to: