<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jeremy Visser &#187; unix</title>
	<atom:link href="http://jeremy.visser.name/tag/unix/feed/" rel="self" type="application/rss+xml" />
	<link>https://jeremy.visser.name</link>
	<description></description>
	<lastBuildDate>Sun, 05 Sep 2010 12:29:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
	<atom:link rel='hub' href='https://jeremy.visser.name/?pushpress=hub'/>
<cloud domain='jeremy.visser.name' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
		<item>
		<title>How terminals work</title>
		<link>https://jeremy.visser.name/2009/10/18/how-terminals-work/</link>
		<comments>https://jeremy.visser.name/2009/10/18/how-terminals-work/#comments</comments>
		<pubDate>Sun, 18 Oct 2009 06:49:22 +0000</pubDate>
		<dc:creator>Jeremy</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[unix]]></category>
		<category><![CDATA[writing]]></category>

		<guid isPermaLink="false">http://jeremy.visser.name/?p=1261</guid>
		<description><![CDATA[Via @toros on Identi.ca, I stumbled across this awesome explanation by Scott James Remnant on how terminals (real terminals, virtual terminals, and pseudo terminals) in Unix work. Because it is pasted from an IRC conversation, it is a little hard to follow, so I present it to you reformatted to be more readable. (I have [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://identi.ca/notice/12016497">Via</a> @<a href="http://identi.ca/toros">toros</a> on Identi.ca, I stumbled across this awesome <a href="https://bugs.launchpad.net/ubuntu/+source/usplash/+bug/439138/comments/122">explanation</a> by <a href="http://www.netsplit.com/">Scott James Remnant</a> on how terminals (real terminals, virtual terminals, and pseudo terminals) in Unix work.</p>
<p>Because it is pasted from an IRC conversation, it is a little hard to follow, so I present it to you reformatted to be more readable. (I have tried to remain as faithful as possible to the original.)</p>
<h4>How Terminals Work</h4>
<p>By <a href="http://www.netsplit.com/">Scott James Remnant</a></p>
<p>In Linux, we have consoles, but really we mean Virtual Terminals (VTs), TTYs, and Pseudo-Terminals (PTYs). It&#8217;s all a bit of the kind of jumble sale you get after 40 years of different solutions to different problems. We can lump them together under the description &#8220;terminals&#8221; for the next bit.</p>
<p>We also have processes. Now, processes have a lot of odd little details: they have a parent, and they have a session. A session has a foreground process group and a background process group. (Stevens devotes an entire chapter for this and nobody but me apparently understands it. And hopefully the guy who maintains the kernel side. <img src='https://jeremy.visser.name/wordpress/wp-content/plugins/tango-smilies/tango/face-wink.png' alt=';)' class='wp-smiley' /> )</p>
<p>So, each process is part of a session &mdash; a process may begin a new session by calling <code>setsid()</code>. Every process that init creates is in its own session. The process is also then the leader of the foreground process group of that session. New processes are also in that session, and in that process group, unless otherwise placed into a new process group (<code>setpgrp()</code>). Any new process group is a background process group.</p>
<p>So now, you have a bunch of sessions. Each session has a bunch of process groups, one of which is the foreground process group. Each process group has a bunch of processes, one of which is the leader.</p>
<p>So this all has to do, fundamentally, with terminals, and who gets the signals.</p>
<p>When the leader of the foreground process group of a session opens a terminal device (without <code>O_NOCTTY</code>) that becomes the controlling terminal of that process group and session. The terminal and the session become bound to each other.</p>
<p>You can fake this another way by opening a terminal device without <code>O_NOCTTY</code> (or having one passed to you) and then calling the <code>TIOCSCTTY</code> <code>ioctl()</code>.</p>
<p>Okay, so: terminals, controlling terminals and processes &mdash; here&#8217;s where this gets fun.</p>
<p>If the controlling terminal is hung up, <code>SIGHUP</code> is sent to the foreground process group. If <code>^C</code> is pressed on the controlling terminal, <code>SIGINT</code> is sent to the foreground process group. If <code>^Z</code> is pressed on the controlling terminal, <code>SIGTSTP</code> is sent to the foreground process group. And so on and so forth.</p>
<p>So this is how the relationship between magic key presses and signals gets established. Shells care about this a lot (and yes, when you use <code>command <em>&#038;</em></code> that becomes a background process group, and when you use <code>command <em>|</em> command</code> they are all in the same process group).</p>
<p>Now, this controlling terminal business applies to all terminals, whether they be true terminals (which Linux doesn&#8217;t have), virtual terminals, or pseudo terminals. So this is as true for your SSH login as your VT1.</p>
<p>You can always access your <em>controlling terminal</em> using <code>/dev/tty</code> &mdash; (it&#8217;s a badly named device node); it may also be called /<code>dev/ttyS0</code> or <code>/dev/pts/4</code>, etc.</p>
<p>So, Linux has a bunch of virtual terminals. These are the things we think of when we say &#8220;console&#8221; but we&#8217;re using that wrongly. Virtual terminals behave just like ordinary terminals: they can be the controlling terminal for a process group, but unfortunately, stacked on top is the linux VT API &mdash; they didn&#8217;t think to make it separate.</p>
<p>So the stuff to set fonts &mdash; to place it in raw or graphics mode, create new VTs, switch VTs, etc. &mdash; is all loaded into the TTY API, so in order for X to function, it needs a VT. X needs access to that VT in interesting and familiar ways to place it into raw and graphics mode, and so on.</p>
<p>X also needs to know if the <em>current VT</em> is switched, so it opens the VT device it wants (<code>/dev/tty7</code>), and that becomes its controlling terminal. So if you were to delete VT7, X would get <code>SIGHUP</code>. <img src='https://jeremy.visser.name/wordpress/wp-content/plugins/tango-smilies/tango/face-smile.png' alt=':)' class='wp-smiley' /> </p>
<p>Now, on VT1-6 you have <code>getty</code>, and on VT8 you have <code>usplash</code>, and so on. This is all fine and dandy, except there&#8217;s this last mystical piece: <code>/dev/console</code>. <code>/dev/console</code> is, like <code>/dev/tty</code>, a fake device: it points at the currently active VT, whatever that is. But it <em>behaves</em> like a terminal in its own right (whereas <code>/dev/tty</code> just behaves as a proxy for the underlying terminal).</p>
<p>Now, Upstart has a few knobs to customise the standard input, output and error file descriptors. Normally it just starts all jobs with them as <code>/dev/null</code>, but for emulation of <code>sysvinit</code>, it has two other options:</p>
<ol>
<li>Set them to <code>/dev/console</code></li>
<li>Set them to <code>/dev/console</code> and issue the <code>TIOCSCTTY</code> <code>ioctl()</code> (console output, console owner)</li>
</ol>
<p>Now, if your current VT is 7 (X), and you start a job that has console owner in it, the new process will take the terminal away from X! X gets <code>SIGHUP</code>, and either hits 100% CPU or crashes. Solving this problem for good requires jobs that need user input to be rewritten.</p>
<p>So this is clearly bad. The problem really is that things need a &#8220;console&#8221; at all &mdash; jobs that require interaction should do it themselves: they should open a VT, switch to it, and ask there. Or they should use usplash to do it &mdash; or they should use X.</p>
<p><a href="https://bugs.launchpad.net/ubuntu/+source/usplash/+bug/439138/comments/122">Link to original source</a></p>
]]></content:encoded>
			<wfw:commentRss>https://jeremy.visser.name/2009/10/18/how-terminals-work/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
