<?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>blueslugs.com &#187; opensolaris</title>
	<atom:link href="http://blueslugs.com/tag/opensolaris/feed/" rel="self" type="application/rss+xml" />
	<link>http://blueslugs.com</link>
	<description>Observations from a West Coast family</description>
	<lastBuildDate>Thu, 22 Dec 2011 23:01:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>adirent.[ch]: Adding d_type to struct dirent on OpenSolaris</title>
		<link>http://blueslugs.com/2010/06/13/adirent-ch-adding-d_type-to-struct-dirent-on-opensolaris/</link>
		<comments>http://blueslugs.com/2010/06/13/adirent-ch-adding-d_type-to-struct-dirent-on-opensolaris/#comments</comments>
		<pubDate>Mon, 14 Jun 2010 02:47:47 +0000</pubDate>
		<dc:creator>Stephen</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[opensolaris]]></category>

		<guid isPermaLink="false">http://blueslugs.com/wordpress/?p=31588</guid>
		<description><![CDATA[An occasional porting problem you may encounter when compiling programs for OpenSolaris is the absence of d_type in the directory entry structure returned by readdir(3C). I hit this issue when experimenting with mu as a search solution for my accumulated email. A trivial example of the failure you might see would be caused by the [...]]]></description>
			<content:encoded><![CDATA[<p>An occasional porting problem you may encounter when compiling programs for OpenSolaris is the absence of <code>d_type</code> in the directory entry structure returned by <code>readdir</code>(3C).  I  hit this issue when experimenting with <a href="http://www.djcbsoftware.nl/code/mu/">mu</a> as a search solution for my accumulated email.</p>

<p>A trivial example of the failure you might see would be caused by the following program:</p>

<pre><code>#include &lt;sys/types.h&gt;
#include &lt;dirent.h&gt;
#include &lt;err.h&gt;
#include &lt;stdio.h&gt;

int
main(int argc, char *argv[])
{
        DIR *d;
        struct dirent *e;

        if ((d = opendir("/")) == NULL)
                err(1, "opendir failed");

        for (e = readdir(d); e != NULL; e = readdir(d)) {
                    if (e-&gt;d_type != DT_UNKNOWN)
                        (void) printf("recognized filetype for '%s'\n",
                            e-&gt;d_name);
        }

        (void) closedir(d);

        return (0);
 }
</code></pre>

<p>When we attempt to compile this program with <code>gcc</code>, we get something like</p>

<pre><code>$ gcc a.c
a.c: In function `main':
a.c:16: error: structure has no member named `d_type'
a.c:16: error: `DT_UNKNOWN' undeclared (first use in this function)
a.c:16: error: (Each undeclared identifier is reported only once
a.c:16: error: for each function it appears in.)
</code></pre>

<p>Studio <code>cc</code> will give similar output:</p>

<pre><code>$ /opt/SunStudioExpress/bin/cc a.c
"a.c", line 16: undefined struct/union member: d_type
"a.c", line 16: undefined symbol: DT_UNKNOWN
cc: acomp failed for a.c
</code></pre>

<p>The addition of <code>d_type</code> to <code>struct dirent</code> came first for the BSD Unixes and was later added to Linux.  Because it&#8217;s not easy to add members to well-known structures and preserve binary compatibility, OpenSolaris and Solaris lack this field, as well as the <code>DT_*</code> constant definitions.  (If <code>d_type</code> were to become part of the Unix standards, Solaris would likely have to introduce a second family of <code>opendir()</code>/<code>readdir()</code>/<code>closedir()</code> functions and a second version of the structure, similar to how large files were introduced for 32-bit programs.)</p>

<p>Because we fail at compilation time, our workaround has to modify either the program&#8217;s source code or its build environment.  (Preloading is too late.)  It&#8217;s probably possible to combine a few definitions and a shared object that we include via <code>LD_PRELOAD</code> but it seems easier to just provide a C wrapper around <code>readdir</code>(3C) and an alternate <code>struct dirent</code>.  We develop this approach in the next section.</p>

<h2><code>DIRENT</code> and <code>READDIR</code></h2>

<p>The approach we take is</p>

<ol>
<li>Introduce <code>DIRENT</code> and <code>READDIR</code> via <code>adirent.h</code>.</li>
<li>Change the source program such that each call to <code>readdir()</code> is replaced by <code>READDIR()</code> and each use of <code>struct dirent</code> is replaced by <code>DIRENT</code>.  In each file so modified, add a <code>#include &lt;adirent.h&gt;</code>.</li>
<li>Compile adirent.c via <code>gcc -I. -O2 -c adirent.c</code> or equivalent.</li>
<li>Add <code>adirent.o</code> to the link line for each binary that includes one of the files modified in step 2.</li>
</ol>

<p>If we apply these steps to our example above, we get</p>

<pre><code>#include &lt;sys/types.h&gt;
#include &lt;adirent.h&gt;
#include &lt;err.h&gt;
#include &lt;stdio.h&gt;

int
main(int argc, char *argv[])
{
        DIR *d;
        DIRENT *e;

        if ((d = opendir("/")) == NULL)
                err(1, "opendir failed");

        for (e = READDIR(d); e != NULL; e = READDIR(d)) {
                    if (e-&gt;d_type != DT_UNKNOWN)
                        (void) printf("recognized filetype for '%s'\n",
                            e-&gt;d_name);
        }

        (void) closedir(d);

        return (0);
 }
</code></pre>

<p>with the result that compilation and execution now work</p>

<pre><code>$ gcc -O2 -I. -c adirent.c
$ gcc -I. a.c adirent.o
$ ./a.out
</code></pre>

<p>This shim function and definitions should be sufficient for most ports around this incompatibility, but there are some additional comments worth making.</p>

<p><em>Performance.</em>  Because many programs expect <code>d_type</code> to be one of <code>DT_REG</code> or <code>DT_DIR</code> to save on a <code>stat</code>(2) call, this shim will force those programs into an alleged &#8220;slow&#8221; path.  The actual impact of returning <code>DT_UNKNOWN</code> on every call will be program- and situation-dependent; it didn&#8217;t seem to affect my mail indexing.</p>

<p><em>Multithreaded programs.</em>  The current implementation does not protect the static structure defined in <code>adirent.c</code>.  Programs with multiple threads performing <code>readdir</code>(3C) calls through <code>READDIR()</code> will get unexpected results.  It should be relatively straightforward to dynamically allocate one <code>struct adirent</code> for each thread coming through <code>READDIR()</code> for the first time.</p>

<h2>Downloads</h2>

<p>I suppose these should be in a repository on Bitbucket or GitHub.  For now, they&#8217;re just simple downloads:</p>

<ul>
<li><a href="http://blueslugs.com/~sch/adirent/adirent.c" title="Function implementation">adirent.c</a></li>
<li><a href="http://blueslugs.com/~sch/adirent/adirent.h" title="Header definitions">adirent.h</a></li>
</ul>

<h2>Acknowledgments</h2>

<p>I discussed this problem with <a href="http://blogs.sun.com/dp">Dan</a>, who in particular noted that <code>DT_UNKNOWN</code> was always a legal return value for <code>d_type</code>.  <a href="http://blogs.sun.com/barts">Bart</a> looked over my shoulder and spied at least one error during the debugging phase.</p>
<img src="http://blueslugs.com/?ak_action=api_record_view&id=31588&type=feed" alt=" adirent.[ch]: Adding d type to struct dirent on OpenSolaris"  title="adirent.[ch]: Adding d type to struct dirent on OpenSolaris" />]]></content:encoded>
			<wfw:commentRss>http://blueslugs.com/2010/06/13/adirent-ch-adding-d_type-to-struct-dirent-on-opensolaris/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>~4100MiB</title>
		<link>http://blueslugs.com/2008/04/26/4100mib/</link>
		<comments>http://blueslugs.com/2008/04/26/4100mib/#comments</comments>
		<pubDate>Sat, 26 Apr 2008 19:30:12 +0000</pubDate>
		<dc:creator>Stephen</dc:creator>
				<category><![CDATA[Observations]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[2008.05]]></category>
		<category><![CDATA[bittorrent]]></category>
		<category><![CDATA[opensolaris]]></category>

		<guid isPermaLink="false">http://blueslugs.com/wordpress/index.php/archives/2008/04/26/4100mib/</guid>
		<description><![CDATA[I seeded the 2008.05 release candidate for about 45 hours, ultimately shipping a little over 4100 megabytes. I&#8217;m going to take a break, because I want to update my DP2-based workstation and get some work done, but, once we have new bits, I&#8217;ll getting seeding again. (I found the actual result: 4237MiB sent up, so [...]]]></description>
			<content:encoded><![CDATA[<p>I seeded the 2008.05 release candidate for about 45 hours, ultimately shipping a little over 4100 megabytes.  I&#8217;m going to take a break, because I want to update my DP2-based workstation and get some work done, but, once we have new bits, I&#8217;ll getting seeding again.</p>

<p>(I found the actual result: 4237MiB sent up, so almost 4GiB.)</p>
<img src="http://blueslugs.com/?ak_action=api_record_view&id=501&type=feed" alt=" ~4100MiB"  title="~4100MiB" />]]></content:encoded>
			<wfw:commentRss>http://blueslugs.com/2008/04/26/4100mib/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

