LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-21-2012, 10:39 AM   #1
romagnolo
Member
 
Registered: Jul 2009
Location: Montaletto
Distribution: Debian GNU/Linux
Posts: 107

Rep: Reputation: 5
C: printf() hangs linux pipes


I've written a simple I/O echoing program in C to test a problem with a bigger real program. Here, linux FD redirection doesn't work.
The echoing program (aka a.out) is:
Code:
#include <stdio.h>

int main(int argc, char **argv) {
  char buff[10];
  while (1) {
    if (fgets(buff, 10, stdin) == NULL) break;
    printf("PRINT: %s \n", buff);
  }
}

From Bash, I run it as:
Code:
$ mkfifo IN OUT
$ # this is a method to keep the pipes IN and OUT opened over time
$ while :; do read; echo Read: $REPLY >&2; sleep 1; done <OUT >IN &
$ a.out >OUT <IN &

$ echo xyz >IN
and there is no output produced: the Bash while loop isn't able to read from OUT.
Let's compare this a.out with cat, which instead works as expected:

Code:
$ mkfifo IN OUT
$ while :; do read; echo Read: $REPLY >&2; sleep 1; done <OUT >IN &
$ cat >OUT <IN &

$ echo xyz >IN
Read: xyz
This last line is printed on console to stderr. cat's output, differently from a.out's, is able to travel across OUT and reach the Bash while loop, which then prints it on console.
What's wrong with a.out?

Last edited by romagnolo; 09-21-2012 at 10:47 AM. Reason: Clarified syntax
 
Old 09-21-2012, 11:09 AM   #2
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by romagnolo View Post
What's wrong with a.out?
It is your source code that has an issue.

Change your source code to the following (note the text in bold font), and it should function as expected:
Code:
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
  char buff[10];
  while (1) {
    if (fgets(buff, sizeof(buff), stdin) == NULL) break;
    char* nl = strchr(buff, '\n');
    if (nl)
      *nl = '\0';
    printf("PRINT: %s \n", buff);
    fflush(stdout);
  }
  return 0;
}
To summarize: flush standard out, and to mimic 'cat', remove the newline that echo inserts into stream (or conversely, remove newline from printf).
 
1 members found this post helpful.
Old 09-21-2012, 11:09 AM   #3
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 709

Rep: Reputation: 428Reputation: 428Reputation: 428Reputation: 428Reputation: 428
Hi.

Add
Code:
fflush(stdout);
after printf(). Look at `man fflush' or here for details.

Last edited by firstfire; 09-21-2012 at 11:10 AM.
 
1 members found this post helpful.
Old 09-21-2012, 11:37 AM   #4
romagnolo
Member
 
Registered: Jul 2009
Location: Montaletto
Distribution: Debian GNU/Linux
Posts: 107

Original Poster
Rep: Reputation: 5
Yes, fflush() solves the problem. So it seems stdin/out work differently if they run across an interactive console or a pipe. In fact, executing a.out directly with no redirections thru pipes produces immediate outputs to console and doesn't require fflush().
 
Old 09-21-2012, 01:00 PM   #5
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: Rocky Linux
Posts: 4,780

Rep: Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213
Quote:
Originally Posted by romagnolo View Post
Yes, fflush() solves the problem. So it seems stdin/out work differently if they run across an interactive console or a pipe.
It's nothing peculiar to stdout. Any stdio output stream is by default line buffered if output is going to a terminal and block buffered (typically 4KB blocks) otherwise. See the manpages for stdio(3) and setbuf(3).
 
  


Reply

Tags
bash, c-language, pipe



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Bash: < & > order is relevant; but why unrelated i/o misordering hangs my pipes? romagnolo Linux - General 3 02-14-2012 09:29 AM
LXer: Linux Pipes – what are they and example of use LXer Syndicated Linux News 0 09-25-2011 07:30 PM
How to use named pipes on linux network...? mgnidhi_3july Linux - Newbie 6 06-24-2010 02:56 PM
Linux pipes question venkat_k Programming 4 10-09-2009 03:01 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:03 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration