<?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>Mac OS X Internals &#187; The Book</title>
	<atom:link href="http://osxbook.com/blog/category/the-book/feed/" rel="self" type="application/rss+xml" />
	<link>http://osxbook.com/blog</link>
	<description>A Systems Approach</description>
	<lastBuildDate>Fri, 30 Sep 2011 07:20:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Extending HFSDebug</title>
		<link>http://osxbook.com/blog/2008/07/23/extending-hfsdebug/</link>
		<comments>http://osxbook.com/blog/2008/07/23/extending-hfsdebug/#comments</comments>
		<pubDate>Wed, 23 Jul 2008 08:08:08 +0000</pubDate>
		<dc:creator>amit</dc:creator>
				<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[The Book]]></category>

		<guid isPermaLink="false">http://www.osxbook.com/blog/?p=99</guid>
		<description><![CDATA[Recently, I had a need to know if any files or folders had been modified or created on an HFS+ volume in the past N seconds. There are many ways you could generate this type of information on Mac OS X. To begin with, you could try asking Spotlight. Besides Spotlight, Mac OS X has [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I had a need to know if any files or folders had been modified or created on an HFS+ volume in the past <em>N</em> seconds. There are many ways you could generate this type of information on Mac OS X.</p>
<p>To begin with, you could try asking Spotlight.</p>
<p>Besides Spotlight, Mac OS X has a rich variety of mechanisms and APIs for learning about file system changes.</p>
<p>On Leopard, you could write a program that uses the FSEvents API to learn of <em>directory-level</em> changes that occur on a volume. The FSEvents API is part of <code>CoreServices.framework</code>. &quot;Directory-level&quot; means that this API is best suited for monitoring large directory trees&mdash;it will not tell you when a particular file changes.</p>
<p>To monitor specific files, you could use the <em>kqueues</em> mechanism. (See <code>kqueue(2)</code>.) Being file-level, kqueues don&#8217;t scale like the FSEvents API as you will need to monitor each file system object separately. Therefore, it&#8217;s better suited for situations where you need to monitor only a few specific objects.</p>
<p>You could also directly use the low-level fsevents mechanism (<code>/dev/fsevents</code>) that underlies the FSEvents API and Spotlight&mdash;but <strong>only</strong> if your need is experimental in nature. The <a href="http://osxbook.com/software/fslogger/" title="A File System Change Logger"><code>fslogger</code></a> program is an example of directly using the fsevents mechanism. <code>fslogger</code> will tell you&mdash;in pretty much real time&mdash;when file system objects change. (Make sure to see <a href="http://osxbook.com/book/bonus/chapter11/fslogger/#FSLOGGER_CAVEAT" title="FSLogger: Caveats">caveats</a>.)</p>
<p>Then there is the kauth mechanism that was introduced in Tiger, primarily to help creators of virus scanning software. Kauth allows for <em>extremely</em> fine-grained file system activity monitoring&mdash;you can see vnode-level operations. In fact, monitoring is sort of a side effect of using the kauth mechanism. You can actually allow and deny individual operations, as virus scanning software might need to. However, kauth is not easy to use. (Not that the other APIs mentioned necessarily are!) To use kauth, you need to write a kernel extension. You also need to be extremely careful in what you do so as not to deadlock the operating system.</p>
<p>There also exist tools like <code>fs_usage</code> and <code>dtrace</code> on Mac OS X. <code>fs_usage</code> uses the kernelâ€™s <em>kdebug</em> facility to perform fine-grained tracing of kernel events. In particular, it allows you to trace file system activity. Beginning with Leopard, the DTrace facility, to which <code>dtrace</code> is a front-end, lets you trace all kinds of activity at both the kernel and user levels. You could do some very imaginative things with <code>dtrace</code>.</p>
<p>So, we see that there is no dearth of ways to monitor file system activity on Mac OS X. However, there are caveats associated with each way we looked at so far. Consider Spotlight. To use it, we would be assuming that Spotlight indexing was enabled on the volume in question. Spotlight also doesn&#8217;t look everywhere: your areas of interest on the file system might be outside of Spotlight&#8217;s default or configured search scope. Moreover, to use or the other APIs we talked about, you will need to have the volume <em>mounted</em>&mdash;usually a reasonable requirement, except it may not be an option if, for example, you are trying to recover valuable data from a volume that has been through an accident. Or you could be performing file system forensics. Or the volume could be damaged enough to not be in a mountable state&mdash;at least not without repair. In these situations, you can&#8217;t or wouldn&#8217;t want to mount the volume. That aside, in my case, I didn&#8217;t know until <em>after</em> the volume had been modified that I wanted to know what had changed. That is, I didn&#8217;t happen to be conveniently running any monitoring programs and such.</p>
<p>You can always old plain old Unix-style <code>find</code> and walk the entire file system, examining each file and folder. This still needs the volume to be mounted, but it <em>is</em> exhaustive. Of course, if you have a large volume, exhaustively examining each file and folder through a brute-force <code>find</code> or other programs could take &quot;forever.&quot; (In my case, I had over 4 million files on the volume. I also had little patience.)</p>
<p>Fortunately, Mac OS X lets you exploit the fact that the HFS+ volume format uses a central catalog B-Tree for storing hierarchy: the <code>searchfs()</code> system call can be used to &quot;quickly&quot; search HFS+ volumes. (It <em>is</em> much, much quicker than a typical portable user-space file-tree-walk.) In my case, I could use <code>searchfs()</code> to search for files and folders with creation or modification dates that match my criteria. Well, <em>almost</em>. I actually <em>did</em> require the volume to be unmounted. I also felt more inclined to do something general purpose.</p>
<p><a href="http://osxbook.com/software/hfsdebug/" title="HFSDebug"><code>hfsdebug</code></a> is a tool that can walk the catalog tree even on unmounted volumes. I decided to add filtering capability to <code>hfsdebug</code>. &quot;Filtering&quot; means that <code>hfsdebug</code> can walk the HFS+ catalog B-Tree, examining each file and folder, and produce output based on some matching criteria. The <a href="http://osxbook.com/software/hfsdebug/#DOWNLOAD" title="Download HFSDebug">new version</a> of <code>hfsdebug</code> contains two built-in filters: <em>mtime</em> and <em>crtime</em>. You can use these filters to look for files and folders that have been modified or created, respectively, in the past <em>N</em> seconds. The number of seconds is passed as an argument to these filters. For example, to look for file system objects modified within the past 60 seconds, you would run <code>hfsdebug</code> as follows:</p>
<p><code></p>
<pre style="font-size: 85%;">
$ <span style="color: #0000a0;">sudo hfsdebug --filter=builtin:crtime --filter_args=60</span>
1216795688 [Tue Jul 22 23:48:08 2008]: Macintosh HD:/private/var/log/asl.db
1216795688 [Tue Jul 22 23:48:08 2008]: Macintosh HD:/private/var/log/system.log
...
</pre>
<p></code></p>
<p>Better still, you can write your own filters that <code>hfsdebug</code> can use. A filter is implemented as a dynamic library that implements up to 3 functions: one of them mandatory (<code>hfsdebug_filter_callback()</code>) and two of them optional (<code>hfsdebug_filter_init()</code> and <code>hfsdebug_filter_fini()</code>.) To use your own filter, you would run <code>hfsdebug</code> the same way as in the case of built-in filters:</p>
<p><code></p>
<pre style="font-size: 85%;">
$ <span style="color: #0000a0;">sudo hfsdebug --filter=/path/to/myfilter.dylib --filter_args=string</span>
...
</pre>
<p></code></p>
<p>If your filter implements the <code>hfsdebug_filter_init()</code> function, <code>hfsdebug</code> would call it with the filter argument string, if any, as the argument. You could parse the argument string in the init function and initialize your filter&#8217;s state, if necessary.</p>
<pre style="font-size:85%;"><tt><font color="#009900">int</font>
<b><font color="#000000">hfsdebug_filter_init</font></b><font color="#990000">(</font><b><font color="#0000FF">const</font></b> <font color="#009900">char</font> <font color="#990000">*</font>filter_args<font color="#990000">);</font></tt></pre>
<p>If you return a non-zero value from the init function, <code>hfsdebug</code> will terminate. If your filter doesn&#8217;t have any arguments, you could choose not to implement the init function.</p>
<p>After you return 0 from the init function, <code>hfsdebug</code> will invoke your filter&#8217;s callback function once for each file and folder record in the HFS+ catalog.</p>
<pre style="font-size:85%;"><tt>
<b><font color="#0000FF">typedef</font></b> <font color="#009900">char</font><font color="#990000">*(*</font>hfsdebug_filter_path_retriever_t<font color="#990000">)(</font><font color="#009900">void</font><font color="#990000">);</font>

<font color="#009900">int</font>
<b><font color="#000000">hfsdebug_filter_callback</font></b><font color="#990000">(</font>
    <font color="#009900">void</font> <font color="#990000">*</font>info<font color="#990000">,</font> hfsdebug_filter_path_retriever_t pathRetriever<font color="#990000">);</font>
</tt></pre>
<p>The <code>info</code> argument is a pointer to either an <code>HFSPlusCatalogFile</code> structure or an <code>HFSPlusCatalogFolder</code> structure. (See the xnu kernel source for details of these structures.) You can determine which structure it is based on the first <code>int16_t</code> within the structure: it&#8217;s either <code>kHFSPlusFileRecord</code> or <code>kHFSPlusFolderRecord</code>. Given these structures, your filter can examine various attributes of the file system object.</p>
<p>Note that <code>hfsdebug</code> does <strong>not</strong> pass you the path to the file system object in question. This is because path computation is expensive. Instead, <code>hfsdebug</code> passes you a pointer to a <em>path retriever function</em>. You can invoke this function to make <code>hfsdebug</code> compute the path on demand and return a C string pointer. This pointer is valid for the given file system object only until your callback returns. You should only call the path retriever function if you truly need the path&mdash;doing so for each file system object would be quite time consuming. Note that <code>hfsdebug</code> filters are <em>not</em> multithreaded.</p>
<p>Again, you must return 0 from the callback for <code>hfsdebug</code> to keep calling you as long as there are more file system objects. If you return a non-zero value, <code>hfsdebug</code> will terminate.</p>
<p>Finally, once <code>hfsdebug</code> is done with all file system objects, it will call your filter&#8217;s fini function if one is implemented.</p>
<pre style="font-size:85%;"><tt>
<font color="#009900">void</font>
<b><font color="#000000">hfsdebug_filter_fini</font></b><font color="#990000">(</font><font color="#009900">void</font><font color="#990000">);</font>
</tt></pre>
<p>The following is a complete example of an <code>hfsdebug</code> filter. It does the same things as the built-in <em>mtime</em> filter, that is, it looks for files and folders that were modified within the last <em>N</em> seconds.</p>
<pre style="font-size: 85%;"><tt><i><font color="#9A1900">/*</font></i>
<i><font color="#9A1900"> * myfilter.c</font></i>
<i><font color="#9A1900"> *</font></i>
<i><font color="#9A1900"> * HFSDebug Filter for "mtime"</font></i>
<i><font color="#9A1900"> *</font></i>
<i><font color="#9A1900"> * Look for file system objects that have been modified</font></i>
<i><font color="#9A1900"> * within the past N seconds.</font></i>
<i><font color="#9A1900"> *</font></i>
<i><font color="#9A1900"> * gcc -arch ppc -dynamiclib -I/path/to/xnu/bsd/ -Wall -o myfilter.dylib myfilter.c</font></i>
<i><font color="#9A1900"> */</font></i>

<b><font color="#000080">#include</font></b> <font color="#FF0000">&lt;stdio.h&gt;</font>
<b><font color="#000080">#include</font></b> <font color="#FF0000">&lt;stdlib.h&gt;</font>
<b><font color="#000080">#include</font></b> <font color="#FF0000">&lt;stdint.h&gt;</font>
<b><font color="#000080">#include</font></b> <font color="#FF0000">&lt;errno.h&gt;</font>
<b><font color="#000080">#include</font></b> <font color="#FF0000">&lt;time.h&gt;</font>

<b><font color="#000080">#include</font></b> <font color="#FF0000">&lt;hfs/hfs_format.h&gt;</font>

<b><font color="#000080">#define</font></b> MAC_GMT_FACTOR 2082844800UL

<b><font color="#0000FF">typedef</font></b> <font color="#009900">char</font><font color="#990000">*(*</font>hfsdebug_filter_path_retriever_t<font color="#990000">)(</font><font color="#009900">void</font><font color="#990000">);</font>

<b><font color="#0000FF">static</font></b> uint32_t mtime_seconds <font color="#990000">=</font> <font color="#993399">0</font><font color="#990000">;</font>

<font color="#009900">int</font>
<b><font color="#000000">hfsdebug_filter_init</font></b><font color="#990000">(</font><b><font color="#0000FF">const</font></b> <font color="#009900">char</font> <font color="#990000">*</font>filter_args<font color="#990000">)</font>
<font color="#FF0000">{</font>
    mtime_seconds <font color="#990000">=</font> <b><font color="#000000">strtoul</font></b><font color="#990000">(</font>filter_args<font color="#990000">,</font> NULL<font color="#990000">,</font> <font color="#993399">10</font><font color="#990000">);</font>
    <b><font color="#0000FF">if</font></b> <font color="#990000">((</font>errno <font color="#990000">==</font> ERANGE<font color="#990000">)</font> <font color="#990000">||</font> <font color="#990000">(</font>errno <font color="#990000">==</font> EINVAL<font color="#990000">))</font> <font color="#FF0000">{</font>
        <b><font color="#000000">fprintf</font></b><font color="#990000">(</font>stderr<font color="#990000">,</font>
                <font color="#FF0000">"invalid argument (%s) to mtime filter</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">,</font> filter_args<font color="#990000">);</font>
        <b><font color="#0000FF">return</font></b> errno<font color="#990000">;</font>
    <font color="#FF0000">}</font>

    time_t now <font color="#990000">=</font> <b><font color="#000000">time</font></b><font color="#990000">(</font>NULL<font color="#990000">);</font>

    mtime_seconds <font color="#990000">=</font> now <font color="#990000">-</font> mtime_seconds <font color="#990000">+</font> MAC_GMT_FACTOR<font color="#990000">;</font>

    <b><font color="#0000FF">return</font></b> <font color="#993399">0</font><font color="#990000">;</font>
<font color="#FF0000">}</font>

<font color="#009900">int</font>
<b><font color="#000000">hfsdebug_filter_callback</font></b><font color="#990000">(</font><font color="#009900">void</font> <font color="#990000">*</font>info<font color="#990000">,</font>
                         hfsdebug_filter_path_retriever_t pathRetriever<font color="#990000">)</font>
<font color="#FF0000">{</font>
    int16_t recordType <font color="#990000">=</font> <font color="#990000">*(</font>int16_t<font color="#990000">*)</font>info<font color="#990000">;</font>
    uint32_t modDate<font color="#990000">;</font>

    <b><font color="#0000FF">if</font></b> <font color="#990000">(</font>recordType <font color="#990000">==</font> kHFSPlusFileRecord<font color="#990000">)</font> <font color="#FF0000">{</font>
        HFSPlusCatalogFile <font color="#990000">*</font>file <font color="#990000">=</font> <font color="#990000">(</font>HFSPlusCatalogFile<font color="#990000">*)</font>info<font color="#990000">;</font>
        modDate <font color="#990000">=</font> file<font color="#990000">-&gt;</font>contentModDate<font color="#990000">;</font>
    <font color="#FF0000">}</font> <b><font color="#0000FF">else</font></b> <b><font color="#0000FF">if</font></b> <font color="#990000">(</font>recordType <font color="#990000">==</font> kHFSPlusFolderRecord<font color="#990000">)</font> <font color="#FF0000">{</font>
        HFSPlusCatalogFolder <font color="#990000">*</font>folder <font color="#990000">=</font> <font color="#990000">(</font>HFSPlusCatalogFolder<font color="#990000">*)</font>info<font color="#990000">;</font>
        modDate <font color="#990000">=</font> folder<font color="#990000">-&gt;</font>contentModDate<font color="#990000">;</font>
    <font color="#FF0000">}</font> <b><font color="#0000FF">else</font></b> <font color="#FF0000">{</font>
        <i><font color="#9A1900">/* ignore */</font></i>
        <b><font color="#0000FF">return</font></b> <font color="#993399">0</font><font color="#990000">;</font>
    <font color="#FF0000">}</font>

    <b><font color="#0000FF">if</font></b> <font color="#990000">(</font>modDate <font color="#990000">&gt;</font> mtime_seconds<font color="#990000">)</font> <font color="#FF0000">{</font>
        modDate <font color="#990000">-=</font> MAC_GMT_FACTOR<font color="#990000">;</font>
        <font color="#009900">char</font> <font color="#990000">*</font>tmpTime <font color="#990000">=</font> <b><font color="#000000">asctime</font></b><font color="#990000">(</font><b><font color="#000000">localtime</font></b><font color="#990000">((</font>time_t<font color="#990000">*)&amp;</font>modDate<font color="#990000">));</font>
        <font color="#990000">*(</font>tmpTime <font color="#990000">+</font> <font color="#993399">24</font><font color="#990000">)</font> <font color="#990000">=</font> <font color="#993399">0</font><font color="#990000">;</font>
        <b><font color="#000000">fprintf</font></b><font color="#990000">(</font>stdout<font color="#990000">,</font>
                <font color="#FF0000">"%u [%s]: %s</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">,</font> modDate<font color="#990000">,</font> tmpTime<font color="#990000">,</font> <b><font color="#000000">pathRetriever</font></b><font color="#990000">());</font>
    <font color="#FF0000">}</font>

    <b><font color="#0000FF">return</font></b> <font color="#993399">0</font><font color="#990000">;</font>
<font color="#FF0000">}</font>

<font color="#009900">void</font>
<b><font color="#000000">hfsdebug_filter_fini</font></b><font color="#990000">(</font><font color="#009900">void</font><font color="#990000">)</font>
<font color="#FF0000">{</font>
    <b><font color="#0000FF">return</font></b><font color="#990000">;</font>
<font color="#FF0000">}</font>
</tt></pre>
<p>
<span style="text-align: right;"><br />
<a href="http://osxbook.com/software/hfsdebug/#DOWNLOAD">Download HFSDebug 3.20</a></span></p>
]]></content:encoded>
			<wfw:commentRss>http://osxbook.com/blog/2008/07/23/extending-hfsdebug/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HFSDebug Bugfix Release 3.10</title>
		<link>http://osxbook.com/blog/2008/02/26/hfsdebug-bugfix-release-310/</link>
		<comments>http://osxbook.com/blog/2008/02/26/hfsdebug-bugfix-release-310/#comments</comments>
		<pubDate>Wed, 27 Feb 2008 03:20:36 +0000</pubDate>
		<dc:creator>amit</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[The Book]]></category>

		<guid isPermaLink="false">http://www.osxbook.com/blog/2008/02/26/hfsdebug-bugfix-release-310/</guid>
		<description><![CDATA[I discovered a bug in hfsdebug. It causes hfsdebug to crash while printing Access Control Entry (ACE) details for certain files or folders. For example, consider the standard ~/Library/Preferences/ folder on Leopard. $ ls -lde ~/Library/Preferences drwx------@ 167 singh staff ... /Users/singh/Library/Preferences 0: group:everyone deny delete This folder has an ACE for the group everyone. [...]]]></description>
			<content:encoded><![CDATA[<p>I discovered a bug in <a href="/software/hfsdebug/" title="HFSDebug: A Debugger for HFS Plus Volumes">hfsdebug</a>. It causes hfsdebug to crash while printing Access Control Entry (ACE) details for certain files or folders. For example, consider the standard <code>~/Library/Preferences/</code> folder on Leopard.</p>
<p><code style="font-size:80%;"></p>
<pre>
$ <strong>ls -lde ~/Library/Preferences</strong>
drwx------@ 167 singh  staff ... /Users/singh/Library/Preferences
 0: group:everyone deny delete
</pre>
<p></code></p>
<p>This folder has an ACE for the group <code>everyone</code>. In particular, the ACE applies to no specific <em>user</em> (or you could say it applies to the wildcard user). HFSDebug was not dealing with this situation well. See what happens.</p>
<p><code style="font-size: 80%;"></p>
<pre>
$ <strong>sudo hfsdebug ~/Library/Preferences/</strong>
  &lt;Catalog B-Tree node = 15028 (sector 0x49080)&gt;
  path                 = Macintosh HD:/Users/singh/Library/Preferences
# Catalog Folder Record
...
        # ACL Entry
        ace_applicable     = ab cd ef ab cd ef ab cd ef ab cd ef 0 0 0 c
zsh: bus error  sudo ./hfsdebug ~/Library/Preferences
</pre>
<p></code></p>
<p>I&#8217;ve released a bugfix version of HFSDebug to take care of this. The correct behavior should be as follows.</p>
<p><code style="font-size: 80%;"></p>
<pre>
$ <strong>sudo hfsdebug ~/Library/Preferences/</strong>
  &lt;Catalog B-Tree node = 15028 (sector 0x49080)&gt;
  path                 = Macintosh HD:/Users/singh/Library/Preferences
# Catalog Folder Record
...
        # ACL Entry
        ace_applicable     = ab cd ef ab cd ef ab cd ef ab cd ef 0 0 0 c
          user             = *
          group            = everyone
          gid              = 12
        ace_flags          = 00000000000000000000000000000010 (0x000002)
                             . KAUTH_ACE_DENY
        ace_rights         = 00000000000000000000000000010000 (0x000010)
                             . KAUTH_VNODE_DELETE
</pre>
<p></code></p>
<p><a href="http://osxbook.com/software/hfsdebug/#DOWNLOAD" title="Download HFSDebug">Download HFSDebug 3.10</href>
]]></content:encoded>
			<wfw:commentRss>http://osxbook.com/blog/2008/02/26/hfsdebug-bugfix-release-310/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GrabFS: The Screenshot File System</title>
		<link>http://osxbook.com/blog/2008/01/02/grabfs-the-screenshot-file-system/</link>
		<comments>http://osxbook.com/blog/2008/01/02/grabfs-the-screenshot-file-system/#comments</comments>
		<pubDate>Wed, 02 Jan 2008 21:47:31 +0000</pubDate>
		<dc:creator>amit</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[MacFUSE]]></category>
		<category><![CDATA[The Book]]></category>

		<guid isPermaLink="false">http://www.osxbook.com/blog/2008/01/02/grabfs-the-screenshot-file-system/</guid>
		<description><![CDATA[A while ago, I wrote about procfs for Mac OS X, a MacFUSE-based file system. Subsequently, I added more cool features to my procfs implementation. Recently, I had reason to demonstrate procfs again and realized that I needed still more cool features. That need led to GrabFS. In a pinch, GrabFS is a file system [...]]]></description>
			<content:encoded><![CDATA[<p>
<a href="/book/bonus/chapter11/grabfs/" title="GrabFS: The Screenshot File System" style="border: none;"><img src="/book/bonus/chapter11/grabfs/images/volumeicon.png" style="float: left; margin-right: 1em; margin-bottom: 1em;"/></a><br />
A while ago, I wrote about <a href="http://osxbook.com/book/bonus/chapter11/procfs/" title="A MacFUSE-Based Process File System for Mac OS X">procfs for Mac OS X</a>, a <a href="http://code.google.com/p/macfuse/" title="MacFUSE Project Page">MacFUSE</a>-based file system. Subsequently, I added more <a href="http://osxbook.com/book/bonus/chapter11/procfs-cool/" title="Making procfs Cooler">cool features</a> to my <a href="http://macfuse.googlecode.com/svn/trunk/filesystems/procfs/" title="MacFUSE procfs Source">procfs implementation</a>. Recently, I had reason to demonstrate procfs again and realized that I needed still more cool features. That need led to <em>GrabFS</em>.
</p>
<p>
In a pinch, GrabFS is a file system that shows you a live view of the window contents of currently running applications. In a GrabFS volume, folders represent running applications and image files represent instant screenshots (&#8220;grabs&#8221;) of the applicationsâ€™ windows. You simply copy a file or just open it in place, and you have a screenshot. Open it again, and you have a new screenshot!
</p>
<p>
<a href="http://osxbook.com/book/bonus/chapter11/grabfs/" title="GrabFS: The Screenshot File System">Go here</a> to read more about GrabFS and to <a href="/book/bonus/chapter11/grabfs/#DOWNLOAD" title="Download GrabFS">download it</a>. GrabFS requires Mac OS X &quot;Leopard&quot; and MacFUSE.</p>
]]></content:encoded>
			<wfw:commentRss>http://osxbook.com/blog/2008/01/02/grabfs-the-screenshot-file-system/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New Version of HFSDebug</title>
		<link>http://osxbook.com/blog/2007/12/30/new-version-of-hfsdebug-3/</link>
		<comments>http://osxbook.com/blog/2007/12/30/new-version-of-hfsdebug-3/#comments</comments>
		<pubDate>Mon, 31 Dec 2007 06:01:37 +0000</pubDate>
		<dc:creator>amit</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[The Book]]></category>

		<guid isPermaLink="false">http://www.osxbook.com/blog/2007/12/30/new-version-of-hfsdebug-3/</guid>
		<description><![CDATA[I found some time today to make a certain feature of HFSDebug work on Leopard. The new version is available for download here. The new version should run on both Leopard and Tiger, but there are no visible changes whatsoever for Tiger users. If you use HFSDebug, you might have realized that the -m option [...]]]></description>
			<content:encoded><![CDATA[<p>I found some time today to make a certain feature of <a href="http://osxbook.com/software/hfsdebug/" title="HFSDebug">HFSDebug</a> work on Leopard. The new version is available for download <a href="http://osxbook.com/software/hfsdebug/#DOWNLOAD" title="Download HFSDebug">here</a>. The new version should run on both Leopard and Tiger, but there are no visible changes whatsoever for Tiger users.</p>
<p>If you use HFSDebug, you might have realized that the <code>-m</code> option doesn&#8217;t work on Leopard any more. This option is used to retrieve and display the in-kernel mount data for a currently mounted HFS+ volume. This is what you would see if you ran the now deprecated version 2.56 of HFSDebug on Leopard:</p>
<p><code><br />
$ <strong>sw_vers</strong><br />
ProductName:	Mac OS X<br />
ProductVersion:	10.5.1<br />
BuildVersion:	9B18<br />
$ <strong>sudo hfsdebug</strong><br />
populateHFSPlusMount(222): failed to retrieve symbol information.<br />
hfsdebug: failed to locate mount data (perhaps the volume is not mounted)<br />
$<br />
</code></p>
<p>The updated version should work correctly as follows. As you can see, if you <em>did</em> care about this information, this is a rather useful feature that needed fixing for Leopard.</p>
<p><code style="font-size:90%">
<pre>
$ <strong>sudo ./hfsdebug -m</strong>
  Volume name                             = Macintosh HD (volfs_id=234881026)
  block device number                     = { major=14, minor=2 }
  HFS+ flags                              = 000...0000000000000010001100
                                            + HFS_WRITEABLE_MEDIA
                                            + HFS_CLEANED_ORPHANS
                                            + HFS_METADATA_ZONE
  default owner                           = { uid=99, gid=99 }
  directory protection bits mask          = 755
  file protection bits mask               = 755
# Key Data Structures
  struct mount *                          = 0x41ebb90
  block device vnode                      = 0x4333f40
  Extents file vnode                      = 0x4333eb0
  Catalog file vnode                      = 0x4333e20
  Allocation file vnode                   = 0x4333d90
  Attributes file vnode                   = 0x4333d00
# Statistics
  physical block size                     = 512
  physical block count                    = 0x12975e60
  alternate volume header location        = 0x12975e5e
  size of a buffer cache buffer           = 4096
  number of files in file system          = 1047391
  number of directories in file system    = 156694
  free allocation blocks                  = 0x1967df5
  start block for next allocation search  = 0xdfd404
  next unused catalog node ID             = 2011304
  file system write count                 = 84130726
  free block reserve                      = 64000
  blocks on loan for delayed allocations  = 0
  encodings in use                        = 00...010000000000000000001001011
# Notification Variables
  notification conditions bits            = 0
  freespace warning limit                 = 64000
  freespace desired level                 = 96000
# Times
  last mounted time                       = Sun Dec 30 21:36:21 2007
  last mounted modification time          = Sun Dec 30 21:35:51 2007
  last modification time                  = Sun Dec 30 22:08:31 2007
  cache of largest known free extents     =
# Journal
  journal for this volume                 = 0x4338f00
  vnode for journal device                = 0x4333f40
  start block of journal                  = 0x4a8
  journal size                            = 16777216
  journal file ID                         = 16
  journal info block file ID              = 17
# Hot File Clustering
  clustering stage                        = HFC_RECORDING
  recording period start time             = Thu Dec 20 07:41:40 2007
  recording period stop time              = Wed Jan  2 13:17:52 2008
  opaque recording data                   = 0x24189004
  maximum files to track                  = 1000
  vnode of Hot Files B-Tree               = 0x0
# Metadata Zone
  metadata zone start block               = 0x1
  metadata zone end block                 = 0x67fff
  hotfile start block                     = 0x45be2
  hotfile end block                       = 0x67fff
  hotfile free blocks                     = 0x20491
  hotfile maximum blocks                  = 0x2241e
  overflow maximum blocks                 = 0x800
  catalog maximum blocks                  = 0x43f3b
# Other
  maximum inline attribute size           = 3802
</pre>
<p></code></p>
]]></content:encoded>
			<wfw:commentRss>http://osxbook.com/blog/2007/12/30/new-version-of-hfsdebug-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making procfs Cooler</title>
		<link>http://osxbook.com/blog/2007/06/05/making-procfs-cooler/</link>
		<comments>http://osxbook.com/blog/2007/06/05/making-procfs-cooler/#comments</comments>
		<pubDate>Wed, 06 Jun 2007 07:05:13 +0000</pubDate>
		<dc:creator>amit</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[MacFUSE]]></category>
		<category><![CDATA[Operating Systems]]></category>
		<category><![CDATA[The Book]]></category>

		<guid isPermaLink="false">http://www.osxbook.com/blog/2007/06/05/making-procfs-cooler/</guid>
		<description><![CDATA[A few weeks ago, I released as open source a MacFUSE-based process file system for Mac OS X. I recently added several new features to this procfs implementation. Some of these features are &#34;cool&#34; in that they put a new twist on certain types of visual information. For example, there&#8217;s a folder /proc/system/hardware/displays/ that contains [...]]]></description>
			<content:encoded><![CDATA[<p>A few weeks ago, I released as open source a <a href="http://osxbook.com/book/bonus/chapter11/procfs" title="A MacFUSE-Based Process File System for Mac OS X">MacFUSE-based process file system for Mac OS X</a>.</p>
<p>I recently added several new features to this procfs implementation. Some of these features are &quot;cool&quot; in that they put a new twist on certain types of visual information.</p>
<p>For example, there&#8217;s a folder <code>/proc/system/hardware/displays/</code> that contains a subfolder each for connected displays. Subfolder <code>0</code> represents the first display, <code>1</code> is the second display (if any), and so on. Within each such subfolder, there&#8217;s a file called <code>info</code> that contains information about that particular display: its resolution, bits-per-pixel, bytes-per-row, whether the display is built-in, whether it supports OpenGL acceleration, and so on. There&#8217;s another file called <code>screenshot.tiff</code> that contains a TIFF rendition of what&#8217;s on that display at that moment&mdash;an <em>always-live screenshot</em>, if you will. You copy this file and you get a screenshot. Copy it again, and you get a new screenshot. You can just open it in place too.</p>
<p>Along similar lines, there&#8217;s another folder <code>/proc/system/hardware/camera/</code> and a file <code>screenshot.tiff</code> within it. When you open this file, procfs activates the camera momentarily, takes a picture, deactivates the camera, and makes the picture available as a TIFF file. You can copy the file and you get an image of what the camera&#8217;s seeing at that moment. Copy it again and you get another &quot;live&quot; image.</p>
<p>Besides these, the updated procfs has other (not-so-visual) interesting features.</p>
<p>More details, source code, and a precompiled binary available here:</p>
<p><a href="http://osxbook.com/book/bonus/chapter11/procfs-cool/" title="Making procfs Cooler">Making procfs Cooler</a></p>
]]></content:encoded>
			<wfw:commentRss>http://osxbook.com/blog/2007/06/05/making-procfs-cooler/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Book vs Machine</title>
		<link>http://osxbook.com/blog/2007/05/29/book-vs-machine/</link>
		<comments>http://osxbook.com/blog/2007/05/29/book-vs-machine/#comments</comments>
		<pubDate>Wed, 30 May 2007 07:45:34 +0000</pubDate>
		<dc:creator>amit</dc:creator>
				<category><![CDATA[The Book]]></category>

		<guid isPermaLink="false">http://www.osxbook.com/blog/2007/05/29/book-vs-machine/</guid>
		<description><![CDATA[On the right, we have a PowerMac G5. On the left, we have academic papers and author-prepared notes that were used in the creation of &#8220;Mac OS X Internals&#8220;. (Recycled paper used when possible. In particular, the book is printed on recycled paper.)]]></description>
			<content:encoded><![CDATA[<p><img src="/images/book_vs_machine.jpg" width="512" height="817" style="border: none;" /></p>
<p>
On the right, we have a PowerMac G5.
</p>
<p>
On the left, we have academic papers and author-prepared notes that were used in the creation of &#8220;<a href="/" title="Mac OS X Internals: The Book">Mac OS X Internals</a>&#8220;.
</p>
<p>
<em>(Recycled paper used when possible. In particular, the book is printed on recycled paper.)</em></p>
]]></content:encoded>
			<wfw:commentRss>http://osxbook.com/blog/2007/05/29/book-vs-machine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Interview Errata</title>
		<link>http://osxbook.com/blog/2007/05/09/interview-errata/</link>
		<comments>http://osxbook.com/blog/2007/05/09/interview-errata/#comments</comments>
		<pubDate>Wed, 09 May 2007 16:54:56 +0000</pubDate>
		<dc:creator>amit</dc:creator>
				<category><![CDATA[The Book]]></category>

		<guid isPermaLink="false">http://www.osxbook.com/blog/2007/05/09/interview-errata/</guid>
		<description><![CDATA[When I replayed this interview of mine, I found a syntax error in one of the things I said. When the interviewer talks about X Window programming on Mac OS X, I said that the communication between &#8220;your program and the X server&#8221; is specific to Mac OS X. I meant to say the communication [...]]]></description>
			<content:encoded><![CDATA[<p>When I replayed this <a href="http://www.itconversations.com/shows/detail1804.html">interview</a> of mine, I found a syntax error in one of the things I said.</p>
<p>When the interviewer talks about X Window programming on Mac OS X, I said that the communication between <em>&#8220;your program and the X server&#8221;</em> is specific to Mac OS X. I meant to say the communication beween <em>&#8220;the X server and Mac OS X&#8221;</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://osxbook.com/blog/2007/05/09/interview-errata/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>File Systems Are Cool</title>
		<link>http://osxbook.com/blog/2007/01/02/file-systems-are-cool/</link>
		<comments>http://osxbook.com/blog/2007/01/02/file-systems-are-cool/#comments</comments>
		<pubDate>Wed, 03 Jan 2007 06:49:31 +0000</pubDate>
		<dc:creator>amit</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Operating Systems]]></category>
		<category><![CDATA[The Book]]></category>

		<guid isPermaLink="false">http://www.osxbook.com/blog/2007/01/02/file-systems-are-cool/</guid>
		<description><![CDATA[Let us try to make them a little cooler on Mac OS X.]]></description>
			<content:encoded><![CDATA[<p><img src="/images/cool.jpg" width="512" height="384" style="border: none;" /></p>
<p>
<a href="http://www.macworldexpo.com/live/20/events/20SFO07A/conference/tracksessions/Mac%20OS%20X%20Management%20and%20Administration/QMONYA04SWWQ">Let us try to make them a little cooler on Mac OS X</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://osxbook.com/blog/2007/01/02/file-systems-are-cool/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Upcoming Conferences</title>
		<link>http://osxbook.com/blog/2006/11/28/upcoming-conferences/</link>
		<comments>http://osxbook.com/blog/2006/11/28/upcoming-conferences/#comments</comments>
		<pubDate>Tue, 28 Nov 2006 10:13:50 +0000</pubDate>
		<dc:creator>amit</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Operating Systems]]></category>
		<category><![CDATA[The Book]]></category>

		<guid isPermaLink="false">http://www.osxbook.com/blog/2006/11/28/upcoming-conferences/</guid>
		<description><![CDATA[I will be speaking at the following venues in the near future: Chaos Communication Congress, Berlin, Germany (December 29, 2006) Macworld Conference &#038; Expo, San Francisco, USA (January 11, 2007)]]></description>
			<content:encoded><![CDATA[<p>I will be speaking at the following venues in the near future:</p>
<ul style="list-style: square;">
<li><a href="http://events.ccc.de/congress/2006/Home">Chaos Communication Congress</a>, Berlin, Germany (December 29, 2006)</li>
<li><a href="http://www.macworldexpo.com/live/20/events/20SFO07A/conference/tracksessions/Mac%20OS%20X%20Management%20and%20Administration/QMONYA04SWWQ">Macworld Conference &#038; Expo</a>, San Francisco, USA (January 11, 2007)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://osxbook.com/blog/2006/11/28/upcoming-conferences/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Understanding Apple&#039;s Binary Protection in Mac OS X</title>
		<link>http://osxbook.com/blog/2006/10/22/understanding-apples-binary-protection-in-mac-os-x/</link>
		<comments>http://osxbook.com/blog/2006/10/22/understanding-apples-binary-protection-in-mac-os-x/#comments</comments>
		<pubDate>Mon, 23 Oct 2006 02:10:02 +0000</pubDate>
		<dc:creator>amit</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[The Book]]></category>

		<guid isPermaLink="false">http://www.osxbook.com/blog/2006/10/22/understanding-apples-binary-protection-in-mac-os-x/</guid>
		<description><![CDATA[A discussion on how Apple&#8217;s binary protection works in the x86 version of Mac OS X: Understanding Apple&#8217;s Binary Protection in Mac OS X]]></description>
			<content:encoded><![CDATA[<p>A discussion on how Apple&#8217;s binary protection works in the x86 version of Mac OS X:</p>
<p><a href="/book/bonus/chapter7/binaryprotection/" title="Understanding Apple's Binary Protection in Mac OS X">Understanding Apple&#8217;s Binary Protection in Mac OS X</a></p>
]]></content:encoded>
			<wfw:commentRss>http://osxbook.com/blog/2006/10/22/understanding-apples-binary-protection-in-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

