<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>eduardofleury.com</title>
	<atom:link href="http://blog.eduardofleury.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.eduardofleury.com</link>
	<description>Thoughts, shuffled...</description>
	<pubDate>Thu, 21 Aug 2008 23:14:40 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
	<language>en</language>
			<item>
		<title>Improving QEdje and Qt performance with nvidia drivers.</title>
		<link>http://blog.eduardofleury.com/archives/2008/08/34/</link>
		<comments>http://blog.eduardofleury.com/archives/2008/08/34/#comments</comments>
		<pubDate>Thu, 21 Aug 2008 23:14:40 +0000</pubDate>
		<dc:creator>fleury</dc:creator>
		
		<category><![CDATA[English]]></category>

		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Misc Links]]></category>

		<category><![CDATA[Primary]]></category>

		<category><![CDATA[QEdje]]></category>

		<category><![CDATA[Qt]]></category>

		<category><![CDATA[gentoo]]></category>

		<category><![CDATA[kde]]></category>

		<category><![CDATA[nvidia]]></category>

		<category><![CDATA[opengl]]></category>

		<guid isPermaLink="false">http://blog.eduardofleury.com/?p=34</guid>
		<description><![CDATA[Hey all,
You may have been following the buzz around bad 2D performance of nvidia-drivers, specially with KDE 4. Well, I found out that QEdje was running slower than it could on my machine due to the same reason.
Zack Rusin released yesterday a nice benchmark utility for Qt, QGears2, which I used to measure the effect [...]]]></description>
			<content:encoded><![CDATA[<p>Hey all,</p>
<p>You may have been following the buzz around bad 2D performance of nvidia-drivers, specially with KDE 4. Well, I found out that QEdje was running slower than it could on my machine due to the same reason.</p>
<p>Zack Rusin released yesterday a nice benchmark utility for Qt, <a title="Zack Rusin blog - QGears2" href="Zack Rusin" target="_blank">QGears2</a>, which I used to measure the effect of <a title="Lemma's suggestion to improve nVidia 2D performance" href="http://techbase.kde.org/User:Lemma/KDE4-NVIDIA" target="_blank">Lemma&#8217;s suggestion on KDE&#8217;s techbase</a>.</p>
<p>My machine is a 2.4GHz Core 2 Duo / 2gb / nVidiaGeForce 8600M 256mb MacBook Pro, running Gentoo ~x86.</p>
<p>The first tests were conducted using:</p>
<ul>
<li>Xorg-server 1.4.2</li>
<li>Xorg 7.3</li>
<li>nvidia proprietary drivers (nvidia-drivers) 173.14.12</li>
</ul>
<p>The second test session were conducted after the following changes:</p>
<ul>
<li>nvidia proprietary drivers (nvidia-drivers) 177.67 beta (I&#8217;ve unmasked them in Gentoo)</li>
<li>Added PixmapCacheSize and OnDemandVBlankInterrupts options to xorg.conf</li>
<li>applied InitialPixmapPlacement and GlyphCache hacks:
<pre>nvidia-settings -a InitialPixmapPlacement=2 -a GlyphCache=1</pre>
</li>
</ul>
<p><strong>GEARSFANCY results</strong>:</p>
<p><strong>Old setup</strong>:</p>
<ul>
<li>-image  &#8211;&gt;  42 fps</li>
<li>-render &#8211;&gt; 35 fps</li>
<li>-gl &#8211;&gt; 396 fps</li>
</ul>
<p><strong>New setup</strong>:</p>
<ul>
<li>-image  &#8211;&gt;  67 fps</li>
<li>-render  &#8211;&gt;  41 fps</li>
<li>-gl  &#8211;&gt;  476 fps</li>
</ul>
<p>Let me know of your results.</p>
<p>Cheers,</p>
<p>Fleury</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eduardofleury.com/archives/2008/08/34/feed/</wfw:commentRss>
		</item>
		<item>
		<title>emerge world reinstalling everything&#8230; not anymore :-)</title>
		<link>http://blog.eduardofleury.com/archives/2008/08/32/</link>
		<comments>http://blog.eduardofleury.com/archives/2008/08/32/#comments</comments>
		<pubDate>Wed, 20 Aug 2008 23:08:08 +0000</pubDate>
		<dc:creator>fleury</dc:creator>
		
		<category><![CDATA[English]]></category>

		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Media]]></category>

		<category><![CDATA[gentoo]]></category>

		<category><![CDATA[emerge]]></category>

		<category><![CDATA[portage]]></category>

		<guid isPermaLink="false">http://blog.eduardofleury.com/?p=32</guid>
		<description><![CDATA[I&#8217;m running ~x86 Gentoo here, eix-sync &#38;&#38; emerge -Dav world every few days till something strange started happening. Portage wanted to reinstall everything, I mean, hundreds of packages to the same version as before, no new use, no new anything, just reinstall all packages for the pleasure of compiling and heating up my Macbook pro [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m running ~x86 Gentoo here, eix-sync &amp;&amp; emerge -Dav world every few days till something strange started happening. Portage wanted to reinstall everything, I mean, hundreds of packages to the same version as before, no new use, no new anything, just reinstall all packages for the pleasure of compiling and heating up my Macbook pro <img src='http://blog.eduardofleury.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Well, now I figured out that <strong>adding the &#8220;-u&#8221; flag to emerge restored the expected behaviour</strong>.</p>
<p>Maybe I was supposed to use &#8220;-u&#8221; since day one but the fact is I didn&#8217;t, and emerge worked fine until now. Anyway, if any of you face the same issue, try &#8220;-u&#8221;.</p>
<p>Cheers,</p>
<p>Fleury</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eduardofleury.com/archives/2008/08/32/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Running x11perf on Maemo (N800)</title>
		<link>http://blog.eduardofleury.com/archives/2008/08/29/</link>
		<comments>http://blog.eduardofleury.com/archives/2008/08/29/#comments</comments>
		<pubDate>Wed, 20 Aug 2008 03:25:14 +0000</pubDate>
		<dc:creator>fleury</dc:creator>
		
		<category><![CDATA[English]]></category>

		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Maemo]]></category>

		<category><![CDATA[Primary]]></category>

		<category><![CDATA[QEdje]]></category>

		<category><![CDATA[Qt]]></category>

		<category><![CDATA[qt qedje maemo english linux]]></category>

		<guid isPermaLink="false">http://blog.eduardofleury.com/?p=29</guid>
		<description><![CDATA[Hi all, this post is about some benchmarks we did on Nokia&#8217;s N800 device to measure the performance of XShmPutImage on this hardware.
I&#8217;ve been working on the QEdje project and, while studying possible optimizations, our team was interested in measuring whether we could benefit from using MIT&#8217;s X11 shared memory extensions. Among other tests, I [...]]]></description>
			<content:encoded><![CDATA[<p>Hi all, this post is about some benchmarks we did on Nokia&#8217;s N800 device to measure the performance of XShmPutImage on this hardware.</p>
<p>I&#8217;ve been working on the QEdje project and, while studying possible optimizations, our team was interested in measuring whether we could benefit from using MIT&#8217;s X11 shared memory extensions. Among other tests, I managed to run x11perf on the N800.</p>
<p>A simple patch was needed before cross-compiling it. This because this app has a hard-coded window size of 600&#215;600 pixels, more than what&#8217;s available in our 800&#215;480 screen, thus leading to a X error message, complaining about get screen parameters.</p>
<p>I also reduced the square side size from 500 to 400 pixels in the XShmPutImage and XPutImage tests (<em>shmput500</em> and <em>putimage500</em>).</p>
<p>The results were absolutely favorable to the use of the shared memory extension as you can see below:</p>
<p>./x11perf -<strong>shmput500</strong> -sync</p>
<p>800 reps @   8.6566 msec (   <strong>116.0/sec</strong>)</p>
<p>./x11perf <strong>-putimage500</strong> -sync</p>
<p>360 reps @  14.8336 msec (    <strong>67.4/sec</strong>)</p>
<p>For those willing to reproduce the tests, the patch is available below and should apply cleanly to x11perf 1.5.</p>
<p><a title="x11perf 1.5 patch" href="http://blog.eduardofleury.com/wp-content/uploads/x11perf-1.5-maemo.patch" target="_self">Download x11perf 1.5 patch</a></p>
<p>Cheers,</p>
<p>Fleury</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eduardofleury.com/archives/2008/08/29/feed/</wfw:commentRss>
		</item>
		<item>
		<title>KDE unresponsible after screensaver is locked for several hours.</title>
		<link>http://blog.eduardofleury.com/archives/2008/08/26/</link>
		<comments>http://blog.eduardofleury.com/archives/2008/08/26/#comments</comments>
		<pubDate>Mon, 04 Aug 2008 20:24:43 +0000</pubDate>
		<dc:creator>fleury</dc:creator>
		
		<category><![CDATA[English]]></category>

		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Primary]]></category>

		<category><![CDATA[kde bug screensaver kdesktop_lock fleury linux gentoo m]]></category>

		<guid isPermaLink="false">http://blog.eduardofleury.com/?p=26</guid>
		<description><![CDATA[Hi all, I&#8217;m currently using Gentoo ~x86 on a Macbook Pro and I&#8217;d been facing a really annoying bug for sometime before I could apply a workaround to it.
The bug sympthons are a very unresponsible system after leaving the screen locked for several hours, ie. all night, for instance, simply unlocking it was almost impossible. [...]]]></description>
			<content:encoded><![CDATA[<p>Hi all, I&#8217;m currently using Gentoo ~x86 on a Macbook Pro and I&#8217;d been facing a really annoying bug for sometime before I could apply a workaround to it.</p>
<p>The bug sympthons are a very unresponsible system after leaving the screen locked for several hours, ie. all night, for instance, simply unlocking it was almost impossible. It was also possible to see intense flickering of the screensaver unlock dialog.</p>
<p>Logging to the terminal was possible though and I found out that there were many kdesktop_lock instances running (more than 80) and they were eating up all machine resources. Killing all of them (ie. pkill kdesktop_lock) would bring the system back to life.</p>
<p>To understand what was happening I left a tiny script logging the number of kdesktop_lock instances all night so I could check the results the other day. It was then interesting to find out that two instances were being spawned every 5 minutes. Note that my screensaver timeout is 5 minutes, and I use two screens on KDE.</p>
<p>Probable cause, maybe due to the existance of a second monitor, KDE is failing to tell the screensaver is already active and is spawning a couple more, one for each screen, everytime the screensaver timeout is due.</p>
<p>Unfortunately I&#8217;m currently unable to investigate this bug in deeper detail due to our current <a title="QEdje on Morpheuz Blog" href="http://labs.morpheuz.eng.br/blog/01/08/2008/qedje-init/" target="_blank">QEdje</a> project but, meanwhile you can avoid it by disabling automatic screensaver and starting it manually when needed.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eduardofleury.com/archives/2008/08/26/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Ensol 2.0</title>
		<link>http://blog.eduardofleury.com/archives/2008/05/25/</link>
		<comments>http://blog.eduardofleury.com/archives/2008/05/25/#comments</comments>
		<pubDate>Fri, 02 May 2008 20:25:10 +0000</pubDate>
		<dc:creator>fleury</dc:creator>
		
		<category><![CDATA[Canola]]></category>

		<category><![CDATA[News]]></category>

		<category><![CDATA[Português]]></category>

		<category><![CDATA[Primary]]></category>

		<category><![CDATA[Talks]]></category>

		<category><![CDATA[ensol maemo mamona canola portugues]]></category>

		<guid isPermaLink="false">http://blog.eduardofleury.com/?p=25</guid>
		<description><![CDATA[Acontece nestes dias 2, 3 e 4 de Maio a segunda edição do Encontro de Software Livre da Paraíba, ou simplesmente, Ensol.
Eu, Eduardo Fleury, e Rodrigo Vivi, teremos o prazer de apresentar duas palestras na manhã do Domingo, dia 04 e agradecemos antecipadamente a presença de todos.
As palestras são independentes porém relacionadas, a primeira, Embarcando [...]]]></description>
			<content:encoded><![CDATA[<p>Acontece nestes dias 2, 3 e 4 de Maio a segunda edi<span>ç</span>ão do <strong>Encontro de Software Livre da Paraíba</strong>, ou simplesmente, Ensol.</p>
<p>Eu, Eduardo Fleury, e Rodrigo Vivi, teremos o prazer de apresentar duas palestras na manhã do Domingo, dia 04 e agradecemos antecipadamente a presen<span>ça de todos.</span></p>
<p>As palestras são independentes porém relacionadas, a primeira, <strong>Embarcando no Linux para sistemas embarcados (<a title="Rodrigo Vivi" href="http://blog.vivi.eng.br" target="_blank">Rodrigo Vivi</a>)</strong> ocorrerá as <strong>09.00h de Domingo</strong> e cobrirá os conceitos fundamentais das plataformas móveis embarcadas baseadas em Linux, mais especificamente o Mamona e o Maemo.</p>
<p>Na seqüência, às <strong>10.15h</strong> apresentarei a palestra <strong>Velejando com o Linux para sistemas embarcados</strong> na qual discutirei aspectos focados no desenvolvimento de aplica<span>ções para estas plataformas, incluindo questões como o ciclo de desenvolvimento e uma compara</span><span>ção entre linguagens de programa</span><span>ção</span>, partindo então para uma introdu<span>ção à linguagem </span>Python e suas principais características.</p>
<p>Links:</p>
<ul>
<li>Ensol 2.0 - <a title="http://www.ensol.org.br/2008/" href="http://www.ensol.org.br/2008/" target="_blank">http://www.ensol.org.br/2008/</a></li>
<li>Embarcando no Linux para sistemas embarcados - <a title="http://www.ensol.org.br/2008/node/74" href="http://www.ensol.org.br/2008/node/74" target="_blank">http://www.ensol.org.br/2008/node/74</a></li>
<li><span class="title">Velejando com o Linux para sistemas embarcados - <a title="http://www.ensol.org.br/2008/node/73" href="http://www.ensol.org.br/2008/node/73" target="_blank">http://www.ensol.org.br/2008/node/73</a></span></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.eduardofleury.com/archives/2008/05/25/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Running Canola2 plug-ins on the desktop</title>
		<link>http://blog.eduardofleury.com/archives/2008/04/24/</link>
		<comments>http://blog.eduardofleury.com/archives/2008/04/24/#comments</comments>
		<pubDate>Tue, 08 Apr 2008 19:54:43 +0000</pubDate>
		<dc:creator>fleury</dc:creator>
		
		<category><![CDATA[Canola]]></category>

		<category><![CDATA[English]]></category>

		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Primary]]></category>

		<category><![CDATA[canola linux]]></category>

		<guid isPermaLink="false">http://blog.eduardofleury.com/?p=24</guid>
		<description><![CDATA[Hey,
A few days ago the Canola2 SDK was released allowing users to run Canola2 on their Linux desktops for plug-ins and themes development. In this post I&#8217;ll show how one can add plugins to the SDK.
What you need

When deploying plugins to Canola2 SDK one must observe three main steps:

Install plug-in code
Install plug-in theme extension (for [...]]]></description>
			<content:encoded><![CDATA[<p>Hey,</p>
<p>A few days ago the Canola2 SDK was released allowing users to run Canola2 on their Linux desktops for plug-ins and themes development. In this post I&#8217;ll show how one can add plugins to the SDK.</p>
<p><strong>What you need<br />
</strong></p>
<p>When deploying plugins to Canola2 SDK one must observe three main steps:</p>
<ol>
<li>Install plug-in code</li>
<li>Install plug-in theme extension (for some themes)</li>
<li>Rebuild plug-in database</li>
</ol>
<p>Note that some plug-ins require extra interface widgets, for those the 2nd step must be completed, for the others it will be skipped.</p>
<p><strong>SDK directory structure</strong></p>
<p>In Canola2 SDK plug-ins code is located at:</p>
<blockquote><p>canola/plugins/&lt;plugin_name&gt;/*</p></blockquote>
<p>Note that the &lt;plugin-name&gt; folder may be zipped so you may also see plugins in the form:</p>
<blockquote><p>canola/plugins/&lt;plugin_name&gt;.zip</p></blockquote>
<p>The theme extensions for each plug-in however are in a different folder:</p>
<blockquote><p>canola/THEMES/&lt;theme_name&gt;-&lt;plugin_name&gt;.edj</p></blockquote>
<p><strong>Example HOWTO - Installing Canola YouTube plug-in</strong></p>
<p>Note that &lt;SDK-base-dir&gt; is the directory where you installed the Canola2 SDK, aka the directory you run Canola2 from.</p>
<p>1. Get Canola YouTube plug-in binaries from maemo repository:</p>
<blockquote><p>$ mkdir /tmp/canola-youtube</p>
<p>$ cd /tmp/canola-youtube</p>
<p>$ wget   http://repository.maemo.org/extras/pool/bora/free/c/canola-youtube-plugin/canola2-youtube-plugin_0.1.1-maemo1_all.deb</p></blockquote>
<p>2. Extract contents (see notes if you don&#8217;t have dpkg-deb installed)</p>
<blockquote><p>$ dpkg-deb -X canola2-youtube-plugin_0.1.1-maemo1_all.deb .</p></blockquote>
<p>3. Copy plug-in code to the SDK dir</p>
<blockquote><p>$ cp usr/share/canola/plugins/canola-tube.zip &lt;SDK-base-dir&gt;/plugins/</p></blockquote>
<p>4. Copy plug-in theme extension to SDK dir</p>
<blockquote><p>$ cp usr/share/canola/themes/*.edj &lt;SDK-base-dir&gt;/THEMES</p></blockquote>
<p>5. Rebuild plug-in database</p>
<blockquote><p>$ cd &lt;SDK-base-dir&gt;</p>
<p>$ ./run-canola &#8211;shell</p>
<p>$ bin/cnl-rescan-collections</p>
<p>$ exit</p></blockquote>
<p>6. Run Canola2 SDK and test the new plugin</p>
<blockquote><p>./run-canola -n</p></blockquote>
<p>Notes:</p>
<p>- You can use &#8220;alien -t&#8221; and &#8220;tar xf&#8221; to extract the .deb contents if you don&#8217;t have dpkg-deb installed on your system.</p>
<p>- If you download the source code of a plug-in you will have to compile each theme extension using &#8220;edje_cc&#8221; that comes with your SDK installation. Just run &#8220;./run-canola &#8211;shell&#8221; to set-up the environment and you&#8217;ll have the compiler available. For more information regarding making your own plug-ins check the &#8220;Plug-ins development&#8221; section in the Canola2 SDK <a title="Canola2 Development README" href="http://openbossa.indt.org/canola/source_files/Development-README" target="_blank">Development-README</a>.</p>
<p><strong>Additional Information</strong></p>
<p>Checkout the <strong>#canola</strong> channel on the <strong>Freenode.net</strong> IRC servers.</p>
<p>Cheers,</p>
<p>Fleury</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eduardofleury.com/archives/2008/04/24/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Time for change&#8230;</title>
		<link>http://blog.eduardofleury.com/archives/2008/03/22/</link>
		<comments>http://blog.eduardofleury.com/archives/2008/03/22/#comments</comments>
		<pubDate>Tue, 18 Mar 2008 20:51:25 +0000</pubDate>
		<dc:creator>fleury</dc:creator>
		
		<category><![CDATA[English]]></category>

		<category><![CDATA[Media]]></category>

		<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://blog.eduardofleury.com/archives/2008/03/22/</guid>
		<description><![CDATA[After two years working for LTC at IBM Brasil I decided it was time for new challenges and accepted an offer from INdT - Instituto Nokia de Tecnologia (Nokia&#8217;s Institute of Technology) for a Researcher position.
Since March 3rd, 2008 I live and work in Recife, PE, northeast of Brazil and work in the Canola project. [...]]]></description>
			<content:encoded><![CDATA[<p>After two years working for LTC at IBM Brasil I decided it was time for new challenges and accepted an offer from INdT - Instituto Nokia de Tecnologia (Nokia&#8217;s Institute of Technology) for a Researcher position.</p>
<p>Since March 3rd, 2008 I live and work in Recife, PE, northeast of Brazil and work in the Canola project. You can now reach me at #canola @ freenode, look for &#8220;efleury&#8221;.</p>
<p>Right now I&#8217;m attending to the Bossa Conference on Open Source Software for Mobile Embedded Platforms &#8216;08 in Porto de Galinhas, PE. Watch for some photos soon.</p>
<p>More info at: http://www.bossaconference.indt.org/</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eduardofleury.com/archives/2008/03/22/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Termios functions, the unix terminal canonical mode and other settings.</title>
		<link>http://blog.eduardofleury.com/archives/2007/11/16/</link>
		<comments>http://blog.eduardofleury.com/archives/2007/11/16/#comments</comments>
		<pubDate>Tue, 13 Nov 2007 18:08:05 +0000</pubDate>
		<dc:creator>fleury</dc:creator>
		
		<category><![CDATA[English]]></category>

		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Primary]]></category>

		<guid isPermaLink="false">http://blog.eduardofleury.com/archives/2007/11/16/</guid>
		<description><![CDATA[A few days ago I was rewriting in C an old piece of script originally coded in BASH. Although the code was pretty simple, I found   something that was worth sharing.
Basically I had to get a confirmation from the user (y/n) - ie. read char from the standard input - and process it [...]]]></description>
			<content:encoded><![CDATA[<p>A few days ago I was rewriting in C an old piece of script originally coded in BASH. Although the code was pretty simple, I found   something that was worth sharing.</p>
<p>Basically I had to get a confirmation from the user (y/n) - ie. read char from the standard input - and process it accordingly. However, rather than waiting for the use to press Return, I wanted to read the char as soon as typed. Besides that, I also wanted to have a timeout to unblock my program and assume a default answer after a given period of time.</p>
<p>In BASH that would be as simple as:</p>
<div class="codesnip-container" >
<div class="codesnip"><span class="kw3">read</span> -t <span class="nu0">5</span> -n <span class="nu0">1</span> MYVAR</div>
</div>
<p>In C this is not straightforward because, by default, UNIX terminals are line-oriented rather than byte-oriented. What does that mean? That means that your C program will only be aware of what was typed after the user presses &lt;Enter&gt;. And we still have the timeout issue. So how to do it?</p>
<p><strong>The Canonical Mode</strong></p>
<p>In Unix systems, the aforementioned line-oriented mode is called &#8220;The Canonical Mode&#8221;. This means that whatever you type is kept in an editable buffer managed by the terminal until you believe what you typed is right and press &lt;Enter&gt;. This is why you can use backspace, auto-complete, arrow keys, etc&#8230; And this is why getchar() or read() will block until &lt;Enter&gt; is pressed. :-/</p>
<p><strong>Termios functions </strong></p>
<p>Changing this behavior is easy with the <em>termios</em> set of functions, namely <em>tcgetattr</em>() and <em>tcsetattr</em>(), the documentation of which is available in man format - see <strong>termios</strong>(3).</p>
<p>These functions read or write terminal settings from or to <em>struct termios</em> arguments, these arguments (as explained in the same man page) have five components being that four bit masks and one integer array, each of these defining a group of related settings. In this post I focus on the ICANON and a few other related flags, however you can always read about the others in the man page.</p>
<p><strong>Example 1</strong> (<a href="http://blog.eduardofleury.com/wp-content/uploads/2007/11/termios0.c" title="Example 1">Download it!</a>):</p>
<pre>
<div class="codesnip-container" >
<div class="codesnip"><span class="coMULTI">/*************************************************************************
&nbsp;* Author: Eduardo M. Fleury - talkto (at) eduardofleury.com&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *
&nbsp;* Site&nbsp; : http://eduardofleury.com&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *
&nbsp;* Desc. : Example 1 from post: http://blog.eduardofleury.com/?p=16&nbsp; &nbsp; &nbsp; *
&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;*************************************************************************
&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;* This program is free software: you can redistribute it and/or modify&nbsp; *
&nbsp;* it under the terms of the GNU General Public License as published by&nbsp; *
&nbsp;* the Free Software Foundation, either version 3 of the License, or&nbsp; &nbsp; &nbsp;*
&nbsp;* (at your option) any later version.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;* This program is distributed in the hope that it will be useful,&nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;* but WITHOUT ANY WARRANTY; without even the implied warranty of&nbsp; &nbsp; &nbsp; &nbsp; *
&nbsp;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&nbsp; See the&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;* GNU General Public License for more details.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *
&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;* You should have received a copy of the GNU General Public License&nbsp; &nbsp; &nbsp;*
&nbsp;* along with this program.&nbsp; If not, see &lt;http://www.gnu.org/licenses/&gt;. *
&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;*************************************************************************/</span>

<span class="co2">#include &lt;stdio.h&gt;</span>
<span class="co2">#include &lt;stdlib.h&gt;</span>
<span class="co2">#include &lt;string.h&gt;</span>
<span class="co2">#include &lt;time.h&gt;</span>
<span class="co2">#include &lt;unistd.h&gt;</span>

<span class="co2">#include &lt;poll.h&gt;</span>
<span class="co2">#include &lt;termios.h&gt;</span>

<span class="kw4">int</span> main<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>

&nbsp; <span class="kw4">int</span> our_opt = <span class="nu0">0</span>;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="coMULTI">/* Our secret number */</span>
&nbsp; <span class="kw4">char</span> user_opt = <span class="nu0">0</span>;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="coMULTI">/* User guess&nbsp; &nbsp; &nbsp; &nbsp; */</span>

&nbsp; <span class="kw4">struct</span> termios tios, orig_tios;&nbsp; &nbsp; <span class="coMULTI">/* terminal settings */</span>

&nbsp; 
&nbsp; <span class="coMULTI">/* Seed random number gen */</span>
&nbsp; srandom<span class="br0">&#40;</span>time<span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; 
&nbsp; <span class="coMULTI">/* Get our number */</span>
&nbsp; our_opt = random<span class="br0">&#40;</span><span class="br0">&#41;</span> % <span class="nu0">10</span>;
&nbsp; 
&nbsp; <span class="coMULTI">/**********************************************************************/</span>
&nbsp; <span class="coMULTI">/* Ok, that's what we're here for... Lets play with terminal settings */</span>
&nbsp; <span class="coMULTI">/**********************************************************************/</span>

&nbsp; <span class="coMULTI">/* Get current terminal settings */</span>
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>tcgetattr<span class="br0">&#40;</span><span class="nu0">0</span>, &amp;orig_tios<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"Error getting current terminal settings<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">3</span>;
&nbsp; <span class="br0">&#125;</span>

&nbsp; <span class="coMULTI">/* Copy that to &quot;tios&quot; and play with it */</span>
&nbsp; tios = orig_tios;
&nbsp; 
&nbsp; <span class="coMULTI">/* We want to disable the canonical mode */</span>
&nbsp; tios.<span class="me1">c_lflag</span> &amp;= ~ICANON;

&nbsp; <span class="coMULTI">/* And make sure ECHO is enabled */</span>
&nbsp; tios.<span class="me1">c_lflag</span> |= ECHO;
&nbsp; 
&nbsp; <span class="coMULTI">/* Apply our settings */</span>
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>tcsetattr<span class="br0">&#40;</span><span class="nu0">0</span>, TCSANOW, &amp;tios<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"Error applying terminal settings<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">3</span>;
&nbsp; <span class="br0">&#125;</span>

&nbsp; <span class="coMULTI">/* Check whether our settings were correctly applied */</span>
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>tcgetattr<span class="br0">&#40;</span><span class="nu0">0</span>, &amp;tios<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; tcsetattr<span class="br0">&#40;</span><span class="nu0">0</span>, TCSANOW, &amp;orig_tios<span class="br0">&#41;</span>;
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"Error while asserting terminal settings<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">3</span>;
&nbsp; <span class="br0">&#125;</span>

&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>tios.<span class="me1">c_lflag</span> &amp; ICANON<span class="br0">&#41;</span> || !<span class="br0">&#40;</span>tios.<span class="me1">c_lflag</span> &amp; ECHO<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; tcsetattr<span class="br0">&#40;</span><span class="nu0">0</span>, TCSANOW, &amp;orig_tios<span class="br0">&#41;</span>;
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"Could not apply all terminal settings<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">3</span>;
&nbsp; <span class="br0">&#125;</span>

&nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"Choose a number [0-9]: "</span><span class="br0">&#41;</span>;
&nbsp; fflush<span class="br0">&#40;</span>stdout<span class="br0">&#41;</span>;

&nbsp; read<span class="br0">&#40;</span><span class="nu0">0</span>, &amp;user_opt, <span class="nu0">1</span><span class="br0">&#41;</span>;
&nbsp; user_opt -= <span class="nu0">48</span>;
&nbsp; 
&nbsp; <span class="coMULTI">/* Restore terminal settings */</span>
&nbsp; tcsetattr<span class="br0">&#40;</span><span class="nu0">0</span>, TCSANOW, &amp;orig_tios<span class="br0">&#41;</span>;
&nbsp; 
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>user_opt == our_opt<span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"<span class="es0">\n</span>Cool, you just won a helluva car!<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">0</span>;
&nbsp; <span class="br0">&#125;</span>
&nbsp; 
&nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"<span class="es0">\n</span>The right answer is %d. Take a walk, alright?<span class="es0">\n</span>"</span>, our_opt<span class="br0">&#41;</span>;
&nbsp; <span class="kw1">return</span> <span class="nu0">1</span>;

<span class="br0">&#125;</span></div>
</div>
</pre>
<p>The code above should be straightforward to follow, note that we:</p>
<ol>
<li>Get the current terminal settings with tcgetattr()</li>
<li>Disable the ICANON flag (Canonical mode) and enable the ECHO flag.</li>
<li>Apply the modified termios struct using tcsetattr().</li>
<li>Get the current terminal settings again and check it against the desired ones. This is important to do because tcsetattr() will report success whenever at least one setting was successfully changed, so, to make sure all of them where changed, we must manually assert it.</li>
<li>Call read.</li>
<li>Restore settings.</li>
</ol>
<p>This works fine, read() will unblock as soon as the first char is typed. However we don&#8217;t have a timeout yet.</p>
<p><strong>Timeout</strong></p>
<p>In C you can use <strong>poll</strong>(2) to implement the timeout, this works fine and is efficient. In this example I could set Poll to wait for an event of type POLLIN on the file descriptor STDIN_FILENO and also set a timeout value so it would block until something is available for reading or the time is up. After poll exits, its return code will let we know whether we had a timeout or success. This can be seen below.</p>
<p><strong>Example 2</strong> (<a href="http://blog.eduardofleury.com/wp-content/uploads/2007/11/poll.c" title="Example 2">Download it!</a>)</p>
<pre>
<div class="codesnip-container" >
<div class="codesnip"><span class="coMULTI">/*************************************************************************
&nbsp;* Author: Eduardo M. Fleury - talkto (at) eduardofleury.com&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;* Site&nbsp; : http://eduardofleury.com&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *
&nbsp;* Desc. : Example 2 from post: http://blog.eduardofleury.com/?p=16&nbsp; &nbsp; &nbsp; *
&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;*************************************************************************
&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;* This program is free software: you can redistribute it and/or modify&nbsp; *
&nbsp;* it under the terms of the GNU General Public License as published by&nbsp; *
&nbsp;* the Free Software Foundation, either version 3 of the License, or&nbsp; &nbsp; &nbsp;*
&nbsp;* (at your option) any later version.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;* This program is distributed in the hope that it will be useful,&nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;* but WITHOUT ANY WARRANTY; without even the implied warranty of&nbsp; &nbsp; &nbsp; &nbsp; *
&nbsp;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&nbsp; See the&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;* GNU General Public License for more details.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *
&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;* You should have received a copy of the GNU General Public License&nbsp; &nbsp; &nbsp;*
&nbsp;* along with this program.&nbsp; If not, see &lt;http://www.gnu.org/licenses/&gt;. *
&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;*************************************************************************/</span>

<span class="co2">#include &lt;stdio.h&gt;</span>
<span class="co2">#include &lt;stdlib.h&gt;</span>
<span class="co2">#include &lt;string.h&gt;</span>
<span class="co2">#include &lt;time.h&gt;</span>
<span class="co2">#include &lt;unistd.h&gt;</span>

<span class="co2">#include &lt;poll.h&gt;</span>
<span class="co2">#include &lt;termios.h&gt;</span>

<span class="kw4">int</span> main<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>

&nbsp; <span class="kw4">int</span> our_opt = <span class="nu0">0</span>;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="coMULTI">/* Our secret number */</span>
&nbsp; <span class="kw4">char</span> user_opt = <span class="nu0">0</span>;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="coMULTI">/* User guess&nbsp; &nbsp; &nbsp; &nbsp; */</span>

&nbsp; <span class="kw4">struct</span> pollfd pfd = <span class="br0">&#123;</span><span class="nu0">0</span>,<span class="nu0">0</span>,<span class="nu0">0</span><span class="br0">&#125;</span>;&nbsp; &nbsp; &nbsp; &nbsp;<span class="coMULTI">/* poll() settings&nbsp; &nbsp;*/</span>
&nbsp; <span class="kw4">int</span> pr;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/* poll() result&nbsp; &nbsp; &nbsp;*/</span>
&nbsp; <span class="kw4">struct</span> termios tios, orig_tios;&nbsp; &nbsp; <span class="coMULTI">/* terminal settings */</span>

&nbsp; 
&nbsp; <span class="coMULTI">/* Seed random number gen */</span>
&nbsp; srandom<span class="br0">&#40;</span>time<span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; 
&nbsp; <span class="coMULTI">/* Get our number */</span>
&nbsp; our_opt = random<span class="br0">&#40;</span><span class="br0">&#41;</span> % <span class="nu0">10</span>;
&nbsp; 
&nbsp; <span class="coMULTI">/* Get current terminal settings */</span>
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>tcgetattr<span class="br0">&#40;</span><span class="nu0">0</span>, &amp;orig_tios<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"Error getting current terminal settings<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">3</span>;
&nbsp; <span class="br0">&#125;</span>

&nbsp; <span class="coMULTI">/* Copy that to &quot;tios&quot; and play with it */</span>
&nbsp; tios = orig_tios;
&nbsp; 
&nbsp; <span class="coMULTI">/* We want to disable the canonical mode */</span>
&nbsp; tios.<span class="me1">c_lflag</span> &amp;= ~ICANON;

&nbsp; <span class="coMULTI">/* And make sure ECHO is enabled */</span>
&nbsp; tios.<span class="me1">c_lflag</span> |= ECHO;
&nbsp; 
&nbsp; <span class="coMULTI">/* Apply our settings */</span>
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>tcsetattr<span class="br0">&#40;</span><span class="nu0">0</span>, TCSANOW, &amp;tios<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"Error applying terminal settings<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">3</span>;
&nbsp; <span class="br0">&#125;</span>

&nbsp; <span class="coMULTI">/* Check whether our settings were correctly applied */</span>
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>tcgetattr<span class="br0">&#40;</span><span class="nu0">0</span>, &amp;tios<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; tcsetattr<span class="br0">&#40;</span><span class="nu0">0</span>, TCSANOW, &amp;orig_tios<span class="br0">&#41;</span>;
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"Error while asserting terminal settings<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">3</span>;
&nbsp; <span class="br0">&#125;</span>

&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>tios.<span class="me1">c_lflag</span> &amp; ICANON<span class="br0">&#41;</span> || !<span class="br0">&#40;</span>tios.<span class="me1">c_lflag</span> &amp; ECHO<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; tcsetattr<span class="br0">&#40;</span><span class="nu0">0</span>, TCSANOW, &amp;orig_tios<span class="br0">&#41;</span>;
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"Could not apply all terminal settings<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">3</span>;
&nbsp; <span class="br0">&#125;</span>

&nbsp; 
&nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"Choose a number [0-9]: "</span><span class="br0">&#41;</span>;
&nbsp; fflush<span class="br0">&#40;</span>stdout<span class="br0">&#41;</span>;

&nbsp; <span class="coMULTI">/*************************************************************
&nbsp; &nbsp;* This is new&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp; &nbsp;*************************************************************/</span>

&nbsp; <span class="coMULTI">/* Wait 5000 miliseconds for an POLLIN event on STDIN. */</span>
&nbsp; pfd.<span class="me1">fd</span> = STDIN_FILENO;
&nbsp; pfd.<span class="me1">events</span> = POLLIN;
&nbsp; pr = poll<span class="br0">&#40;</span>&amp;pfd, <span class="nu0">1</span>, <span class="nu0">5000</span><span class="br0">&#41;</span>;

&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>pr &gt; <span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="coMULTI">/* We have got something to read */</span>
&nbsp; &nbsp; read<span class="br0">&#40;</span><span class="nu0">0</span>, &amp;user_opt, <span class="nu0">1</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; user_opt -= <span class="nu0">48</span>;
&nbsp; <span class="br0">&#125;</span>
&nbsp; <span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span>!pr<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="coMULTI">/* We got a timeout */</span>
&nbsp; &nbsp; tcsetattr<span class="br0">&#40;</span><span class="nu0">0</span>, TCSANOW, &amp;orig_tios<span class="br0">&#41;</span>;
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"<span class="es0">\n</span>Sorry, time is up.<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">2</span>;
&nbsp; <span class="br0">&#125;</span>
&nbsp; <span class="kw1">else</span><span class="br0">&#123;</span>
&nbsp; &nbsp; tcsetattr<span class="br0">&#40;</span><span class="nu0">0</span>, TCSANOW, &amp;orig_tios<span class="br0">&#41;</span>;
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"<span class="es0">\n</span>Poll() error.<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">3</span>;
&nbsp; <span class="br0">&#125;</span>

&nbsp; <span class="coMULTI">/*************************************************************/</span>

&nbsp; <span class="coMULTI">/* Restore terminal settings */</span>
&nbsp; tcsetattr<span class="br0">&#40;</span><span class="nu0">0</span>, TCSANOW, &amp;orig_tios<span class="br0">&#41;</span>;

&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>user_opt == our_opt<span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"<span class="es0">\n</span>Cool, you just won a helluva car!<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">0</span>;
&nbsp; <span class="br0">&#125;</span>
&nbsp; 
&nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"<span class="es0">\n</span>The right answer is %d. Take a walk, alright?<span class="es0">\n</span>"</span>, our_opt<span class="br0">&#41;</span>;
&nbsp; <span class="kw1">return</span> <span class="nu0">1</span>;

<span class="br0">&#125;</span></div>
</div>
</pre>
<p><strong>Timeout using only read() </strong></p>
<p>Ok, poll() is nice but this post is not about it; so why not to implement a timeout using only read() and termios functions?</p>
<p>When ICANON is enabled the terminal has no difficulties to determine when the text input is ready to be sent to our application, just wait for an &lt;Enter&gt;. This task becomes more complicated when ICANON is disabled though. Should the terminal wait for more than one char before sending the text? Should it wait for a timeout?</p>
<p>Instead of a single answer for these questions, Linux lets the programmer tune the terminal to the best of his convenience, and this is what the variables <strong>c_cc[VMIN]</strong> and <strong>c_cc[VTIME]</strong> are for.</p>
<p>In a nutshell, if VMIN &gt; 0, it determines the number of received chars upon which read() calls will return immediately. If it&#8217;s Zero than read() will block until one char is available (more on that in 1 minute).</p>
<p>At the same time, if VTIME &gt; 0, it determines a timeout (in deciseconds) after which read() calls will return even if VMIN chars haven&#8217;t been read yet; Zero means no timeout. Cool, isn&#8217;t it?</p>
<p>What about the difference between VMIN = 0 and VMIN = 1? The difference is that in the former case the timeout counter (if applicable) will be started as soon as read() is called, which means that read() will return without any chars read after the timeout period; in the latter case however, the timeout is only enabled after the first char is typed and is reset when a new char arrives. Actually my understanding is that in terms of behavior, VMIN = 0 and VTIME = 0 are the same as VMIN = 1 and VTIME = anything. If you see a difference, please let me know.</p>
<p>So, our code would become:</p>
<p><strong>Example 3</strong> (<a href="http://blog.eduardofleury.com/wp-content/uploads/2007/11/termios.c" title="Example 3">Download it!</a>)</p>
<pre>
<div class="codesnip-container" >
<div class="codesnip"><span class="coMULTI">/*************************************************************************
&nbsp;* Author: Eduardo M. Fleury - talkto (at) eduardofleury.com&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;* Site&nbsp; : http://eduardofleury.com&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *
&nbsp;* Desc. : Example 3 from post: http://blog.eduardofleury.com/?p=16&nbsp; &nbsp; &nbsp; *
&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;*************************************************************************
&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;* This program is free software: you can redistribute it and/or modify&nbsp; *
&nbsp;* it under the terms of the GNU General Public License as published by&nbsp; *
&nbsp;* the Free Software Foundation, either version 3 of the License, or&nbsp; &nbsp; &nbsp;*
&nbsp;* (at your option) any later version.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;* This program is distributed in the hope that it will be useful,&nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;* but WITHOUT ANY WARRANTY; without even the implied warranty of&nbsp; &nbsp; &nbsp; &nbsp; *
&nbsp;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&nbsp; See the&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;* GNU General Public License for more details.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *
&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;* You should have received a copy of the GNU General Public License&nbsp; &nbsp; &nbsp;*
&nbsp;* along with this program.&nbsp; If not, see &lt;http://www.gnu.org/licenses/&gt;. *
&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*
&nbsp;*************************************************************************/</span>

<span class="co2">#include &lt;sys/types.h&gt;</span>
<span class="co2">#include &lt;stdio.h&gt;</span>
<span class="co2">#include &lt;string.h&gt;</span>
<span class="co2">#include &lt;stdlib.h&gt;</span>

<span class="co2">#include &lt;unistd.h&gt;</span>
<span class="co2">#include &lt;poll.h&gt;</span>
<span class="co2">#include &lt;termios.h&gt;</span>
<span class="co2">#include &lt;time.h&gt;</span>

<span class="co2">#define VMIN_VALUE 0</span>
<span class="co2">#define VTIME_VALUE 50</span>

<span class="kw4">int</span> main<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>

&nbsp; <span class="kw4">int</span> our_opt = <span class="nu0">0</span>;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="coMULTI">/* Our secret number&nbsp; &nbsp; */</span>
&nbsp; <span class="kw4">char</span> user_opt = <span class="nu0">0</span>;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="coMULTI">/* User guess&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span>
&nbsp; 
&nbsp; <span class="kw4">int</span> bytes_read = <span class="nu0">0</span>;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/* Number of bytes read */</span>

&nbsp; <span class="kw4">struct</span> termios tios, orig_tios;&nbsp; <span class="coMULTI">/* terminal settings&nbsp; &nbsp; */</span>

&nbsp; 
&nbsp; <span class="coMULTI">/* Seed random number gen */</span>
&nbsp; srandom<span class="br0">&#40;</span>time<span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; 
&nbsp; <span class="coMULTI">/* Get our number */</span>
&nbsp; our_opt = random<span class="br0">&#40;</span><span class="br0">&#41;</span> % <span class="nu0">10</span>;
&nbsp; 
&nbsp; <span class="coMULTI">/**********************************************************************/</span>
&nbsp; <span class="coMULTI">/* Ok, that's what we're here for... Lets play with terminal settings */</span>
&nbsp; <span class="coMULTI">/**********************************************************************/</span>

&nbsp; <span class="coMULTI">/* Get current terminal settings */</span>
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>tcgetattr<span class="br0">&#40;</span><span class="nu0">0</span>, &amp;orig_tios<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"Error getting current terminal settings<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">3</span>;
&nbsp; <span class="br0">&#125;</span>

&nbsp; <span class="coMULTI">/* Copy that to &quot;tios&quot; and play with it */</span>
&nbsp; tios = orig_tios;
&nbsp; 
&nbsp; <span class="coMULTI">/* We want to disable the canonical mode */</span>
&nbsp; tios.<span class="me1">c_lflag</span> &amp;= ~ICANON;

&nbsp; <span class="coMULTI">/* And make sure ECHO is enabled */</span>
&nbsp; tios.<span class="me1">c_lflag</span> |= ECHO;

&nbsp; <span class="coMULTI">/* Set timeout */</span>
&nbsp; tios.<span class="me1">c_cc</span><span class="br0">&#91;</span>VMIN<span class="br0">&#93;</span> = VMIN_VALUE;
&nbsp; tios.<span class="me1">c_cc</span><span class="br0">&#91;</span>VTIME<span class="br0">&#93;</span> = VTIME_VALUE;
&nbsp; 
&nbsp; <span class="coMULTI">/* Apply our settings */</span>
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>tcsetattr<span class="br0">&#40;</span><span class="nu0">0</span>, TCSANOW, &amp;tios<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"Error applying terminal settings<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">3</span>;
&nbsp; <span class="br0">&#125;</span>

&nbsp; <span class="coMULTI">/* Check whether our settings were correctly applied */</span>
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>tcgetattr<span class="br0">&#40;</span><span class="nu0">0</span>, &amp;tios<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; tcsetattr<span class="br0">&#40;</span><span class="nu0">0</span>, TCSANOW, &amp;orig_tios<span class="br0">&#41;</span>;
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"Error while asserting terminal settings<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">3</span>;
&nbsp; <span class="br0">&#125;</span>

&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="br0">&#40;</span>tios.<span class="me1">c_lflag</span> &amp; ICANON<span class="br0">&#41;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|| !<span class="br0">&#40;</span>tios.<span class="me1">c_lflag</span> &amp; ECHO<span class="br0">&#41;</span> ||
&nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#40;</span>tios.<span class="me1">c_cc</span><span class="br0">&#91;</span>VMIN<span class="br0">&#93;</span> != VMIN_VALUE<span class="br0">&#41;</span> ||&nbsp; <span class="br0">&#40;</span>tios.<span class="me1">c_cc</span><span class="br0">&#91;</span>VTIME<span class="br0">&#93;</span> != VTIME_VALUE<span class="br0">&#41;</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; tcsetattr<span class="br0">&#40;</span><span class="nu0">0</span>, TCSANOW, &amp;orig_tios<span class="br0">&#41;</span>;
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"Could not apply all terminal settings<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">3</span>;
&nbsp; <span class="br0">&#125;</span>

&nbsp; 
&nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"Choose a number [0-9]: "</span><span class="br0">&#41;</span>;
&nbsp; fflush<span class="br0">&#40;</span>stdout<span class="br0">&#41;</span>;

&nbsp; bytes_read = read<span class="br0">&#40;</span><span class="nu0">0</span>, &amp;user_opt, <span class="nu0">1</span><span class="br0">&#41;</span>;

&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!bytes_read<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="coMULTI">/* We got a timeout */</span>
&nbsp; &nbsp; tcsetattr<span class="br0">&#40;</span><span class="nu0">0</span>, TCSANOW, &amp;orig_tios<span class="br0">&#41;</span>;
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"<span class="es0">\n</span>Sorry, time is up.<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">2</span>;
&nbsp; <span class="br0">&#125;</span>
&nbsp; <span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span>bytes_read &lt; <span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; tcsetattr<span class="br0">&#40;</span><span class="nu0">0</span>, TCSANOW, &amp;orig_tios<span class="br0">&#41;</span>;
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"<span class="es0">\n</span>Read() error<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">3</span>;
&nbsp; <span class="br0">&#125;</span>

&nbsp; <span class="coMULTI">/* Restore terminal settings */</span>
&nbsp; tcsetattr<span class="br0">&#40;</span><span class="nu0">0</span>, TCSANOW, &amp;orig_tios<span class="br0">&#41;</span>;

&nbsp; user_opt -= <span class="nu0">48</span>;

&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>user_opt == our_opt<span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"<span class="es0">\n</span>Cool, you just won a helluva car!<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">0</span>;
&nbsp; <span class="br0">&#125;</span>
&nbsp; 
&nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"<span class="es0">\n</span>The right answer is %d. Take a walk, alright?<span class="es0">\n</span>"</span>, our_opt<span class="br0">&#41;</span>;
&nbsp; <span class="kw1">return</span> <span class="nu0">1</span>;

<span class="br0">&#125;</span></div>
</div>
</pre>
<p>Note that we set c_cc[VMIN] = 0 so read() can unblock even if nothing was typed and finally we define the timeout period using c_cc[VTIME] to 50 deciseconds (5 seconds). Then we use the return value of read() to determine whether it had an error, timeout or success condition.</p>
<p>This approach requires the use of non-canonical mode so you cannot use this to set a timeout when the user is required to enter a full line and you want to let him edit it, case when you must use poll(). I hope this is interesting from the learning point of view though. It&#8217;s always nice to understand how and why things work.</p>
<p>All examples in this page are released under the terms of GPLv3 and can be redistributed and modified under its terms.</p>
<p>Comments are always welcome and encouraged.</p>
<p>Take care.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eduardofleury.com/archives/2007/11/16/feed/</wfw:commentRss>
		</item>
		<item>
		<title>New blog on air ;-)</title>
		<link>http://blog.eduardofleury.com/archives/2007/10/15/</link>
		<comments>http://blog.eduardofleury.com/archives/2007/10/15/#comments</comments>
		<pubDate>Tue, 09 Oct 2007 14:42:02 +0000</pubDate>
		<dc:creator>fleury</dc:creator>
		
		<category><![CDATA[English]]></category>

		<category><![CDATA[Media]]></category>

		<category><![CDATA[Misc Links]]></category>

		<guid isPermaLink="false">http://blog.eduardofleury.com/archives/2007/10/15/</guid>
		<description><![CDATA[Hi all, today this space is dedicated to promote a blog just created by someone I love  My girlfriend Fabi.
Fabi, bienvenue a le monde du blogs!!!  
http://fabithome.blogspot.com
]]></description>
			<content:encoded><![CDATA[<p>Hi all, today this space is dedicated to promote a blog just created by someone I love <img src='http://blog.eduardofleury.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> My girlfriend <a href="http://fabithome.blogspot.com" target="_blank">Fabi</a>.</p>
<p>Fabi, bienvenue a le monde du blogs!!! <img src='http://blog.eduardofleury.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>http://fabithome.blogspot.com</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eduardofleury.com/archives/2007/10/15/feed/</wfw:commentRss>
		</item>
		<item>
		<title>AF_UNIX sockets and the abstract namespace, inter-process communication.</title>
		<link>http://blog.eduardofleury.com/archives/2007/09/13/</link>
		<comments>http://blog.eduardofleury.com/archives/2007/09/13/#comments</comments>
		<pubDate>Sun, 23 Sep 2007 23:36:09 +0000</pubDate>
		<dc:creator>fleury</dc:creator>
		
		<category><![CDATA[English]]></category>

		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Primary]]></category>

		<guid isPermaLink="false">http://blog.eduardofleury.com/archives/2007/09/13/</guid>
		<description><![CDATA[Hi all, today I&#8217;ll write something about sockets of the AF_UNIX family (aka as AF_LOCAL) and more specifically about the &#8220;abstract namespace&#8221; held by the Linux kernel.
Previous knowledge
Before I start, let me share what I expect you to know before reading this article, and also some references in case you are not familiar with these [...]]]></description>
			<content:encoded><![CDATA[<p>Hi all, today I&#8217;ll write something about sockets of the AF_UNIX family (aka as AF_LOCAL) and more specifically about the &#8220;abstract namespace&#8221; held by the Linux kernel.</p>
<p><strong>Previous knowledge</strong></p>
<p>Before I start, let me share what I expect you to know before reading this article, and also some references in case you are not familiar with these terms yet. <img src='http://blog.eduardofleury.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<ul>
<li>Processes - A process is an independent part of a computer program; they are composed of a sequence of instructions that run following a sequential path,  a private memory space and context information. Unlike threads, different processes don&#8217;t share memory, so when two of them need to communicate, we need to use one of the so called &#8220;inter-process communication methods&#8221;. For more information about that I recommend the <a href="http://wikipedia.org" title="Wikipedia" target="_blank">Wikipedia</a> and the book <a href="http://www.amazon.com/dp/0130313580/ref=s9_asin_image_1/102-9231269-3294502?pf_rd_m=ATVPDKIKX0DER&amp;pf_rd_s=center-2&amp;pf_rd_r=1GR2T57SEZE81V60QHDW&amp;pf_rd_t=101&amp;pf_rd_p=278240301&amp;pf_rd_i=507846" title="Modern Operating Systems, by Andrew Tanenbaum" target="_blank">Modern Operating Systems</a>, by Andrew Tanenbaum.</li>
<li>Sockets - In this context, sockets are bi-directional inter-process communication channels; being available in several flavors, some of them allow communication through network interfaces, others rely on the system kernel only as the carrier, and so forth. Differences also exist on reliability, message boundaries preservation, etc. In this article I&#8217;ll focus on sockets of the family AF_UNIX (or AF_LOCAL), although most of the information provided here applies to all AF_UNIX sockets, examples will be based on sockets of the subtype SOCK_STREAM.</li>
</ul>
<p><strong>AF_UNIX sockets</strong></p>
<p>These sockets provide a communication channel between two processes in the same machine, they are not visible from other machines and cannot be used to establish communication using the network interface. For the latter case see AF_INET sockets.</p>
<p>Every socket family has its own addressing scheme, while you can identify a specific AF_INET socket by an IP address/port pair, this is not true with AF_UNIX sockets. So, how do I address these? Please keep reading, this is what this post is all about.</p>
<p>Reliability is present in most AF_UNIX sockets implementations, the Linux implementation is an example. However, the only subtypes that are formally reliable are the SOCK_STREAM and SOCK_SEQPACKET types, both connection oriented but with some differences in the maximum message length and message boundaries preservation.</p>
<p><strong>The challenge</strong></p>
<p>A couple of weeks ago I was dealing with a situation where I had to code a script that would be run from a chroot&#8217;ed environment and that would be able to pull files from outside the chroot sandbox. In other situations I could do the opposite, ie. push files from the outside environment to the chroot folder, or maybe I could mount the source directory inside the chroot folder&#8230; but this case was different, neither I had control over the chroot&#8217;ing procedure nor I knew beforehand in which folder would my script would be running on. This because this script would be run in Anaconda&#8217;s or Yast&#8217;s post install, inside a just partitioned and installed system.</p>
<p>Although I could try using some heuristics to parse log files and discover the right target directory I wanted to make it right, put together something reliable, that I wouldn&#8217;t have to revisit in the future.</p>
<p><strong>The idea</strong></p>
<p>For some time I would think about how to do it&#8230; finally I though about some kind of client/server architecture where I would have a server with access to the files and a client run from the chroot&#8217;ed environment; both processes should communicate and the files would make their way through a pipe&#8230; or a socket! <img src='http://blog.eduardofleury.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Then I started some investigation on how to code my new idea, first I though of pipes, but these wouldn&#8217;t work as the processes would be started independently, from different shells, in different moments, and pipes need to be created at once, not in parts. Then I remembered sockets, AF_UNIX sockets.</p>
<p><strong>Sockets create/bind/listen/accept logic</strong></p>
<p>Before you can use sockets as a bi-directional communication channel, some handshaking and setup is necessary. Sockets of type SOCK_STREAM or other connection-oriented types follow the following logic until a connection is established:</p>
<ol>
<li>Node A <strong>creates</strong> a new socket.</li>
<li>If node A wants its socket to be visible from other processes, it must publish it, or assign it to an univocal address. This assignment is called &#8220;<strong>binding</strong>&#8220;.</li>
<li>After the socket is bond to a name, node A must put its socket in the <strong>listen</strong> state, this creates a backlog queue where new connection requests will be placed and served on a FIFO base. If the socket is not in the listen state or if its backlog is full, connection attempts will be denied.</li>
<li>Finally, when node A has a bond socket and a connection request, all it needs to do is <strong>accept</strong> this request. The accept command can be blocking and this will make the server wait for a client before proceeding. After a successfully connection a new &#8220;<strong>connected socket</strong>&#8221; that can be used for communication is created.</li>
</ol>
<p>In the client side the process is even more straightforward.</p>
<ol>
<li>Node B <strong>creates</strong> a new socket, of the same family and type as the one Node A has created.</li>
<li>Node B tries to <strong>connect </strong>to an address it must know somehow. When the connection is established, communication occurs under the scheme defined by the socket type, for instance, as a reliable byte stream when you have a SOCK_STREAM socket.</li>
</ol>
<p>This procedure is common for most sockets families and types, with just two exceptions: datagram oriented sockets don&#8217;t require connection (so it&#8217;s just create, bind and go) and, the address scheme. All sockets have to be bond to an address before connections are received, but addresses are different for each socket family.</p>
<p>For instance, when one is creating a socket to communicate with another computer in the network, it must bind to a given port and network interface. This pair, IP and port is the address the other node will need to use when connecting to that socket. In AF_UNIX sockets, the address is slight different as you will see below.</p>
<p><strong>AF_UNIX sockets addressing</strong></p>
<p>In most cases AF_UNIX sockets are bond to filenames, that&#8217;s the ordinary addressing space used by them. So the server creates a socket, binds it to a filename somewhere in its filesystem and waits for a connection. It was clear that wouldn&#8217;t solve my problem. If I had a folder where one of my processes could write and the other read my very first problem wouldn&#8217;t exist <img src='http://blog.eduardofleury.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<p>That&#8217;s when I found the Abstract Namespace.</p>
<p><strong>The solution - Abstract Namespace</strong></p>
<p>The Linux kernel holds in its memory space a <strong>table of open sockets</strong>. AF_UNIX sockets can be bond to &#8220;names&#8221; rather than &#8220;files&#8221;, it&#8217;s that simple, you just give your socket a name, an identifier, and then all other process can find it by its name, no matter which filesystem it&#8217;s running in! No matter whether it&#8217;s running in a chroot&#8217;ed environment or not! <img src='http://blog.eduardofleury.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':-D' class='wp-smiley' /> </p>
<p>In a few minutes I had a functional proof of concept, two processes talking, one inside a chroot&#8217;ed environment and the other outside. After that all I had to do was code some extra logic and avoid race conditions.</p>
<p><strong>How to bind a socket to the Abstract Namespace</strong></p>
<p>AF_UNIX socket names are always a sequence of chars, something like a C string, but with some peculiarities and differences in behavior. Instructing the bind function to use a filename or an abstract name is just a matter of crafting the right char sequence.</p>
<p>Ordinary bind names, that are associated to filenames, are simply ordinary strings, sequences of letters and numbers terminated by a null-byte. Calling bind with a &#8220;name&#8221; in this format will create a file in the path specified by &#8220;name&#8221;.</p>
<p>The trick to trigger the abstract namespace is simple: <strong>start the name with a null-byte</strong>. All characters found after the null-byte will then be interpreted as the identifier name and the socket will registered by the Kernel under the given name.</p>
<p>After that, just use the same string in the client and you will have a working socket.</p>
<p><strong>Note for C programmers</strong></p>
<p>Unlike high-level bind functions found in languages like Python, the <strong>bind(2)</strong> syscall arguments requires some attention. As you may have noticed in the above text, unlike C strings and path names, abstract namespace identifiers are not null-terminated strings; their length must be provided in the <em>socklen_t</em> <em>addrlen</em> argument. This means that the char sequences:</p>
<ol>
<li>0&#215;48454C4C4F00         (&#8221;HELLO\0&#8243;)    and</li>
<li>0&#215;48454C4C4F0000    (&#8221;HELLO\0\0&#8243;)</li>
</ol>
<p>represent different bind points. So make sure you pass the right length to avoid segmentation faults or undesired behavior, especially when creating clients and servers using different languages.</p>
<p><strong>Simple example in Python</strong></p>
<p>BTW, sorry for the bad indentation, I still must find a nice way of posting code using this blog theme. Suggestions are appreciated <img src='http://blog.eduardofleury.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> Meanwhile, you can download the code here &#8211;&gt; <a href="http://blog.eduardofleury.com/wp-content/uploads/2007/09/abstractnamespace.txt" title="AF_UNIX - Python example">AF_UNIX - Python example</a>.</p>
<p><strong><em>Server code </em></strong>from socket import *</p>
<p># Create an unbound and not-connected socket.<br />
sock = socket(AF_UNIX, SOCK_STREAM)</p>
<p># Bind the socket to &#8220;MyBindName&#8221; in the abstract namespace. Note the null-byte.<br />
sock.bind(&#8221;\0MyBindName&#8221;)</p>
<p># Create a backlog queue for up to 1 connection.<br />
sock.listen(1)</p>
<p># Blocks until a connection arrives. A tuple (connected_socket, None) is returned<br />
# upon connection. Note we get the first argument and throw away the rest.<br />
conn = sock.accept()[0]</p>
<p># Say hi<br />
conn.send(&#8221;Hello World\n&#8221;)</p>
<p># Wait for response<br />
msg = conn.recv(100)<br />
print msg</p>
<p># Close it, this will unblock the other peer in case it&#8217;s waiting for another message.<br />
conn.close()</p>
<p><em><strong>Client code</strong></em></p>
<p>from socket import *</p>
<p># Create an unbound and not-connected socket.<br />
sock = socket(AF_UNIX, SOCK_STREAM)</p>
<p># Connect to the peer registered as &#8220;MyBindName&#8221; in the abstract namespace. Note the &#8216;\0&#8242;.<br />
sock.connect(&#8221;\0MyBindName&#8221;)</p>
<p># Wait for message<br />
msg = sock.recv(100)<br />
print msg</p>
<p># Send reply<br />
sock.send(&#8221;Hi there!\n&#8221;)</p>
<p># Block until new message arrives<br />
msg = sock.recv(100)</p>
<p># When the socket is closed cleanly, recv unblocks and returns &#8220;&#8221;<br />
if not msg:<br />
print &#8220;It seems the other side has closed its connection&#8221;</p>
<p># Close it<br />
sock.close()</p>
<p>That&#8217;s all for today. Don&#8217;t forget to leave your comment! <img src='http://blog.eduardofleury.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eduardofleury.com/archives/2007/09/13/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 1.533 seconds -->
