LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
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 11-16-2007, 07:58 AM   #1
gearoid_murphy
Member
 
Registered: Mar 2006
Location: Ireland
Distribution: Debian Etch
Posts: 72

Rep: Reputation: 18
strange blocking behavior


Hello.

I have written this program :

#include <iostream>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

using namespace std ;

#define BSIZE 4096
int main()
{
char buf [BSIZE] ;

fcntl(0, F_SETFL, O_NONBLOCK);
read(0, buf, BSIZE);
cout<<buf<<endl ;

return 0 ;
}

Its purpose is to print out the contents of std input from a unix pipe. The fcntl call is to set the read operation to non blocking. This will stop the program from freezing if there is not std input. My problem is that the program will not register input even if I pipe some into it. What really really bites is the fact that if I run an strace on the program, The program runs normally (it prints the piped input).

ls | ./a.out // no output
ls | strace -o strace.out ./a.out //output.

Can anyone explain this to me?
 
Old 11-16-2007, 06:01 PM   #2
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 78
Quote:
Originally Posted by gearoid_murphy View Post
This will stop the program from freezing if there is not std input. My problem is that the program will not register input even if I pipe some into it. What really really bites is the fact that if I run an strace on the program, The program runs normally (it prints the piped input).
First, you don’t check to see the return value of read. Most likely, it’s -1 and errno is EAGAIN.

Second, there is no guarantee that nonblocking input from a pipe will successfully read anything on the first try. Moreover, you are not guaranteed to read all the bytes at once.

Also, since you don’t check to see whether you have successfully read into the buffer, the contents of the buffer are 4096 bytes of stack space (p.s., not a good idea to use such a large buffer on the stack). Since this is uninitialized, your attempt to write it will result in the sequence of the first C-style string (e.g., all bytes from buf[0] up until the first ascii nul character).

Additionally, your nonblocking trickery messes up on the majority of the cases you want to stop (when stdin is a terminal, not a pipe). In this case, when you set stdin to be nonblocking, you might also set stdout and stderr as nonblocking as well (since it’s all the same terminal). When you try to do buffered output (using cout) to a non-blocking file, funny things can happen.

If you just want to check whether a file descriptor (in your case 0 for stdin) is connected to a terminal, use the much more elegant (and portable) POSIX function isatty().
 
Old 11-16-2007, 10:22 PM   #3
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
Quote:
Originally Posted by osor View Post
Also, since you don’t check to see whether you have successfully read into the buffer, the contents of the buffer are 4096 bytes of stack space (p.s., not a good idea to use such a large buffer on the stack).
I don't mean to hijack the thread, but I'm curious as to why using a large buffer on the stack is a bad idea? Why should having a buffer on the stack be worse than a similar-sized buffer in the data segment?
 
Old 11-17-2007, 07:44 AM   #4
gearoid_murphy
Member
 
Registered: Mar 2006
Location: Ireland
Distribution: Debian Etch
Posts: 72

Original Poster
Rep: Reputation: 18
Ok, I had code the check the status of the read but it indicated a null read even when there was std input. However, I now see, as you correctly point out, that the non-blocking behavior is the source of the problem. I have tested isatty(0) and it correctly identifies the presence of std input. w.r.t stack space, 4096 poses no threat to the stability of the system, 8192 being the default limit, either way, its a tangential point. Thanks.
 
Old 11-17-2007, 02:02 PM   #5
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 78
Quote:
Originally Posted by ntubski View Post
I'm curious as to why using a large buffer on the stack is a bad idea?
On most modern systems, stack size dynamically grows to accommodate the needs of a program. On other (still “modern”) systems, stack size is a limited commodity. So in the interest of portability, putting large buffers on the stack is discouraged. So it’s not really a “bad idea” per se, but it is not always a good idea. There is also no harm in making the buffer static. Of course the C standard says nothing about how a stack should be implemented (or even if a stack should be used at all). These are all implementation-specific issues which don’t affect the OP.
 
Old 11-17-2007, 02:05 PM   #6
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 78
Quote:
Originally Posted by gearoid_murphy View Post
I have tested isatty(0) and it correctly identifies the presence of std input.
I wanted to point out that obviously there are possibilities for stdin different from being a pipe and being a terminal. In most cases, however, the terminal is the only “interactive” such possibility.
 
  


Reply



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
Apache2 strange behavior JJX Linux - Server 0 02-10-2007 01:14 PM
Strange behavior(??) in Samba! bigoli MEPIS 1 06-06-2005 11:43 AM
Very Strange Behavior raysr Mandriva 4 08-31-2004 02:06 PM
Strange Behavior andrewb758 Linux - Hardware 5 08-31-2003 02:42 PM
strange behavior abhijit Linux - General 3 07-09-2003 11:25 PM

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

All times are GMT -5. The time now is 11:33 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