LinuxQuestions.org
Visit Jeremy's Blog.
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-12-2014, 06:19 PM   #1
NeoLux
LQ Newbie
 
Registered: Dec 2012
Posts: 15

Rep: Reputation: Disabled
Question printf() hinders getchar() ? (non-blocking)


so here is a terminal program in C

Code:
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>

void TTYCook(int) ;
int main() {
	int c ;
	TTYCook( 0 )  ;
	while (1) {
		c = getchar() ;
		if (c != -1) break ;
		printf( "X\n" ) ;
	}
	printf( "done\n" ) ;
	TTYCook( 1 )  ;
	return 0 ;
}
void TTYCook(int yes) {
	struct termios ttystate  ;
	int f				;
	tcgetattr( STDIN_FILENO,&ttystate ) ;
	f = fcntl( STDIN_FILENO,F_GETFL,0 ) ;
	if (yes) {
		ttystate.c_lflag |=  ICANON ;
		ttystate.c_lflag |=  ECHO   ;
		f &= ~O_NONBLOCK ;
	} else {
		ttystate.c_lflag &= ~ICANON ;
		ttystate.c_lflag &= ~ECHO   ;
		f |=  O_NONBLOCK ;
	}
        fcntl( STDIN_FILENO,F_SETFL,f ) ;
	tcsetattr( STDIN_FILENO,TCSANOW,&ttystate ) ;
}
It confuses me that pressing a key either is ignored, or has heavy lag.
I understand it's a busy loop, but input is checked on every single iteration.

My understanding is that every keypress is stored in memory until you take it out with getchar, so a character should be waiting in that buffer after I hit a key.

this program works fine when I replaced the
Code:
printf( "X\n" )
with a call
to a heavy function that takes .3 seconds to compute. All that happened in that case
was that (assuming I pressed a key immediately) the program took either .3 or .6 seconds to stop.

To me that means that there must be something more to the terminal in/out stuff I don't know that would explain this behaviour, I believe that understanding/solving this problem would lead to valuable knowledge for myself.

please let me know if I wasn't clear enough about what I'm asking for help with, thx
 
Old 09-12-2014, 06:58 PM   #2
smallpond
Senior Member
 
Registered: Feb 2011
Location: Massachusetts, USA
Distribution: Fedora
Posts: 4,140

Rep: Reputation: 1263Reputation: 1263Reputation: 1263Reputation: 1263Reputation: 1263Reputation: 1263Reputation: 1263Reputation: 1263Reputation: 1263
O_NONBLOCK means don't block. If you never block, then nothing else can happen on the CPU while your program is running. I would guess your CPU is at 100% while in the loop.
 
Old 09-12-2014, 08:23 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
I just tried it here, the printf version seems to stop immediately for me.
 
1 members found this post helpful.
Old 09-13-2014, 12:37 AM   #4
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Here is an example to switch the keyboard into raw mode:
Code:
    struct termios oldtio, newtio;
    int rc;

    rc= tcgetattr (0, &oldtio);
    if (rc) {
        perror ("tcgetattr (0, &oldtio)");
	return 4;
    }
    memcpy (&newtio, &oldtio, sizeof (newtio));
    newtio.c_lflag &= ~(ISIG | ICANON | ECHO);
    newtio.c_iflag &= ~(INLCR | ICRNL | IXON | IXOFF);
    newtio.c_cflag &= ~(PARENB);
    newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS8;
    newtio.c_cc[VMIN] = 1;
    rc= tcsetattr (0, TCSAFLUSH, &newtio);
    if (rc) {
	perror ("tcsetattr (0, TCSAFLUSH, &newtio)");
	return 12;
    }
after this, you can use 'read(handle=0)' to read (not getchar, or other buffering function)
 
Old 09-13-2014, 07:24 PM   #5
NeoLux
LQ Newbie
 
Registered: Dec 2012
Posts: 15

Original Poster
Rep: Reputation: Disabled
smallpond: I appreciate the feedback, but would you mind explaining more clearly what you're trying to tell me ?

NevemTeve: I tried the code, with the exception of that read function 'read(handle=0)' not sure why you're setting a variable inside of a function I only found one function that was close that is syntax
Code:
 ssize_t read(int,void*,size_t)
and when I tried it out the input was blocking so It didn't get me to the solution I was looking for.

ntubski: I would really love to find out what the differences are for our circumstances. I ran
Code:
gcc test.c
Code:
./a.out
with gcc 4.9.1-1
on
xterm 309-1
ummm this is my output of 'stty'
Code:
# stty
speed 38400 baud; line = 0;
erase = ^H; eof = <undef>;
-brkint -imaxbel iutf8
I would ask for cpuinfo stuff, but I'm really hoping that your circumstances are ones that I can duplicate

I'm not sure what other settings would count, but just to verify, you compiled that code, and when it ran it printed X's in an infinite loop, and when you hit a key it stopped immediately ?
 
Old 09-13-2014, 11:18 PM   #6
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Sorry, that part wasn't meant for direct usage, it only meant 'read' from handle #0

The complete program is here: http://dtelnet.sf.net/shkeys.c
 
Old 09-14-2014, 12:10 PM   #7
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
I ran
Code:
gcc -Wall -Wextra -Wformat=2 -ggdb -pedantic -std=c99    noblock-term.c   -o noblock-term
Code:
./noblock-term
Code:
% gcc --version
gcc (Debian 4.9.1-4) 4.9.1
% stty
speed 38400 baud; line = 0;
iutf8
% urxvt -help 2>&1 | head -1
rxvt-unicode (urxvt) v9.20 - released: 2014-04-26
When I switch to xterm (310) then I get the delay too. And the scrolling of the Xs flickers a lot more.

stty on xterm is a bit different:
Code:
% stty
speed 38400 baud; line = 0;
-brkint -imaxbel iutf8
But unsetting -brkint and -imaxbel didn't help.
 
Old 09-14-2014, 12:32 PM   #8
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
@OP: It would be a good idea if you told what did you really wanted to accomplish with this program.
 
Old 09-14-2014, 10:35 PM   #9
NeoLux
LQ Newbie
 
Registered: Dec 2012
Posts: 15

Original Poster
Rep: Reputation: Disabled
NevemTeve: i will try it with your read function again once i get the chance God willing. As for the purpose, it was just a test program and this post was to find out why it didnt work the way i expected it to.

ntubski: that is very funny i actually kept thinking "what if hes using a different terminal like urxvt ?"
your post is very helpful, at least i have a chance to find out what might be the cause in difference of behaviour.
 
  


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
getchar() satellite Programming 10 12-24-2017 01:47 PM
What hinders the popularity of Linux? kuser:) Linux - General 44 03-01-2012 03:59 AM
LXer: App store licensing hinders OSS growth LXer Syndicated Linux News 0 05-24-2011 03:30 PM
Help with getchar() please geraneum Programming 9 12-18-2008 04:42 AM
about getchar() captainstorm Programming 6 10-11-2003 04:14 AM

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

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