<?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>Enterprise LAMP &#187; Planet</title>
	<atom:link href="http://enterpriselamp.org/news/category/planet/feed/" rel="self" type="application/rss+xml" />
	<link>http://enterpriselamp.org</link>
	<description></description>
	<lastBuildDate>Mon, 06 Sep 2010 02:26:06 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Should Module::Install move to explicit plugin declaration?</title>
		<link>http://feedproxy.google.com/~r/PlanetPerl/~3/oHJVzg-J8N4/40523</link>
		<comments>http://feedproxy.google.com/~r/PlanetPerl/~3/oHJVzg-J8N4/40523#comments</comments>
		<pubDate>Mon, 06 Sep 2010 02:26:06 +0000</pubDate>
		<dc:creator>Alias</dc:creator>
				<category><![CDATA[Planet]]></category>

		<guid isPermaLink="false">http://use.perl.org/~Alias/journal/40523?from=rss</guid>
		<description><![CDATA[Module::Install has been through a long period of gradual stability over the last year, without any really dramatic improvements to the grammar or APIs.With the more urgent "it doesn't work with blah" stuff mostly solved now, one of the big remaining i...]]></description>
			<content:encoded><![CDATA[<p>Module::Install has been through a long period of gradual stability over the last year, without any really dramatic improvements to the grammar or APIs.</p><p>With the more urgent "it doesn't work with blah" stuff mostly solved now, one of the big remaining issues is around error clarity and excessive magic.</p><p>For example, some random author that is trying to checkout a Catalyst project needs:</p><p>1. To have Module::Install installed.<br />2. To have Module::Install::Catalyst installed.</p><p>In the case of the former, you get the semi-cryptic but at least standard "Can't find inc/Module/Install.pm in @INC" message, so the error is resolvable.</p><p>But in the latter case, you're likely to get something like "Unknown command 'catalyst_ignore'", with no real obvious resolution mechanism.</p><p>I think this idea of automatic plugin discovery is starting to hit it's limits in terms of clarity.</p><p>And so I'd like to do something counter to my natural instincts here, and make M:I more verbose.</p><p>I'm thinking of something like the following for explicitly declaring the use of a non-core Module::Install extension.</p><blockquote><div><p> <tt>use inc::Module::Install qw{ Catalyst XSUtil };</tt></p></div> </blockquote><p>This would both allow M:I to error with a much more meaningful error when you don't have a plugin, and also prevent the loading of unused plugins which should prevent accidental plugin collisions (some of which I've seen occurring in the CPAN Testers machines).</p><p>Thoughts?</p><img src="http://feeds.feedburner.com/~r/PlanetPerl/~4/oHJVzg-J8N4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://feedproxy.google.com/~r/PlanetPerl/~3/oHJVzg-J8N4/40523/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hector Garcia: FlacComp (FLAC Compilation)</title>
		<link>http://nomadblue.com/blog/python/flaccomp/</link>
		<comments>http://nomadblue.com/blog/python/flaccomp/#comments</comments>
		<pubDate>Sun, 05 Sep 2010 23:46:07 +0000</pubDate>
		<dc:creator>Planet Python</dc:creator>
				<category><![CDATA[Planet]]></category>

		<guid isPermaLink="false">http://nomadblue.com/blog/python/flaccomp/</guid>
		<description><![CDATA[<p>I recently released a little application I wrote for personal use. I am very scrupulous mantaining my music collections. I fancy having them in lossless formats, specially <a class="reference external" href="http://flac.sourceforge.net/">FLAC</a> for storage and <a class="reference external" href="http://en.wikipedia.org/wiki/Apple_Lossless">Apple Lossless</a> for playback in iTunes. To achieve a decent level of tidiness, I wrote some Python code so I can organize the files and associated metadata tags right from the command line.</p>
<p>The app can be found in its project page <a class="reference external" href="http://nomadblue.com/projects/flaccomp/">here</a>.</p>
<p>Please comments, forks, jokes, donations or awards welcome!</p>]]></description>
			<content:encoded><![CDATA[<p>I recently released a little application I wrote for personal use. I am very scrupulous mantaining my music collections. I fancy having them in lossless formats, specially <a class="reference external" href="http://flac.sourceforge.net/">FLAC</a> for storage and <a class="reference external" href="http://en.wikipedia.org/wiki/Apple_Lossless">Apple Lossless</a> for playback in iTunes. To achieve a decent level of tidiness, I wrote some Python code so I can organize the files and associated metadata tags right from the command line.</p>
<p>The app can be found in its project page <a class="reference external" href="http://nomadblue.com/projects/flaccomp/">here</a>.</p>
<p>Please comments, forks, jokes, donations or awards welcome!</p>]]></content:encoded>
			<wfw:commentRss>http://nomadblue.com/blog/python/flaccomp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Chris Leary: A prototypal binding trap</title>
		<link>http://blog.cdleary.com/2010/09/a-prototypal-binding-trap/</link>
		<comments>http://blog.cdleary.com/2010/09/a-prototypal-binding-trap/#comments</comments>
		<pubDate>Sun, 05 Sep 2010 20:29:30 +0000</pubDate>
		<dc:creator>Planet Python</dc:creator>
				<category><![CDATA[Planet]]></category>

		<guid isPermaLink="false">http://blog.cdleary.com/2010/09/a-prototypal-binding-trap/</guid>
		<description><![CDATA[<p>It always pains me to explain these little identifier resolution traps:</p>

<div class="wp_syntax"><div class="code"><pre><span>#!/usr/bin/env python3</span>
&#160;
<span>class</span> Egg:
&#160;
    _next_id = <span>1</span>
&#160;
    <span>def</span> <span>__init__</span><span>&#40;</span><span>self</span><span>&#41;</span>:
        <span>self</span>.<span>id</span> = <span>self</span>._next_id
        <span>self</span>._next_id += <span>1</span>
        <span>assert</span> Egg._next_id <span>is</span> <span>self</span>._next_id
&#160;
&#160;
<span>if</span> __name__ == <span>'__main__'</span>:
    f = Egg<span>&#40;</span><span>&#41;</span></pre></div></div>

<p>Fails the assertion. It&#8217;s decomposing the assignment-update into its constituent <tt><span class="pre">tmp</span> <span class="pre">=</span> <span class="pre">self._next_id</span> <span class="pre">+</span> <span class="pre">1;</span> <span class="pre">self._next_id</span> <span class="pre">=</span> <span class="pre">tmp</span></tt> components, but a programmer could reasonably expect a Lookup/Update hash map ADT operation to occur instead &#8212; get the slot by lookup, mutate the value found, and store back in an atomic sense, clobbering the class member with the updated value &#8212; but that&#8217;s <strong>not</strong> how it works.</p>
<p>This goes with the prototypal territory:</p>

<div class="wp_syntax"><div class="code"><pre><span>function</span> Egg<span>&#40;</span><span>&#41;</span> <span>&#123;</span>
    <span>this</span>.<span>id</span> <span>=</span> <span>this</span>.<span>next_id</span><span>;</span>
    <span>this</span>.<span>next_id</span> <span>+=</span> <span>1</span><span>;</span>
    assertEq<span>&#40;</span><span>this</span>.<span>next_id</span><span>,</span> Egg.<span>prototype</span>.<span>next_id</span><span>&#41;</span><span>;</span>
<span>&#125;</span>
&#160;
Egg.<span>prototype</span>.<span>next_id</span> <span>=</span> <span>1</span><span>;</span>
<span>var</span> e <span>=</span> <span>new</span> Egg<span>&#40;</span><span>&#41;</span><span>;</span> <span>// Error: Assertion failed: got 2, expected 1</span></pre></div></div>

<p>Fortunately, note that this behavior definitely has the semantics you want when you add inheritance to the mix. Is the <tt><span class="pre">self.viscosity</span></tt> that this class implementation is referring to a class member or an instance member in the base class?</p>

<div class="wp_syntax"><div class="code"><pre><span>#!/usr/bin/env python3</span>
&#160;
<span>import</span> sauce
&#160;
<span>class</span> AwesomeSauce<span>&#40;</span>sauce.<span>Sauce</span><span>&#41;</span>:
&#160;
    <span>def</span> <span>__init__</span><span>&#40;</span><span>self</span><span>&#41;</span>:
        <span>super</span><span>&#40;</span><span>&#41;</span>.<span>__init__</span><span>&#40;</span><span>&#41;</span>
        <span>self</span>.<span>viscosity</span> += <span>12</span> <span># Deca-viscoses per milliliter.</span></pre></div></div>

<p>The answer is that you don&#8217;t care &#8212; it&#8217;s being rebound on the <tt><span class="pre">AwesomeSauce</span></tt> instance no matter what.</p>
<p>Moral of the story is to be mindful when using update operations on class members &#8212; if you want to rebind a class member within an instance method, you&#8217;ve got to use the class name instead of <tt>self</tt>.</p>
<img src="http://feeds.feedburner.com/~r/VaporWarning-Python/~4/QfHA2bgNl5I" height="1" width="1" />]]></description>
			<content:encoded><![CDATA[<p>It always pains me to explain these little identifier resolution traps:</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span>#!/usr/bin/env python3</span>
&nbsp;
<span>class</span> Egg:
&nbsp;
    _next_id = <span>1</span>
&nbsp;
    <span>def</span> <span>__init__</span><span>&#40;</span><span>self</span><span>&#41;</span>:
        <span>self</span>.<span>id</span> = <span>self</span>._next_id
        <span>self</span>._next_id += <span>1</span>
        <span>assert</span> Egg._next_id <span>is</span> <span>self</span>._next_id
&nbsp;
&nbsp;
<span>if</span> __name__ == <span>'__main__'</span>:
    f = Egg<span>&#40;</span><span>&#41;</span></pre></div></div>

<p>Fails the assertion. It&#8217;s decomposing the assignment-update into its constituent <tt class="docutils literal"><span class="pre">tmp</span> <span class="pre">=</span> <span class="pre">self._next_id</span> <span class="pre">+</span> <span class="pre">1;</span> <span class="pre">self._next_id</span> <span class="pre">=</span> <span class="pre">tmp</span></tt> components, but a programmer could reasonably expect a Lookup/Update hash map ADT operation to occur instead &#8212; get the slot by lookup, mutate the value found, and store back in an atomic sense, clobbering the class member with the updated value &#8212; but that&#8217;s <strong>not</strong> how it works.</p>
<p>This goes with the prototypal territory:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span>function</span> Egg<span>&#40;</span><span>&#41;</span> <span>&#123;</span>
    <span>this</span>.<span>id</span> <span>=</span> <span>this</span>.<span>next_id</span><span>;</span>
    <span>this</span>.<span>next_id</span> <span>+=</span> <span>1</span><span>;</span>
    assertEq<span>&#40;</span><span>this</span>.<span>next_id</span><span>,</span> Egg.<span>prototype</span>.<span>next_id</span><span>&#41;</span><span>;</span>
<span>&#125;</span>
&nbsp;
Egg.<span>prototype</span>.<span>next_id</span> <span>=</span> <span>1</span><span>;</span>
<span>var</span> e <span>=</span> <span>new</span> Egg<span>&#40;</span><span>&#41;</span><span>;</span> <span>// Error: Assertion failed: got 2, expected 1</span></pre></div></div>

<p>Fortunately, note that this behavior definitely has the semantics you want when you add inheritance to the mix. Is the <tt class="docutils literal"><span class="pre">self.viscosity</span></tt> that this class implementation is referring to a class member or an instance member in the base class?</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span>#!/usr/bin/env python3</span>
&nbsp;
<span>import</span> sauce
&nbsp;
<span>class</span> AwesomeSauce<span>&#40;</span>sauce.<span>Sauce</span><span>&#41;</span>:
&nbsp;
    <span>def</span> <span>__init__</span><span>&#40;</span><span>self</span><span>&#41;</span>:
        <span>super</span><span>&#40;</span><span>&#41;</span>.<span>__init__</span><span>&#40;</span><span>&#41;</span>
        <span>self</span>.<span>viscosity</span> += <span>12</span> <span># Deca-viscoses per milliliter.</span></pre></div></div>

<p>The answer is that you don&#8217;t care &#8212; it&#8217;s being rebound on the <tt class="docutils literal"><span class="pre">AwesomeSauce</span></tt> instance no matter what.</p>
<p>Moral of the story is to be mindful when using update operations on class members &#8212; if you want to rebind a class member within an instance method, you&#8217;ve got to use the class name instead of <tt>self</tt>.</p>
<img src="http://feeds.feedburner.com/~r/VaporWarning-Python/~4/QfHA2bgNl5I" height="1" width="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.cdleary.com/2010/09/a-prototypal-binding-trap/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mario Boikov: IcecastRadio &#8211; Qt widget/Qt Quick example Icecast player</title>
		<link>http://pysnippet.blogspot.com/2010/09/icecastradio-qt-widgetqt-quick-example.html</link>
		<comments>http://pysnippet.blogspot.com/2010/09/icecastradio-qt-widgetqt-quick-example.html#comments</comments>
		<pubDate>Sun, 05 Sep 2010 14:40:07 +0000</pubDate>
		<dc:creator>Planet Python</dc:creator>
				<category><![CDATA[Planet]]></category>

		<guid isPermaLink="false">http://pysnippet.blogspot.com/2010/09/icecastradio-qt-widgetqt-quick-example.html</guid>
		<description><![CDATA[I've been toying with modeling a Qt application which supports both a traditional widget-based view and a quick-based (qml) view.<br /><br /><b>About IcecastRadio</b><br />The intention of this project/application is to demonstrate how important<br />it can be to design a model for your application. If the model is correctly<br />designed, it can be used from both traditional widget based UIs and<br />modern UIs built with Qt Quick without too much effort.<br /><br />The advantage is of course that you can provide both a desktop application which integrates with the native look and feel of the OS and at the same time have a totally different experience UI-wise, for example in an embedded device by only changing the view-layer.<br /><br />IcecastRadio is actually two applications, QtCast and QuickCast. QtCast implements the widget-based view and QuickCast the quick-based view. Both application depends on a third entity, the model. You'll see this division in the source code in form of three projects, qtcast, quickcast and model.<br /><br />The application was successfully compiled against Qt 4.7-beta 1 and 2. <br /><br /><b>Source code</b><br />You'll find the source code at <a href="http://gitorious.org/icecastradio">http://gitorious.org/icecastradio</a>. The player code is released under the MIT license, clone and have fun. Please read the README file found in the repository for more information.<br /><br /><b>Screenshots</b><br />Must have...<br /><br /><div class="separator"></div><div class="separator"></div><div class="separator"><a href="http://1.bp.blogspot.com/_ilsnPCKxGBM/TIOPAjSVJ3I/AAAAAAAAAB8/jdoPpQ_1gsk/s1600/qtcast.png"><img border="0" height="312" src="http://1.bp.blogspot.com/_ilsnPCKxGBM/TIOPAjSVJ3I/AAAAAAAAAB8/jdoPpQ_1gsk/s400/qtcast.png" width="400" /></a></div><div class="separator"></div><div class="separator"></div><div class="separator"></div><div class="separator"><a href="http://3.bp.blogspot.com/_ilsnPCKxGBM/TIOPJ-huZ4I/AAAAAAAAACE/24PHo5GJjhc/s1600/quickcast.png"><img border="0" height="240" src="http://3.bp.blogspot.com/_ilsnPCKxGBM/TIOPJ-huZ4I/AAAAAAAAACE/24PHo5GJjhc/s400/quickcast.png" width="400" /></a><a class="cssButton ubtn-disabled" href="void(0)" id="draftButton"></a></div><br /><br /><b>Remark</b><br />The application lacks a lot of features that could be expected from a radio player, for example there is no way of sorting the list of stations nor any filtering can be applied. The intention was not to create a full blown Icecast player but to demonstrate how to create a model that is usable from both a widget-based application and a quick-based application.<br /><br />Patches are welcome :) <br /><br /><div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/7970464356958190643-7675298162266809189?l=pysnippet.blogspot.com" alt="" /></div>]]></description>
			<content:encoded><![CDATA[I've been toying with modeling a Qt application which supports both a traditional widget-based view and a quick-based (qml) view.<br /><br /><b>About IcecastRadio</b><br />The intention of this project/application is to demonstrate how important<br />it can be to design a model for your application. If the model is correctly<br />designed, it can be used from both traditional widget based UIs and<br />modern UIs built with Qt Quick without too much effort.<br /><br />The advantage is of course that you can provide both a desktop application which integrates with the native look and feel of the OS and at the same time have a totally different experience UI-wise, for example in an embedded device by only changing the view-layer.<br /><br />IcecastRadio is actually two applications, QtCast and QuickCast. QtCast implements the widget-based view and QuickCast the quick-based view. Both application depends on a third entity, the model. You'll see this division in the source code in form of three projects, qtcast, quickcast and model.<br /><br />The application was successfully compiled against Qt 4.7-beta 1 and 2. <br /><br /><b>Source code</b><br />You'll find the source code at <a href="http://gitorious.org/icecastradio">http://gitorious.org/icecastradio</a>. The player code is released under the MIT license, clone and have fun. Please read the README file found in the repository for more information.<br /><br /><b>Screenshots</b><br />Must have...<br /><br /><div class="separator"></div><div class="separator"></div><div class="separator"><a href="http://1.bp.blogspot.com/_ilsnPCKxGBM/TIOPAjSVJ3I/AAAAAAAAAB8/jdoPpQ_1gsk/s1600/qtcast.png"><img border="0" height="312" src="http://1.bp.blogspot.com/_ilsnPCKxGBM/TIOPAjSVJ3I/AAAAAAAAAB8/jdoPpQ_1gsk/s400/qtcast.png" width="400" /></a></div><div class="separator"></div><div class="separator"></div><div class="separator"></div><div class="separator"><a href="http://3.bp.blogspot.com/_ilsnPCKxGBM/TIOPJ-huZ4I/AAAAAAAAACE/24PHo5GJjhc/s1600/quickcast.png"><img border="0" height="240" src="http://3.bp.blogspot.com/_ilsnPCKxGBM/TIOPJ-huZ4I/AAAAAAAAACE/24PHo5GJjhc/s400/quickcast.png" width="400" /></a><a class="cssButton ubtn-disabled" href="javascript:void(0)" id="draftButton"></a></div><br /><br /><b>Remark</b><br />The application lacks a lot of features that could be expected from a radio player, for example there is no way of sorting the list of stations nor any filtering can be applied. The intention was not to create a full blown Icecast player but to demonstrate how to create a model that is usable from both a widget-based application and a quick-based application.<br /><br />Patches are welcome :) <br /><br /><div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/7970464356958190643-7675298162266809189?l=pysnippet.blogspot.com" alt="" /></div>]]></content:encoded>
			<wfw:commentRss>http://pysnippet.blogspot.com/2010/09/icecastradio-qt-widgetqt-quick-example.html/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Doug Hellmann: PyMOTW: re &#8211; Regular Expressions</title>
		<link>http://blog.doughellmann.com/2010/09/pymotw-re-regular-expressions.html</link>
		<comments>http://blog.doughellmann.com/2010/09/pymotw-re-regular-expressions.html#comments</comments>
		<pubDate>Sun, 05 Sep 2010 11:42:05 +0000</pubDate>
		<dc:creator>Planet Python</dc:creator>
				<category><![CDATA[Planet]]></category>

		<guid isPermaLink="false">http://blog.doughellmann.com/2010/09/pymotw-re-regular-expressions.html</guid>
		<description><![CDATA[<p><em>Regular expressions</em> are text matching patterns described with a<br />formal syntax.  The patterns are interpreted as a set of instructions,<br />which are then executed with a string as input to produce a matching<br />subset or modified version of the original.  The term &#8220;regular<br />expressions&#8221; is frequently shortened to as &#8220;regex&#8221; or &#8220;regexp&#8221; in<br />conversation.  Expressions can include literal text matching,<br />repetition, pattern-composition, branching, and other sophisticated<br />rules.  A large number of parsing problems are easier to solve with a<br />regular expression than by creating a special-purpose lexer and<br />parser.</p><p><a href="http://www.doughellmann.com/PyMOTW/re/">Read more...</a></p><br /><div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/5440028356946346379-3556104269326492491?l=blog.doughellmann.com" alt="" /></div>]]></description>
			<content:encoded><![CDATA[<p><em>Regular expressions</em> are text matching patterns described with a<br />formal syntax.  The patterns are interpreted as a set of instructions,<br />which are then executed with a string as input to produce a matching<br />subset or modified version of the original.  The term &#8220;regular<br />expressions&#8221; is frequently shortened to as &#8220;regex&#8221; or &#8220;regexp&#8221; in<br />conversation.  Expressions can include literal text matching,<br />repetition, pattern-composition, branching, and other sophisticated<br />rules.  A large number of parsing problems are easier to solve with a<br />regular expression than by creating a special-purpose lexer and<br />parser.</p><p><a href="http://www.doughellmann.com/PyMOTW/re/">Read more...</a></p><br /><div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/5440028356946346379-3556104269326492491?l=blog.doughellmann.com" alt="" /></div>]]></content:encoded>
			<wfw:commentRss>http://blog.doughellmann.com/2010/09/pymotw-re-regular-expressions.html/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Richard Tew: Roguelike MUD progress</title>
		<link>http://posted-stuff.blogspot.com/2010/09/roguelike-mud-progress.html</link>
		<comments>http://posted-stuff.blogspot.com/2010/09/roguelike-mud-progress.html#comments</comments>
		<pubDate>Sun, 05 Sep 2010 11:37:31 +0000</pubDate>
		<dc:creator>Planet Python</dc:creator>
				<category><![CDATA[Planet]]></category>

		<guid isPermaLink="false">http://posted-stuff.blogspot.com/2010/09/roguelike-mud-progress.html</guid>
		<description><![CDATA[I finally found some more time to work on my roguelike MUD project.  Tonight I managed to get proper multi-player support in, so that concurrently logged in players have their view of the game updated as other game objects change position.  Up to this point the players mostly shared the world representation, and had separate state defining what was in it.<br /><br /><a href="http://3.bp.blogspot.com/_7X0iQg6tJ40/TH0L9kd5yxI/AAAAAAAAAP4/z-izwSUZCOI/s1600/2010-08-31+-+Roguelike+shared+world.jpg"><img src="http://3.bp.blogspot.com/_7X0iQg6tJ40/TH0L9kd5yxI/AAAAAAAAAP4/z-izwSUZCOI/s320/2010-08-31+-+Roguelike+shared+world.jpg" border="0" alt="" /></a><br />While the <a href="http://code.google.com/p/sorrows-mudlib/source/detail?r=174">changes required</a> are more or less fine, some didn't fit well into the existing game framework.  I need to put some thought into cleaning those up.<br /><br />Achievable next steps should hopefully be:<ol><li>Cleaning up the bugs.<br />- Fix the incorrect menu related message that appears in the top telnet window shown in the screenshot.<br />- When a player quits the game, the display of other observing players does not update to reflect it.<br />- When an object moves, observing players are defined as those who have visited the tile the object moved to and currently have it on their display.  Instead only observing players who have the object in their field of vision should see the movement.</li><li>Polish the field of vision support.<br />- The tiles that are in the field of vision should be distinct from those that are not (<a href="http://www.zincland.com/7drl/kobold/">Smart Kobold</a> uses this approach to good effect).</li><li>Widen the corridors so players can pass each other.</li><li>Add entities controlled by AI that move around of their own volition.</li></ol>Really, in this day and age a game like this should be browser based (like <a href="http://startcontinue.com/community/">91</a>).  But getting side tracked into a non-game related endeavour to implement an equivalent canvas based display with a AJAX or COMET connection to the backend server, is something I have no time for just now.<br /><br />Next post: <a href="http://posted-stuff.blogspot.com/2010/09/roguelike-mud-progress-2.html">Roguelike MUD progress #2</a><div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/27648409-1495639712229954151?l=posted-stuff.blogspot.com" alt="" /></div>]]></description>
			<content:encoded><![CDATA[I finally found some more time to work on my roguelike MUD project.  Tonight I managed to get proper multi-player support in, so that concurrently logged in players have their view of the game updated as other game objects change position.  Up to this point the players mostly shared the world representation, and had separate state defining what was in it.<br /><br /><a href="http://3.bp.blogspot.com/_7X0iQg6tJ40/TH0L9kd5yxI/AAAAAAAAAP4/z-izwSUZCOI/s1600/2010-08-31+-+Roguelike+shared+world.jpg"><img src="http://3.bp.blogspot.com/_7X0iQg6tJ40/TH0L9kd5yxI/AAAAAAAAAP4/z-izwSUZCOI/s320/2010-08-31+-+Roguelike+shared+world.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5511574671360379666" /></a><br />While the <a href="http://code.google.com/p/sorrows-mudlib/source/detail?r=174">changes required</a> are more or less fine, some didn't fit well into the existing game framework.  I need to put some thought into cleaning those up.<br /><br />Achievable next steps should hopefully be:<ol><li>Cleaning up the bugs.<br />- Fix the incorrect menu related message that appears in the top telnet window shown in the screenshot.<br />- When a player quits the game, the display of other observing players does not update to reflect it.<br />- When an object moves, observing players are defined as those who have visited the tile the object moved to and currently have it on their display.  Instead only observing players who have the object in their field of vision should see the movement.</li><li>Polish the field of vision support.<br />- The tiles that are in the field of vision should be distinct from those that are not (<a href="http://www.zincland.com/7drl/kobold/">Smart Kobold</a> uses this approach to good effect).</li><li>Widen the corridors so players can pass each other.</li><li>Add entities controlled by AI that move around of their own volition.</li></ol>Really, in this day and age a game like this should be browser based (like <a href="http://startcontinue.com/community/">91</a>).  But getting side tracked into a non-game related endeavour to implement an equivalent canvas based display with a AJAX or COMET connection to the backend server, is something I have no time for just now.<br /><br />Next post: <a href="http://posted-stuff.blogspot.com/2010/09/roguelike-mud-progress-2.html">Roguelike MUD progress #2</a><div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/27648409-1495639712229954151?l=posted-stuff.blogspot.com" alt="" /></div>]]></content:encoded>
			<wfw:commentRss>http://posted-stuff.blogspot.com/2010/09/roguelike-mud-progress.html/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Richard Tew: Roguelike MUD progress #2</title>
		<link>http://posted-stuff.blogspot.com/2010/09/roguelike-mud-progress-2.html</link>
		<comments>http://posted-stuff.blogspot.com/2010/09/roguelike-mud-progress-2.html#comments</comments>
		<pubDate>Sun, 05 Sep 2010 11:37:31 +0000</pubDate>
		<dc:creator>Planet Python</dc:creator>
				<category><![CDATA[Planet]]></category>

		<guid isPermaLink="false">http://posted-stuff.blogspot.com/2010/09/roguelike-mud-progress-2.html</guid>
		<description><![CDATA[Previous post: <a href="http://posted-stuff.blogspot.com/2010/09/roguelike-mud-progress.html">Roguelike MUD progress</a>.<br /><br />I wasn't feeling very motivated when the time I had set aside tonight to work on this came around, but once I got into it I made pretty good progress.  The bugs I listed yesterday are now fixed, and additionally the field of view emphasis is working.  It's annoying that the stupid mistakes are the ones that take the longest to track down.  In this case, absently writing <code>or</code> instead of <code>and</code>.<pre>if y in self.drawRangesNew:<br />    minX, maxX = self.drawRangesNew[y]<br />    if x &#62;= minX or x = maxX:<br />        return True</pre>Maybe I should reconsider <code>minX = x = maxX</code>, although it never quite seems right.<br /><br /><a href="http://2.bp.blogspot.com/_7X0iQg6tJ40/TH5cosGPhFI/AAAAAAAAAQA/UoHWrIBfcmc/s1600/2010-09-01+-+03+-+Field+of+view+multiplayer.jpg"><img src="http://2.bp.blogspot.com/_7X0iQg6tJ40/TH5cosGPhFI/AAAAAAAAAQA/UoHWrIBfcmc/s320/2010-09-01+-+03+-+Field+of+view+multiplayer.jpg" border="0" alt="" /></a><br />The <a href="http://code.google.com/p/sorrows-mudlib/source/detail?r=177">FoV changes</a> are not as optimal as they could be.  Every tile in the post-move FoV tile set is individually marked up with escape codes, I should instead simply mark each row of qualifying tiles in one go.<br /><br />Current TODO list:<ol><li>Clean up the FoV emphasis to be row-based, rather than tile-based.</li><li>Add some objects and entities to the world, that can be interacted with.  Entities should move to add life to the world.</li></ol><br /><br />Next post: <a href="http://posted-stuff.blogspot.com/2010/09/roguelike-mud-progress-3.html">Roguelike MUD progress #3</a><div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/27648409-6092525463466435058?l=posted-stuff.blogspot.com" alt="" /></div>]]></description>
			<content:encoded><![CDATA[Previous post: <a href="http://posted-stuff.blogspot.com/2010/09/roguelike-mud-progress.html">Roguelike MUD progress</a>.<br /><br />I wasn't feeling very motivated when the time I had set aside tonight to work on this came around, but once I got into it I made pretty good progress.  The bugs I listed yesterday are now fixed, and additionally the field of view emphasis is working.  It's annoying that the stupid mistakes are the ones that take the longest to track down.  In this case, absently writing <code>or</code> instead of <code>and</code>.<pre class="brush: python">if y in self.drawRangesNew:<br />    minX, maxX = self.drawRangesNew[y]<br />    if x >= minX or x = maxX:<br />        return True</pre>Maybe I should reconsider <code>minX = x = maxX</code>, although it never quite seems right.<br /><br /><a href="http://2.bp.blogspot.com/_7X0iQg6tJ40/TH5cosGPhFI/AAAAAAAAAQA/UoHWrIBfcmc/s1600/2010-09-01+-+03+-+Field+of+view+multiplayer.jpg"><img src="http://2.bp.blogspot.com/_7X0iQg6tJ40/TH5cosGPhFI/AAAAAAAAAQA/UoHWrIBfcmc/s320/2010-09-01+-+03+-+Field+of+view+multiplayer.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5511944848049931346" /></a><br />The <a href="http://code.google.com/p/sorrows-mudlib/source/detail?r=177">FoV changes</a> are not as optimal as they could be.  Every tile in the post-move FoV tile set is individually marked up with escape codes, I should instead simply mark each row of qualifying tiles in one go.<br /><br />Current TODO list:<ol><li>Clean up the FoV emphasis to be row-based, rather than tile-based.</li><li>Add some objects and entities to the world, that can be interacted with.  Entities should move to add life to the world.</li></ol><br /><br />Next post: <a href="http://posted-stuff.blogspot.com/2010/09/roguelike-mud-progress-3.html">Roguelike MUD progress #3</a><div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/27648409-6092525463466435058?l=posted-stuff.blogspot.com" alt="" /></div>]]></content:encoded>
			<wfw:commentRss>http://posted-stuff.blogspot.com/2010/09/roguelike-mud-progress-2.html/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Richard Tew: Roguelike MUD progress #3</title>
		<link>http://posted-stuff.blogspot.com/2010/09/roguelike-mud-progress-3.html</link>
		<comments>http://posted-stuff.blogspot.com/2010/09/roguelike-mud-progress-3.html#comments</comments>
		<pubDate>Sun, 05 Sep 2010 11:37:31 +0000</pubDate>
		<dc:creator>Planet Python</dc:creator>
				<category><![CDATA[Planet]]></category>

		<guid isPermaLink="false">http://posted-stuff.blogspot.com/2010/09/roguelike-mud-progress-3.html</guid>
		<description><![CDATA[Previous post: <a href="http://posted-stuff.blogspot.com/2010/09/roguelike-mud-progress-2.html">Roguelike MUD progress #2</a>.<br /><br />Field of view emphasis is now row based, rather than tile based.  However, I've also added the ability for tiles to have attached foreground and background colours.  Really, the rendering needs to break all this down and minimise the number of switches made using different escape codes.  For now, use of colour is limited, so updating the display does not seem slow or flickery like it was in the past before I batched updates.<br /><br />I've also added simple NPCs, in this case three small green dragons that wander around the dungeon.  For now, that's all they do, but they're good at highlighting rendering bugs.<br /><br /><a href="http://3.bp.blogspot.com/_7X0iQg6tJ40/TIM2-bVcneI/AAAAAAAAAQQ/YhGdGtECieY/s1600/2010-09-05+-+01+-+Coloured+tiles.jpg"><img src="http://3.bp.blogspot.com/_7X0iQg6tJ40/TIM2-bVcneI/AAAAAAAAAQQ/YhGdGtECieY/s320/2010-09-05+-+01+-+Coloured+tiles.jpg" border="0" alt="" /></a><br /><br />Current TODO list:<ol><li>Add bursts of fire, using different tiles and colours to make use of a wide range of colours than the <a href="http://en.wikipedia.org/wiki/ANSI_escape_code#Colors">basic eight</a> through dithering.  It might be a good idea to write the tile/colour choosing logic in a way that can optionally use the <a href="http://www.frexx.de/xterm-256-notes/">xterm 256 colour mode</a>, if the client can be detected as supporting it.</li><li>Add option for NPCs to choose to attack, rather than move, when they are ticked.</li><li>Add option for players to attack, rather than move.</li><li>At the moment, player keypresses are executed as they come in from the client.  They should instead be queued and executed at a fixed rate.</li></ol><div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/27648409-3649004583991090686?l=posted-stuff.blogspot.com" alt="" /></div>]]></description>
			<content:encoded><![CDATA[Previous post: <a href="http://posted-stuff.blogspot.com/2010/09/roguelike-mud-progress-2.html">Roguelike MUD progress #2</a>.<br /><br />Field of view emphasis is now row based, rather than tile based.  However, I've also added the ability for tiles to have attached foreground and background colours.  Really, the rendering needs to break all this down and minimise the number of switches made using different escape codes.  For now, use of colour is limited, so updating the display does not seem slow or flickery like it was in the past before I batched updates.<br /><br />I've also added simple NPCs, in this case three small green dragons that wander around the dungeon.  For now, that's all they do, but they're good at highlighting rendering bugs.<br /><br /><a href="http://3.bp.blogspot.com/_7X0iQg6tJ40/TIM2-bVcneI/AAAAAAAAAQQ/YhGdGtECieY/s1600/2010-09-05+-+01+-+Coloured+tiles.jpg"><img src="http://3.bp.blogspot.com/_7X0iQg6tJ40/TIM2-bVcneI/AAAAAAAAAQQ/YhGdGtECieY/s320/2010-09-05+-+01+-+Coloured+tiles.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5513310814949121506" /></a><br /><br />Current TODO list:<ol><li>Add bursts of fire, using different tiles and colours to make use of a wide range of colours than the <a href="http://en.wikipedia.org/wiki/ANSI_escape_code#Colors">basic eight</a> through dithering.  It might be a good idea to write the tile/colour choosing logic in a way that can optionally use the <a href="http://www.frexx.de/xterm-256-notes/">xterm 256 colour mode</a>, if the client can be detected as supporting it.</li><li>Add option for NPCs to choose to attack, rather than move, when they are ticked.</li><li>Add option for players to attack, rather than move.</li><li>At the moment, player keypresses are executed as they come in from the client.  They should instead be queued and executed at a fixed rate.</li></ol><div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/27648409-3649004583991090686?l=posted-stuff.blogspot.com" alt="" /></div>]]></content:encoded>
			<wfw:commentRss>http://posted-stuff.blogspot.com/2010/09/roguelike-mud-progress-3.html/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP segfaulting with pecl/uuid and pecl/imagick &#8211; Lars Strojny</title>
		<link>http://usrportage.de/archives/922-PHP-segfaulting-with-pecluuid-and-peclimagick.html</link>
		<comments>http://usrportage.de/archives/922-PHP-segfaulting-with-pecluuid-and-peclimagick.html#comments</comments>
		<pubDate>Sun, 05 Sep 2010 11:24:02 +0000</pubDate>
		<dc:creator>Planet PHP</dc:creator>
				<category><![CDATA[Planet]]></category>

		<guid isPermaLink="false">tag:www.planet-php.net://834e01444d77f0119ace4b343c3b0b56</guid>
		<description><![CDATA[
            <div>
                	<p>Ran into a bug yesterday, where <a href="pecl/uuid">http://pecl.php.net/uuid</a> in combination with <a href="pecl/imagick">http://pecl.php.net/imagick</a> yielded a segfault when using <code>uuid_create()</code>. <span class="caps">GDB</span> backtrace looks like this (without the exact place where it happens in libuuid, as there is unfortunatly no <code>libuuid1-dbg</code>-package in current Ubuntu versions):</p>

<pre><code>gdb --silent --ex run --args php -r "var_dump(uuid_create());"
#0  0xb6e85321 in ?? () from /lib/libuuid.so.1
#1  0xb6e862bf in uuid_generate () from /lib/libuuid.so.1
#2  0xb6bcc67a in zif_uuid_create (ht=0, return_value=0xbffff1e8, return_value_ptr=0x0, this_ptr=0x0, return_value_used=1) at /usr/src/pecl-uuid-trunk/uuid.c:182
#3  0x0835d26a in zend_do_fcall_common_helper_SPEC (execute_data=0x894ed4c) at /build/buildd/php5-5.3.2/Zend/zend_vm_execute.h:313
#4  0x08333d8e in execute (op_array=0x891c464) at /build/buildd/php5-5.3.2/Zend/zend_vm_execute.h:104
#5  0x082fe283 in zend_eval_stringl (str=0xbffff998 "var_dump(uuid_create());", str_len=24, retval_ptr=0x0, string_name=0x871f2fc "Command line code")
    at /build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1172
#6  0x082fe422 in zend_eval_stringl_ex (str=0xbffff998 "var_dump(uuid_create());", str_len=24, retval_ptr=0x0, string_name=0x871f2fc "Command line code", handle_exceptions=1)
    at /build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1214
#7  0x082fe4a3 in zend_eval_string_ex (str=0xbffff998 "var_dump(uuid_create());", retval_ptr=0x0, string_name=0x871f2fc "Command line code", handle_exceptions=1)
    at /build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1225
#8  0x083a0579 in main (argc=3, argv=0xbffff854) at /build/buildd/php5-5.3.2/sapi/cli/php_cli.c:1235
</code></pre>

	<p>The interesting thing is, the crash happens in libuuid, but only if imagick is enabled. Let’s see what Valgrind says:</p>

<pre><code>valgrind -q  php -r "var_dump(uuid_create());"
==25103== Invalid write of size 2
==25103==    at 0x5517321: ??? (in /lib/libuuid.so.1.3.0)
==25103==    by 0x55182BE: uuid_generate (in /lib/libuuid.so.1.3.0)
==25103==    by 0x57D0679: zif_uuid_create (uuid.c:182)
==25103==    by 0x835D269: zend_do_fcall_common_helper_SPEC (in /usr/bin/php5)
==25103==    by 0x8333D8D: execute (/build/buildd/php5-5.3.2/Zend/zend_vm_execute.h:104)
==25103==    by 0x82FE282: zend_eval_stringl (/build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1172)
==25103==    by 0x82FE421: zend_eval_stringl_ex (/build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1214)
==25103==    by 0x82FE4A2: zend_eval_string_ex (/build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1225)
==25103==    by 0x83A0578: main (/build/buildd/php5-5.3.2/sapi/cli/php_cli.c:1235)
==25103==  Address 0x30 is not stack'd, malloc'd or (recently) free'd
==25103== 
==25103== 
==25103== Process terminating with default action of signal 11 (SIGSEGV)
==25103==  Access not within mapped region at address 0x30
==25103==    at 0x5517321: ??? (in /lib/libuuid.so.1.3.0)
==25103==    by 0x55182BE: uuid_generate (in /lib/libuuid.so.1.3.0)
==25103==    by 0x57D0679: zif_uuid_create (uuid.c:182)
==25103==    by 0x835D269: zend_do_fcall_common_helper_SPEC (in /usr/bin/php5)
==25103==    by 0x8333D8D: execute (/build/buildd/php5-5.3.2/Zend/zend_vm_execute.h:104)
==25103==    by 0x82FE282: zend_eval_stringl (/build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1172)
==25103==    by 0x82FE421: zend_eval_stringl_ex (/build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1214)
==25103==    by 0x82FE4A2: zend_eval_string_ex (/build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1225)
==25103==    by 0x83A0578: main (/build/buildd/php5-5.3.2/sapi/cli/php_cli.c:1235)
==25103==  If you believe this happened as a result of a stack
==25103==  overflow in your program's main thread (unlikely but
==25103==  possible), you can try to increase the size of the
==25103==  main thread stack using the --main-stacksize= flag.
==25103==  The main thread stack size used in this run was 8388608.
Segmentation fault
</code></pre>

	<p>Not really any more helpful. After two hours debugging the issue with the help of <a href="http://valokuva.org/">Mikko</a> and <a href="http://blog.thepimp.net/">Pierre</a> we found out, that pecl/imagick is linked against libuuid too:</p>

<pre><code>ldd /usr/lib/php5/20090626+lfs/imagick.so
    (...)
    libuuid.so.1 =&#62; /lib/libuuid.so.1 (0xb7086000)
    (...)
</code></pre>

	<p>For whatever reason this is happening, this is most likely the root cause of the issue.</p>

	<h3>Solution (sort of)</h3>

	<p>pecl/uuid was loaded by <code>/etc/php5/conf.d/uuid.ini</code> and pecl/imagick by <code>/etc/php5/conf.d/imagick.ini</code>. As they are loaded in there alphabetical order, imagick initialized before uuid. Renaming <code>/etc/php5/conf.d/uuid.ini</code> to  <code>/etc/php5/conf.d/00-uuid.ini</code> fixed the issue, as uuid is than initialized before imagick and the segmentation fault was gone.<br /></br>
Not sure about that, but maybe it would be a good idea to check in <code>PHP_MINIT(uuid)</code> in pecl/uuid if pecl/imagick has been initialized before and warn the user about it?</p> 
            </div>
        ]]></description>
			<content:encoded><![CDATA[
            <div >
                	<p >Ran into a bug yesterday, where <a href="http://usrportage.de/archives/pecl/uuid">http://pecl.php.net/uuid</a> in combination with <a href="http://usrportage.de/archives/pecl/imagick">http://pecl.php.net/imagick</a> yielded a segfault when using <code >uuid_create()</code>. <span class="caps">GDB</span> backtrace looks like this (without the exact place where it happens in libuuid, as there is unfortunatly no <code >libuuid1-dbg</code>-package in current Ubuntu versions):</p>

<pre ><code >gdb --silent --ex run --args php -r "var_dump(uuid_create());"
#0  0xb6e85321 in ?? () from /lib/libuuid.so.1
#1  0xb6e862bf in uuid_generate () from /lib/libuuid.so.1
#2  0xb6bcc67a in zif_uuid_create (ht=0, return_value=0xbffff1e8, return_value_ptr=0x0, this_ptr=0x0, return_value_used=1) at /usr/src/pecl-uuid-trunk/uuid.c:182
#3  0x0835d26a in zend_do_fcall_common_helper_SPEC (execute_data=0x894ed4c) at /build/buildd/php5-5.3.2/Zend/zend_vm_execute.h:313
#4  0x08333d8e in execute (op_array=0x891c464) at /build/buildd/php5-5.3.2/Zend/zend_vm_execute.h:104
#5  0x082fe283 in zend_eval_stringl (str=0xbffff998 "var_dump(uuid_create());", str_len=24, retval_ptr=0x0, string_name=0x871f2fc "Command line code")
    at /build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1172
#6  0x082fe422 in zend_eval_stringl_ex (str=0xbffff998 "var_dump(uuid_create());", str_len=24, retval_ptr=0x0, string_name=0x871f2fc "Command line code", handle_exceptions=1)
    at /build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1214
#7  0x082fe4a3 in zend_eval_string_ex (str=0xbffff998 "var_dump(uuid_create());", retval_ptr=0x0, string_name=0x871f2fc "Command line code", handle_exceptions=1)
    at /build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1225
#8  0x083a0579 in main (argc=3, argv=0xbffff854) at /build/buildd/php5-5.3.2/sapi/cli/php_cli.c:1235
</code></pre>

	<p >The interesting thing is, the crash happens in libuuid, but only if imagick is enabled. Let’s see what Valgrind says:</p>

<pre ><code >valgrind -q  php -r "var_dump(uuid_create());"
==25103== Invalid write of size 2
==25103==    at 0x5517321: ??? (in /lib/libuuid.so.1.3.0)
==25103==    by 0x55182BE: uuid_generate (in /lib/libuuid.so.1.3.0)
==25103==    by 0x57D0679: zif_uuid_create (uuid.c:182)
==25103==    by 0x835D269: zend_do_fcall_common_helper_SPEC (in /usr/bin/php5)
==25103==    by 0x8333D8D: execute (/build/buildd/php5-5.3.2/Zend/zend_vm_execute.h:104)
==25103==    by 0x82FE282: zend_eval_stringl (/build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1172)
==25103==    by 0x82FE421: zend_eval_stringl_ex (/build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1214)
==25103==    by 0x82FE4A2: zend_eval_string_ex (/build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1225)
==25103==    by 0x83A0578: main (/build/buildd/php5-5.3.2/sapi/cli/php_cli.c:1235)
==25103==  Address 0x30 is not stack'd, malloc'd or (recently) free'd
==25103== 
==25103== 
==25103== Process terminating with default action of signal 11 (SIGSEGV)
==25103==  Access not within mapped region at address 0x30
==25103==    at 0x5517321: ??? (in /lib/libuuid.so.1.3.0)
==25103==    by 0x55182BE: uuid_generate (in /lib/libuuid.so.1.3.0)
==25103==    by 0x57D0679: zif_uuid_create (uuid.c:182)
==25103==    by 0x835D269: zend_do_fcall_common_helper_SPEC (in /usr/bin/php5)
==25103==    by 0x8333D8D: execute (/build/buildd/php5-5.3.2/Zend/zend_vm_execute.h:104)
==25103==    by 0x82FE282: zend_eval_stringl (/build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1172)
==25103==    by 0x82FE421: zend_eval_stringl_ex (/build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1214)
==25103==    by 0x82FE4A2: zend_eval_string_ex (/build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1225)
==25103==    by 0x83A0578: main (/build/buildd/php5-5.3.2/sapi/cli/php_cli.c:1235)
==25103==  If you believe this happened as a result of a stack
==25103==  overflow in your program's main thread (unlikely but
==25103==  possible), you can try to increase the size of the
==25103==  main thread stack using the --main-stacksize= flag.
==25103==  The main thread stack size used in this run was 8388608.
Segmentation fault
</code></pre>

	<p >Not really any more helpful. After two hours debugging the issue with the help of <a href="http://valokuva.org/">Mikko</a> and <a href="http://blog.thepimp.net/">Pierre</a> we found out, that pecl/imagick is linked against libuuid too:</p>

<pre ><code >ldd /usr/lib/php5/20090626+lfs/imagick.so
    (...)
    libuuid.so.1 => /lib/libuuid.so.1 (0xb7086000)
    (...)
</code></pre>

	<p >For whatever reason this is happening, this is most likely the root cause of the issue.</p>

	<h3 >Solution (sort of)</h3>

	<p >pecl/uuid was loaded by <code >/etc/php5/conf.d/uuid.ini</code> and pecl/imagick by <code >/etc/php5/conf.d/imagick.ini</code>. As they are loaded in there alphabetical order, imagick initialized before uuid. Renaming <code >/etc/php5/conf.d/uuid.ini</code> to  <code >/etc/php5/conf.d/00-uuid.ini</code> fixed the issue, as uuid is than initialized before imagick and the segmentation fault was gone.<br ></br>
Not sure about that, but maybe it would be a good idea to check in <code >PHP_MINIT(uuid)</code> in pecl/uuid if pecl/imagick has been initialized before and warn the user about it?</p> 
            </div>
        ]]></content:encoded>
			<wfw:commentRss>http://usrportage.de/archives/922-PHP-segfaulting-with-pecluuid-and-peclimagick.html/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ned Batchelder: Making good tar files on Windows</title>
		<link>http://nedbatchelder.com/blog/201009/making_good_tar_files_on_windows.html</link>
		<comments>http://nedbatchelder.com/blog/201009/making_good_tar_files_on_windows.html#comments</comments>
		<pubDate>Sun, 05 Sep 2010 11:13:06 +0000</pubDate>
		<dc:creator>Planet Python</dc:creator>
				<category><![CDATA[Planet]]></category>

		<guid isPermaLink="false">http://nedbatchelder.com/blog/201009/making_good_tar_files_on_windows.html</guid>
		<description><![CDATA[<p>I work on Windows, and produce Python kits for various projects.
        Of course one of the kits is a source kit, as a .tar.gz.
        Python's distutils does a fine job of this, but it uses the 
        native system command to tar up the files, and this means my
        tar files are from Windows.</p><p>The problem is that Windows doesn't know how to make tar files
        that look native on Unix: the permission bits aren't right,
        they come out as 0700:</p><blockquote class="code"><tt>drwx------ batcheln/100      0 2010-08-21 14:13 coverage-3.4b1/<br />-rwx------ batcheln/100    516 2010-08-08 09:36 coverage-3.4b1/AUTHORS.txt<br />...<br /></tt></blockquote><p>The tar command let me set the mode bits in a command-line switch,
    which means I could set them in an environment variable, but that
    would make all the files have the same permission bits, and directories
    and files should be different.</p><p>To fix this problem, I wrote a distutils extension command.  It turned
    out to be not difficult, distutils has good extensibility.</p><p>To make a new command, create a new package directory somewhere, I 
    called my "distcmd".  To make a command called "fixtar", you you derive a
    class from distutils.core.Command, name it fixtar, and put it in a file
    called fixtar.py.  You have to provide three methods:</p><blockquote class="code"><tt><span class="p_word">from</span><span class="p_default">&#160;</span><span class="p_identifier">distutils</span><span class="p_operator">.</span><span class="p_identifier">core</span><span class="p_default">&#160;</span><span class="p_word">import</span><span class="p_default">&#160;</span><span class="p_identifier">Command</span><br />
<span class="p_word">import</span><span class="p_default">&#160;</span><span class="p_identifier">shutil</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">tarfile</span><br />
<br />
<span class="p_word">class</span><span class="p_default">&#160;</span><span class="p_classname">fixtar</span><span class="p_operator">(</span><span class="p_identifier">Command</span><span class="p_operator">):</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_tripledouble">"""A&#160;new&#160;setup.py&#160;command&#160;to&#160;fix&#160;tar&#160;file&#160;permissions."""</span><br />
<br />
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_identifier">description</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_string">"Re-pack&#160;the&#160;tar&#160;file&#160;to&#160;have&#160;correct&#160;permissions."</span><br />
<br />
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_identifier">user_options</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_operator">[]</span><br />
<br />
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">def</span><span class="p_default">&#160;</span><span class="p_defname">initialize_options</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">):</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_tripledouble">"""Required&#160;by&#160;Command,&#160;even&#160;though&#160;I&#160;have&#160;nothing&#160;to&#160;add."""</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">pass</span><br />
<br />
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">def</span><span class="p_default">&#160;</span><span class="p_defname">finalize_options</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">):</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_tripledouble">"""Required&#160;by&#160;Command,&#160;even&#160;though&#160;I&#160;have&#160;nothing&#160;to&#160;add."""</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">pass</span><br />
<br />
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">def</span><span class="p_default">&#160;</span><span class="p_defname">run</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">):</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_tripledouble">"""The&#160;body&#160;of&#160;the&#160;command."""</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_commentline">#&#160;Put&#160;something&#160;useful&#160;here!</span><br />
</tt></blockquote><p>The initialize_options and finalize_options methods are required.  It's too
    bad distutils didn't allow them to be omitted in cases like mine where
    there are no options to specify.  The run() method is the interesting one,
    that's where all the work will happen.  In mine, I read the tar file
    distutils made, and I create a new tar file just like it, but with the
    permissions and owner info that I want:</p><blockquote class="code"><tt><span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">def</span><span class="p_default">&#160;</span><span class="p_defname">run</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">):</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_tripledouble">"""The&#160;body&#160;of&#160;the&#160;command."""</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">for</span><span class="p_default">&#160;</span><span class="p_identifier">_</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">_</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">filename</span><span class="p_default">&#160;</span><span class="p_word">in</span><span class="p_default">&#160;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">distribution</span><span class="p_operator">.</span><span class="p_identifier">dist_files</span><span class="p_operator">:</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">if</span><span class="p_default">&#160;</span><span class="p_identifier">filename</span><span class="p_operator">.</span><span class="p_identifier">endswith</span><span class="p_operator">(</span><span class="p_string">".tar.gz"</span><span class="p_operator">):</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">repack_tar</span><span class="p_operator">(</span><span class="p_identifier">filename</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_string">"temp.tar.gz"</span><span class="p_operator">)</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">shutil</span><span class="p_operator">.</span><span class="p_identifier">move</span><span class="p_operator">(</span><span class="p_string">"temp.tar.gz"</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">filename</span><span class="p_operator">)</span><br />
<br />
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">def</span><span class="p_default">&#160;</span><span class="p_defname">repack_tar</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">infilename</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">outfilename</span><span class="p_operator">):</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_tripledouble">"""Re-pack&#160;`infilename`&#160;as&#160;`outfilename`.</span><br />
<br />
<span class="p_tripledouble">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Permissions&#160;and&#160;owners&#160;are&#160;set&#160;the&#160;way&#160;we&#160;like&#160;them.</span><br />
<br />
<span class="p_tripledouble">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;"""</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">itar</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_identifier">tarfile</span><span class="p_operator">.</span><span class="p_identifier">open</span><span class="p_operator">(</span><span class="p_identifier">infilename</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_string">"r:gz"</span><span class="p_operator">)</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">otar</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_identifier">tarfile</span><span class="p_operator">.</span><span class="p_identifier">open</span><span class="p_operator">(</span><span class="p_identifier">outfilename</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_string">"w:gz"</span><span class="p_operator">)</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">for</span><span class="p_default">&#160;</span><span class="p_identifier">itarinfo</span><span class="p_default">&#160;</span><span class="p_word">in</span><span class="p_default">&#160;</span><span class="p_identifier">itar</span><span class="p_operator">:</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">otarinfo</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_identifier">otar</span><span class="p_operator">.</span><span class="p_identifier">gettarinfo</span><span class="p_operator">(</span><span class="p_identifier">itarinfo</span><span class="p_operator">.</span><span class="p_identifier">name</span><span class="p_operator">)</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">if</span><span class="p_default">&#160;</span><span class="p_identifier">itarinfo</span><span class="p_operator">.</span><span class="p_identifier">isfile</span><span class="p_operator">():</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">otarinfo</span><span class="p_operator">.</span><span class="p_identifier">mode</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_number">0644</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">else</span><span class="p_operator">:</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">otarinfo</span><span class="p_operator">.</span><span class="p_identifier">mode</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_number">0755</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">otarinfo</span><span class="p_operator">.</span><span class="p_identifier">uid</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_number">100</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">otarinfo</span><span class="p_operator">.</span><span class="p_identifier">gid</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_number">100</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">otarinfo</span><span class="p_operator">.</span><span class="p_identifier">uname</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_string">"ned"</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">otarinfo</span><span class="p_operator">.</span><span class="p_identifier">gname</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_string">"coverage"</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">otar</span><span class="p_operator">.</span><span class="p_identifier">addfile</span><span class="p_operator">(</span><span class="p_identifier">otarinfo</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">itar</span><span class="p_operator">.</span><span class="p_identifier">extractfile</span><span class="p_operator">(</span><span class="p_identifier">itarinfo</span><span class="p_operator">))</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">itar</span><span class="p_operator">.</span><span class="p_identifier">close</span><span class="p_operator">()</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">otar</span><span class="p_operator">.</span><span class="p_identifier">close</span><span class="p_operator">()</span><br />
</tt></blockquote><p>To invoke my new command, I have to tell setup.py to pull it in with the --command-packages=distcmd switch.
Then I can simply use "fixtar" as a command on the line just like any other:</p><blockquote class="code"><tt>python setup.py --command-packages=distcmd sdist --keep-temp --formats=gztar fixtar</tt></blockquote><p>Now I get a tar file that looks right:</p><blockquote class="code"><tt>drwxr-xr-x ned/coverage      0 2010-09-04 19:44 coverage-3.4b2/<br />-rw-r--r-- ned/coverage    516 2010-08-08 09:36 coverage-3.4b2/AUTHORS.txt<br />...<br /></tt></blockquote><p>There's a bit more complication to it, because of the --keep-temp switch that I needed
    to keep the original tarred files around so they could be re-tarred.  The 
    <a class="offsite" href="http://bitbucket.org/ned/coveragepy/src/tip/distcmd/fixtar.py">real fixtar.py</a>
    also cleans up that directory.</p><p>This was more than I wanted to do to get the right permissions in a tar file, 
    but it was a chance to see how distutils extensions work, and it lets me make all
    my kits in one place.</p>]]></description>
			<content:encoded><![CDATA[<p>I work on Windows, and produce Python kits for various projects.
        Of course one of the kits is a source kit, as a .tar.gz.
        Python's distutils does a fine job of this, but it uses the 
        native system command to tar up the files, and this means my
        tar files are from Windows.</p><p>The problem is that Windows doesn't know how to make tar files
        that look native on Unix: the permission bits aren't right,
        they come out as 0700:</p><blockquote class="code"><tt>drwx------ batcheln/100      0 2010-08-21 14:13 coverage-3.4b1/<br />-rwx------ batcheln/100    516 2010-08-08 09:36 coverage-3.4b1/AUTHORS.txt<br />...<br /></tt></blockquote><p>The tar command let me set the mode bits in a command-line switch,
    which means I could set them in an environment variable, but that
    would make all the files have the same permission bits, and directories
    and files should be different.</p><p>To fix this problem, I wrote a distutils extension command.  It turned
    out to be not difficult, distutils has good extensibility.</p><p>To make a new command, create a new package directory somewhere, I 
    called my "distcmd".  To make a command called "fixtar", you you derive a
    class from distutils.core.Command, name it fixtar, and put it in a file
    called fixtar.py.  You have to provide three methods:</p><blockquote class="code"><tt><span class="p_word">from</span><span class="p_default">&#160;</span><span class="p_identifier">distutils</span><span class="p_operator">.</span><span class="p_identifier">core</span><span class="p_default">&#160;</span><span class="p_word">import</span><span class="p_default">&#160;</span><span class="p_identifier">Command</span><br />
<span class="p_word">import</span><span class="p_default">&#160;</span><span class="p_identifier">shutil</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">tarfile</span><br />
<br />
<span class="p_word">class</span><span class="p_default">&#160;</span><span class="p_classname">fixtar</span><span class="p_operator">(</span><span class="p_identifier">Command</span><span class="p_operator">):</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_tripledouble">"""A&#160;new&#160;setup.py&#160;command&#160;to&#160;fix&#160;tar&#160;file&#160;permissions."""</span><br />
<br />
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_identifier">description</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_string">"Re-pack&#160;the&#160;tar&#160;file&#160;to&#160;have&#160;correct&#160;permissions."</span><br />
<br />
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_identifier">user_options</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_operator">[]</span><br />
<br />
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">def</span><span class="p_default">&#160;</span><span class="p_defname">initialize_options</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">):</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_tripledouble">"""Required&#160;by&#160;Command,&#160;even&#160;though&#160;I&#160;have&#160;nothing&#160;to&#160;add."""</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">pass</span><br />
<br />
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">def</span><span class="p_default">&#160;</span><span class="p_defname">finalize_options</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">):</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_tripledouble">"""Required&#160;by&#160;Command,&#160;even&#160;though&#160;I&#160;have&#160;nothing&#160;to&#160;add."""</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">pass</span><br />
<br />
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">def</span><span class="p_default">&#160;</span><span class="p_defname">run</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">):</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_tripledouble">"""The&#160;body&#160;of&#160;the&#160;command."""</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_commentline">#&#160;Put&#160;something&#160;useful&#160;here!</span><br />
</tt></blockquote><p>The initialize_options and finalize_options methods are required.  It's too
    bad distutils didn't allow them to be omitted in cases like mine where
    there are no options to specify.  The run() method is the interesting one,
    that's where all the work will happen.  In mine, I read the tar file
    distutils made, and I create a new tar file just like it, but with the
    permissions and owner info that I want:</p><blockquote class="code"><tt><span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">def</span><span class="p_default">&#160;</span><span class="p_defname">run</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">):</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_tripledouble">"""The&#160;body&#160;of&#160;the&#160;command."""</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">for</span><span class="p_default">&#160;</span><span class="p_identifier">_</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">_</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">filename</span><span class="p_default">&#160;</span><span class="p_word">in</span><span class="p_default">&#160;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">distribution</span><span class="p_operator">.</span><span class="p_identifier">dist_files</span><span class="p_operator">:</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">if</span><span class="p_default">&#160;</span><span class="p_identifier">filename</span><span class="p_operator">.</span><span class="p_identifier">endswith</span><span class="p_operator">(</span><span class="p_string">".tar.gz"</span><span class="p_operator">):</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">self</span><span class="p_operator">.</span><span class="p_identifier">repack_tar</span><span class="p_operator">(</span><span class="p_identifier">filename</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_string">"temp.tar.gz"</span><span class="p_operator">)</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">shutil</span><span class="p_operator">.</span><span class="p_identifier">move</span><span class="p_operator">(</span><span class="p_string">"temp.tar.gz"</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">filename</span><span class="p_operator">)</span><br />
<br />
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">def</span><span class="p_default">&#160;</span><span class="p_defname">repack_tar</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">infilename</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">outfilename</span><span class="p_operator">):</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_tripledouble">"""Re-pack&#160;`infilename`&#160;as&#160;`outfilename`.</span><br />
<br />
<span class="p_tripledouble">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Permissions&#160;and&#160;owners&#160;are&#160;set&#160;the&#160;way&#160;we&#160;like&#160;them.</span><br />
<br />
<span class="p_tripledouble">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;"""</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">itar</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_identifier">tarfile</span><span class="p_operator">.</span><span class="p_identifier">open</span><span class="p_operator">(</span><span class="p_identifier">infilename</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_string">"r:gz"</span><span class="p_operator">)</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">otar</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_identifier">tarfile</span><span class="p_operator">.</span><span class="p_identifier">open</span><span class="p_operator">(</span><span class="p_identifier">outfilename</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_string">"w:gz"</span><span class="p_operator">)</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">for</span><span class="p_default">&#160;</span><span class="p_identifier">itarinfo</span><span class="p_default">&#160;</span><span class="p_word">in</span><span class="p_default">&#160;</span><span class="p_identifier">itar</span><span class="p_operator">:</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">otarinfo</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_identifier">otar</span><span class="p_operator">.</span><span class="p_identifier">gettarinfo</span><span class="p_operator">(</span><span class="p_identifier">itarinfo</span><span class="p_operator">.</span><span class="p_identifier">name</span><span class="p_operator">)</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">if</span><span class="p_default">&#160;</span><span class="p_identifier">itarinfo</span><span class="p_operator">.</span><span class="p_identifier">isfile</span><span class="p_operator">():</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">otarinfo</span><span class="p_operator">.</span><span class="p_identifier">mode</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_number">0644</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">else</span><span class="p_operator">:</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">otarinfo</span><span class="p_operator">.</span><span class="p_identifier">mode</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_number">0755</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">otarinfo</span><span class="p_operator">.</span><span class="p_identifier">uid</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_number">100</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">otarinfo</span><span class="p_operator">.</span><span class="p_identifier">gid</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_number">100</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">otarinfo</span><span class="p_operator">.</span><span class="p_identifier">uname</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_string">"ned"</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">otarinfo</span><span class="p_operator">.</span><span class="p_identifier">gname</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_string">"coverage"</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">otar</span><span class="p_operator">.</span><span class="p_identifier">addfile</span><span class="p_operator">(</span><span class="p_identifier">otarinfo</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">itar</span><span class="p_operator">.</span><span class="p_identifier">extractfile</span><span class="p_operator">(</span><span class="p_identifier">itarinfo</span><span class="p_operator">))</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">itar</span><span class="p_operator">.</span><span class="p_identifier">close</span><span class="p_operator">()</span><br />
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">otar</span><span class="p_operator">.</span><span class="p_identifier">close</span><span class="p_operator">()</span><br />
</tt></blockquote><p>To invoke my new command, I have to tell setup.py to pull it in with the --command-packages=distcmd switch.
Then I can simply use "fixtar" as a command on the line just like any other:</p><blockquote class="code"><tt>python setup.py --command-packages=distcmd sdist --keep-temp --formats=gztar fixtar</tt></blockquote><p>Now I get a tar file that looks right:</p><blockquote class="code"><tt>drwxr-xr-x ned/coverage      0 2010-09-04 19:44 coverage-3.4b2/<br />-rw-r--r-- ned/coverage    516 2010-08-08 09:36 coverage-3.4b2/AUTHORS.txt<br />...<br /></tt></blockquote><p>There's a bit more complication to it, because of the --keep-temp switch that I needed
    to keep the original tarred files around so they could be re-tarred.  The 
    <a class="offsite" href="http://bitbucket.org/ned/coveragepy/src/tip/distcmd/fixtar.py">real fixtar.py</a>
    also cleans up that directory.</p><p>This was more than I wanted to do to get the right permissions in a tar file, 
    but it was a chance to see how distutils extensions work, and it lets me make all
    my kits in one place.</p>]]></content:encoded>
			<wfw:commentRss>http://nedbatchelder.com/blog/201009/making_good_tar_files_on_windows.html/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
