<?xml version="1.0" encoding="utf-8"?>
<!-- If you are running a bot please visit this policy page outlining rules you must respect. http://www.livejournal.com/bots/ -->
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:lj="http://www.livejournal.com">
  <id>urn:lj:livejournal.com:atom1:fragglet</id>
  <title>fragglet</title>
  <subtitle>fragglet</subtitle>
  <author>
    <name>fragglet</name>
  </author>
  <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/"/>
  <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom"/>
  <updated>2011-12-24T12:45:22Z</updated>
  <lj:journal userid="6372374" username="fragglet" type="personal"/>
  <link rel="service.feed" type="application/x.atom+xml" href="http://fragglet.livejournal.com/data/atom" title="fragglet"/>
  <link rel="hub" href="http://pubsubhubbub.appspot.com/"/>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:19971</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/19971.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=19971"/>
    <title>Goodbye Livejournal</title>
    <published>2011-12-24T12:45:22Z</published>
    <updated>2011-12-24T12:45:22Z</updated>
    <content type="html">I've decided to discontinue using Livejournal. The posts on this blog will remain up but future posts will appear &lt;a href="https://plus.google.com/111550145781278122079" rel="nofollow"&gt;on Google+&lt;/a&gt;.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:19966</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/19966.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=19966"/>
    <title>Initialisation dogma considered harmful</title>
    <published>2010-11-25T21:56:37Z</published>
    <updated>2011-12-14T13:27:07Z</updated>
    <content type="html">In C, variables aren't initialised to a value automatically.  I've seen some people who seem to have adopted a rule of initialising every variable they use when they declare it.  That is to say, they write code like this:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;
   void frobnicate(void)
   {
       int num_frobs = 0;
       void *frobs = NULL;

       num_frobs = get_num_frobs();
       frobs = malloc(num_frobs);

       ....
&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;Even though they initialise the variables before using them in their code, they include an initialiser in the declaration to set the value to zero or NULL.  Presumably the logic is something like: variables that aren't initialised can hold any value, which can cause bugs, so it's a good idea to always initialise every variable &lt;i&gt;just in case&lt;/i&gt;.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;I think this is an actively harmful practise and should be discouraged.  The reason I think this is that modern C compilers can detect when variables might be used without being initialised first (and gcc is scarily good at it), and adopting a rule like this of initialising everything breaks that functionality.  Consider an example like this:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;
    void clever_function_name(void)
    {
        mystruct *obj = NULL;
        int bar = 0;

        if (somecondition) {
            obj = new_mystruct();
            bar = 1;
        } else {
            // oops, forgot to initialise obj here as well
            bar = 2;
        }

        ...

        obj-&amp;gt;member = bar;
    }
&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;In this situation, "obj" is "uninitialised", as there is a code path where it isn't set that leads to a crash.  But technically, it &lt;i&gt;has&lt;/i&gt; been initialised in the variable declaration, as part of this initialisation dogma.  If it hadn't, the compiler would have been able to detect this bug, but it can't.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;I think the key thing is that initialising to a value like zero or NULL doesn't actually solve anything or prevent any bugs because it's just an arbitrary value.  In a general sense, having a variable that is set to those values isn't any more helpful than having some random garbage that got left on the stack.  It doesn't prevent uninitialised variable bugs, but it does prevent the compiler from detecting them.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:19646</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/19646.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=19646"/>
    <title>How to coerce gdb into giving a backtrace</title>
    <published>2010-11-23T20:38:03Z</published>
    <updated>2011-12-14T13:28:01Z</updated>
    <content type="html">When debugging with gdb, I sometimes encounter a problem in getting it to recognise a stack trace.  Sometimes it only gives a few function calls, or none at all.  Here's an example:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;(gdb) bt
#0  0xb7886424 in __kernel_vsyscall ()
#1  0xb7559163 in ?? () from /lib/i686/cmov/libc.so.6
#2  0xb74f1387 in ?? () from /lib/i686/cmov/libc.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;This obviously isn't a very useful backtrace.  At this point it can be useful to have a look at the registers and the contents of the stack.&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;
(gdb) info registers
eax            0xfffffe00	-512
ecx            0x80	128
edx            0x2	2
ebx            0xb75c33a0	-1218694240
esp            0xbfe55018	0xbfe55018    &lt;b&gt;&amp;lt;= stack pointer on x86 &lt;/b&gt;
ebp            0xbfe55048	0xbfe55048
esi            0x0	0
edi            0x0	0
eip            0xb7886424	0xb7886424 &amp;lt;__kernel_vsyscall+16&amp;gt;
eflags         0x202	[ IF ]
cs             0x73	115
ss             0x7b	123
ds             0x7b	123
es             0x7b	123
fs             0x0	0
gs             0x33	51
(gdb) x/64x $sp
0xbfe55018:	&lt;b&gt;0xbfe55048&lt;/b&gt;	0x00000002	0x00000080	0xb7559163
0xbfe55028:	0xb75c33a0	0xb75c1ff4	0x09ec0470	0xb74f1387
0xbfe55038:	0xb77c4afd	0xb782199c	0xb782199c	0x09ec0478
0xbfe55048:	&lt;b&gt;0xbfe55078&lt;/b&gt;	0xb77c4bf4	0x09ec0478	0xb782199c
0xbfe55058:	0x0000ffff	0xb75c3438	0xbfe55098	0xb789a240
0xbfe55068:	0x00000000	0xb782199c	0x0000ffff	0xb75c3438
0xbfe55078:	&lt;b&gt;0xbfe55098&lt;/b&gt;	0xb7818736	0x09ec0478	0x00000000
0xbfe55088:	0xb77c50cd	0xb782199c	0xb7818709	0xb782199c
0xbfe55098:	&lt;b&gt;0xbfe550b8&lt;/b&gt;	0xb77c54ad	0x00000000	0x00000000
0xbfe550a8:	0x0000000b	0xb75c3438	0xb77c5449	0xb782199c
0xbfe550b8:	&lt;b&gt;0xbfe550c8&lt;/b&gt;	0xb77bb7dd	0xb782199c	0x0000000b
0xbfe550c8:	&lt;b&gt;0xbfe550e8&lt;/b&gt;	0xb77bb84e	0x0000ffff	0xb789a240
0xbfe550d8:	0x00000000	0xb77bb830	0xb77bb839	0xb782199c
0xbfe550e8:	&lt;b&gt;0xbfe55108&lt;/b&gt;	0xb77bc08f	0x0000000b	0x00000000
0xbfe550f8:	0x00000000	0x00000010	0xb75c1ff4	0x3efafafb
0xbfe55108:	&lt;b&gt;0xbfe556c8&lt;/b&gt;	0xb7886400	0x0000000b	0x00000033
&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;The values in bold are the frame pointers, forming a linked list back up the stack.  If you compiled with &lt;tt&gt;-fomit-frame-pointer&lt;/tt&gt; things will be harder to figure out.  In this case it certainly doesn't look like the stack is corrupt.  Perhaps gdb is just confused.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Pick a location slightly further up the stack and set the &lt;tt&gt;$sp&lt;/tt&gt; variable, and suddenly backtrace works!&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;(gdb) set $sp=0xbfe55048
(gdb) bt
#0  0xb7886424 in __kernel_vsyscall ()
#1  0xb782199c in ?? () from /usr/lib/libSDL-1.2.so.0
#2  0xb7818736 in ?? () from /usr/lib/libSDL-1.2.so.0
#3  0xb77c54ad in ?? () from /usr/lib/libSDL-1.2.so.0
#4  0xb77bb7dd in SDL_QuitSubSystem () from /usr/lib/libSDL-1.2.so.0
#5  0xb77bb84e in SDL_Quit () from /usr/lib/libSDL-1.2.so.0
#6  0xb77bc08f in ?? () from /usr/lib/libSDL-1.2.so.0
#7  &lt;signal handler="handler" called="called"&gt;
#8  0xb74ede80 in ?? () from /lib/i686/cmov/libc.so.6
#9  0xb74efc8c in malloc () from /lib/i686/cmov/libc.so.6
#10 0xb7764eec in ?? () from /usr/lib/libSDL_mixer-1.2.so.0
#11 0xb7765b98 in Mix_SetPanning () from /usr/lib/libSDL_mixer-1.2.so.0
#12 0x080828b1 in I_SDL_StartSound (id=-1218694088, channel=-1218699276, 
    vol=120, sep=38) at i_sdlsound.c:671
#13 0x08073e9b in S_StartSound (origin_p=0xb624f990, sfx_id=22)
    at s_sound.c:656
#14 0x08061459 in T_MoveFloor (floor=0xb63271b8) at p_floor.c:220
#15 0x0806d0ea in P_RunThinkers () at p_tick.c:119
#16 0x0806d161 in P_Ticker () at p_tick.c:153
#17 0x08052fb6 in G_Ticker () at g_game.c:1151
#18 0x0804dbf4 in D_DoomLoop () at d_main.c:437
#19 0x0804ecc0 in D_DoomMain () at d_main.c:1506
#20 0x08054d1c in main (argc=5, argv=0xbfe55d04) at i_main.c:152
&lt;/blockquote&gt;&lt;/pre&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:19450</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/19450.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=19450"/>
    <title>Most absurd CMOS battery ever?</title>
    <published>2010-09-06T11:16:19Z</published>
    <updated>2011-12-14T13:28:20Z</updated>
    <content type="html">I have a &lt;a href="http://www.zone6400.com/" rel="nofollow"&gt;Performa 6400&lt;/a&gt; PowerMac, which I bought off &lt;a href="http://andylandy.livejournal.com/"&gt;a friend&lt;/a&gt; several years ago.  It runs Linux and I use it for portability testing (as it's a big endian machine).  Considering its age, it's not surprising that the battery for the onboard clock ran out years ago.  It's not a huge problem, but it's certainly annoying to have &lt;i&gt;make&lt;/i&gt; complain about modification dates in the future, and be confronted with "filesystem has not been checked for 19370 days" on boot-up.  So I decided to replace the battery.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;a href="http://www.laptopsolutions.net/840-rayovac.htm" rel="nofollow"&gt;This is the battery&lt;/a&gt; that is supposed to go in it.  Almost £15 for a battery!  This seemed far too expensive to me, so I set out to find an alternative. Unfortunately 4.5 volt batteries are rather uncommon.  However, I managed to find this, which was listed as a "lantern battery" used for torches, bike lamps and doorbells.  I suspect that there are probably 3 AA batteries inside:&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;a href="http://www.soulsphere.org/img/blog/absurd-cmos/01-battery-comparison.jpg" rel="nofollow"&gt;&lt;img src="http://www.soulsphere.org/img/blog/absurd-cmos/01sm-battery-comparison.jpg"&gt;&lt;/a&gt;&lt;br&gt;&lt;br /&gt;- Greencell 312G 4.5V lantern battery alongside the original (depleted) CMOS battery.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;I did a quick sanity check of the old battery to make sure I had the polarity right.  The voltage is down to 1V:&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;a href="http://www.soulsphere.org/img/blog/absurd-cmos/02-battery-voltage.jpg" rel="nofollow"&gt;&lt;img src="http://www.soulsphere.org/img/blog/absurd-cmos/02sm-battery-voltage.jpg"&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;All that needs to be done now is to connect the connector from the old battery to the new one. I've always been hopeless at soldering, but fortunately this is a job that is simple enough for sellotape.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;a href="http://www.soulsphere.org/img/blog/absurd-cmos/05-hacked-battery" rel="nofollow"&gt;&lt;img src="http://www.soulsphere.org/img/blog/absurd-cmos/05sm-hacked-battery.jpg"&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;This is the logic board from the Mac.  I've maxed out the RAM and added PCI Ethernet and USB cards. The black square at the bottom left is where the battery is supposed to be attached (it has a velcro strip at the back).&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;a href="http://www.soulsphere.org/img/blog/absurd-cmos/03-logic-board.jpg" rel="nofollow"&gt;&lt;img src="http://www.soulsphere.org/img/blog/absurd-cmos/03sm-logic-board.jpg"&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Obviously this is far too small for the new battery, and the card slides into the back of the machine, mounted vertically.  It has to be attached to the board somehow.  Where can it go?&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;a href="http://www.soulsphere.org/img/blog/absurd-cmos/04-new-battery.jpg" rel="nofollow"&gt;&lt;img src="http://www.soulsphere.org/img/blog/absurd-cmos/04sm-new-battery.jpg"&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Fortunately, the engineers at Apple were apparently smart enough to anticipate this very problem, and designed a convenient space on the riser card to put the battery in.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:19131</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/19131.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=19131"/>
    <title>Interview with me</title>
    <published>2010-07-29T21:01:22Z</published>
    <updated>2010-07-29T21:01:22Z</updated>
    <content type="html">&lt;a href="http://fragorama.se/" rel="nofollow"&gt;fragorama.se&lt;/a&gt; is a new website about Classic Doom, and they have just published an &lt;a href="http://fragorama.se/?p=104" rel="nofollow"&gt;interview&lt;/a&gt; with me!</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:18803</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/18803.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=18803"/>
    <title>Southampton Test Hustings</title>
    <published>2010-05-02T18:31:39Z</published>
    <updated>2011-12-14T13:39:07Z</updated>
    <content type="html">I just attended the &lt;a href="http://southampton.myvillage.com/news/join-southampton-candidates-for-hustings-debates?utm_source=twitterfeed&amp;amp;utm_medium=twitter" rel="nofollow"&gt;Hustings&lt;/a&gt; for Southampton Test.  These are my thoughts on some of the candidates.&lt;br /&gt;&lt;br /&gt;Alan Whitehead (incumber Labour MP): Seemed rather nervous at the start but gained confidence later in the debate.  To his credit he made some good points; I was impressed that he was bold enough to state that the law of the land should trump religious beliefs.  However I also got the impression that he was less up to speed with other candidates on local issues and perhaps hadn't been paying proper attention to his constituency. Surprisingly enough he opposes Trident in favour of a cruise missile system like the LibDems advocate.&lt;br /&gt;&lt;br /&gt;Jeremy Moulton (Conservatives): Made some good points and seemed a confident speaker.  Some of the answers he gave seemed to have been slighty evasive/misleading when audience members responded to his answers.  Attacked Alan Whitehead for using the communications allowance and supposedly putting the Labour party name on it (?)&lt;br /&gt;&lt;br /&gt;Dave Callaghan (Liberal Democrats): Seemed the most honest of the lot. He highlighted some of the local issues that he's been campaigning for, like the closure of the Millbrook library, which he attacked Jeremy on (Jeremy is responsible for finances on the local council?). &lt;br /&gt;&lt;br /&gt;Pearline Hingston (UKIP): A UKIP candidate who is an immigrant (how's that for a brain-breaker?).  She came across as completely clueless and in general contributed very little of note.  The one time she really attempted to express an opinion on something (cyclists riding on the pavement) she got smacked down by a member of the audience in response for not having a clue what she was talking about.&lt;br /&gt;&lt;br /&gt;Chris Bluemel (Green): Surprisingly clueful and well-spoken. He spoke out in favour of nuclear disarmament and did it well, even though I don't agree with his views.&lt;br /&gt;&lt;br /&gt;During the debates I sat next to an older gentleman who spent the time scribbling down notes on the back of an envelope.  When he asked a question to the panel, he made some strange comments about Halliburton and BP. He seemed to think that there were plans to site nuclear submarines in Southampton docks, and was worried they might blow up and destroy the city. Very odd.&lt;br /&gt;&lt;br /&gt;There was an obvious large Christian presence in the audience, and I suspect that siting the debate in a church probably didn't help.  The candidates were asked at one point why they had all refused to sign a petition (I forget the name of it) declaring their support for Christian beliefs, although it was then revealed that none of the candidates had even heard of it.  Several questions were asked about Christian rights that were obviously homophobic (eg. anti-gay marriage), though the people posing the questions tried to veil this by speaking in vague terms that made it less obvious what they were talking about.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:18531</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/18531.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=18531"/>
    <title>Twitter</title>
    <published>2010-04-29T11:53:20Z</published>
    <updated>2011-12-14T13:40:21Z</updated>
    <content type="html">I now have a &lt;a href="http://twitter.com/fraggletastic" rel="nofollow"&gt;Twitter&lt;/a&gt; account.  You will find regular postings there about completely irrelevant things. I'm tagging Chocolate Doom-related postings with the &lt;a href="http://twitter.com/#search?q=%23chocdoom" rel="nofollow"&gt;#chocdoom&lt;/a&gt; tag.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:18339</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/18339.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=18339"/>
    <title>Chocolate Doom on OS X, and GNUstep</title>
    <published>2010-02-05T13:19:11Z</published>
    <updated>2011-12-14T13:38:27Z</updated>
    <content type="html">&lt;a href="http://www.chocolate-doom.org/" rel="nofollow"&gt;Chocolate Doom&lt;/a&gt; runs on Mac OS X and has done for several years; however, until now, getting it running has been overly complicated and required compiling the source code from scratch.  Obviously this isn't really appropriate for a Mac; it certainly doesn't fit in with the Apple way of doing things.  I recently set about trying to improve the situation.&lt;br /&gt;&lt;br /&gt;I first investigated how things are installed on OS X.  Generally speaking there are two ways that things are installed; the &lt;a href="http://en.wikipedia.org/wiki/Installer_(Mac_OS_X)" rel="nofollow"&gt;installer&lt;/a&gt; (.pkg files), and &lt;a href="http://en.wikipedia.org/wiki/Application_Bundle" rel="nofollow"&gt;Application Bundles&lt;/a&gt;, typically contained inside a .dmg archive.  The installer simply installs a bunch of files to your machine, while Application Bundles are a lot more fluid; to install, you simply drag an icon into the Applications folder.&lt;br /&gt;&lt;br /&gt;Application Bundles seem obviously preferable, but there's the problem of how one should be structured.  Chocolate Doom needs a Doom IWAD file that contains the data used by the game, so it's not sufficient to simply package the normal binary as a bundle. Then there's the setup tool as well - should that be in a separate bundle?  Finally, people often like to load PWAD files containing extra levels and mods.  How do you do that with a bundle?&lt;br /&gt;&lt;br /&gt;In the end, I decided to write a minimalist launcher program.  Everything is in a single bundle file which, when launched opens a launcher window.  The launcher allows the locations of the IWAD files to be configured and extra command line parameters entered.  There's also a button to open the setup tool.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.chocolate-doom.org/wiki/images/5/5b/OS_X_Launcher.png"&gt;&lt;br /&gt;&lt;br /&gt;The launcher also sets up file associations when installed, so that it is possible to double-click a WAD file in the Finder, and an appropriate command line is constructed to load it.  The interface is not as fully-featured as other "launcher" programs are, but it's simple and I think fits with the philosophy of the project.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt; Developing with GNUstep &lt;/h3&gt;&lt;br /&gt;The interesting part is how I developed the launcher.  I only have occasional use of a Mac, so I developed it on &lt;a href="http://www.gnustep.org/" rel="nofollow"&gt;GNUstep&lt;/a&gt;.  This is an earlier version of the launcher interface while it was under development:&lt;br /&gt;&lt;img src="http://www.soulsphere.org/img/screenshots/gnustep-launcher.png"&gt;&lt;br /&gt;GNUstep provides an implementation of the same Objective C API that OS X's Cocoa provides, albeit with a rather crufty-looking &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/NeXTStep" rel="nofollow"&gt;NeXTStep&lt;/a&gt; appearance.  It also has &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Gorm_(computing)" rel="nofollow"&gt;Gorm&lt;/a&gt;, which works in a very similar way to OS X's Interface Builder application.  Using GNUstep, I was able to mock up a working program relatively easy.  Constructing interfaces is very straightforward: the controls are simply dragged-and-dropped onto a window.  I was able to get the underlying code into a working state before porting to OS X.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt; Porting to OS X &lt;/h3&gt;&lt;br /&gt;Porting to OS X had some hassles.  Firstly, Gorm/GNUstep uses its own native format for interface files, which are different to the .nibs used on OS X.  Recent versions of Gorm can save .nibs, but I found that the program crashed when I tried to do this.  I eventually just reconstructed the whole interface from scratch in Interface Builder.  GNUstep can use .nibs, so I just threw the older Gorm interface away.&lt;br /&gt;&lt;a href="http://www.chocolate-doom.org/wiki/index.php/Image:OS_X_Launcher_GNUstep.png" rel="nofollow"&gt;&lt;img src="http://www.chocolate-doom.org/wiki/images/thumb/c/c7/180px-OS_X_Launcher_GNUstep.png"&gt;&lt;/a&gt;&lt;br /&gt;The other main annoyance was that the format for &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Property_list" rel="nofollow"&gt;property lists&lt;/a&gt; is different on OS X.  It seems that GNUstep uses the older NeXT format, which Apple have since replaced with a newer XML-based format. Finally, icon files on OS X are in a proprietary .icns format, while GNUstep simply uses PNGs.&lt;br /&gt;&lt;br /&gt;Both OS X and GNUstep try to force you to use their build tools (Xcode, ProjectCenter) which seem to generate a whole load of junk.  I wrote a &lt;a href="http://chocolate-doom.svn.sourceforge.net/viewvc/chocolate-doom/trunk/chocolate-doom/pkg/osx/GNUmakefile" rel="nofollow"&gt;Makefile&lt;/a&gt; instead. There are some conditional parts to handle the two systems - OS X and GNUstep application bundles have different internal structures, for example.  On OS X, the Makefile will do the complete process of compiler code, constructing the application bundle and generating a .dmg archive.&lt;br /&gt;&lt;br /&gt;One thing I did find interesting is how OS X handles libraries.  The full paths to any .dylib libraries (which are like Linux .so files or Windows DLLs) are stored inside a program when it is compiled.  In my case, my application bundle needs to include the SDL libraries that Chocolate Doom depends upon.  There's a convenient program called &lt;a href="http://developer.apple.com/Mac/library/documentation/Darwin/Reference/ManPages/man1/install_name_tool.1.html" rel="nofollow"&gt;install_name_tool&lt;/a&gt; that can be used to change these paths after the program has been compiled.  A special macro called @executable_path can be used to mean "the path where this binary is".  I wrote a &lt;a href="http://chocolate-doom.svn.sourceforge.net/viewvc/chocolate-doom/trunk/chocolate-doom/pkg/osx/cp-with-libs" rel="nofollow"&gt;script&lt;/a&gt; to copy a program along with any libraries it depends on, changing its library search paths appropriately.&lt;br /&gt;&lt;br /&gt;As one last finishing touch, there's a "Command Line..." menu item that calls into Terminal.app to open a command line window, if you're of the type who prefers the command line.  The window sets up the PATH to point to the directory within the package that contains the chocolate-doom binary, and also sets up DOOMWADPATH to point to all the IWAD files you've configured within the GUI.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt; Thoughts on GNUstep &lt;/h3&gt;&lt;br /&gt;GNUstep was certainly incredibly useful in this activity; the ability to develop the program on my usual (Linux) laptop was very convenient.  From a technical perspective, GNUstep seems to be a very impressive project.  There is great usefulness in having a Linux implementation of the OPENSTEP (ie. Cocoa) API, which is what GNUstep is. However, the NeXT-style interface clashes horribly with almost any desktop environment that you might want to run under Linux (Gnome/KDE/etc), which is a huge turn-off.&lt;br /&gt;&lt;br /&gt;The main problems are (1) the mini-window icons (which represent the running application) and (2) the menus, which appear in a separate window to the other application windows.  I expect these are things that I could get used to if I was running a full GNUstep desktop where everything was like this; however, I'm not and it wouldn't really be practical for me to do so.  It is possible to theme GNUstep to look nicer than its default "ugly grey square" appearance, but these problem remain.&lt;br /&gt;&lt;br /&gt;GNUstep is a frustrating project in this respect. I can't help wonder if the full potential of the project is limited by the short-sightedness of its developers. It seems like they're too hung up on their goal of recreating NeXTstep, when I doubt there are many people who would even want to use such a system nowadays. &lt;a href="http://wiki.gnustep.org/index.php/Developer_FAQ#How_about_implementing_parts_of_the_Application_Kit_with_GTK.3F" rel="nofollow"&gt;This&lt;/a&gt; entry from the developer FAQ gives a good example of what I'm talking about:&lt;br /&gt;&lt;blockquote&gt;&lt;b&gt;How about implementing parts of the Application Kit with GTK?&lt;/b&gt;&lt;br /&gt;&lt;i&gt;Yes and No - The GNUstep architecture provides a single, platform-independent, API for handling all aspects of GUI interaction (implemented in the gstep-gui library), with a backend architecture that permits you to have different display models (display postscript, X-windows, win32, berlin ...) while letting you use the same code for printing as for displaying. Use of GTK in the frontend gui library would remove some of those advantages &lt;b&gt;without adding any&lt;/b&gt;.&lt;/i&gt;&lt;/blockquote&gt;&lt;br /&gt;"Without adding any [advantages]" - except, of course, the ability to give GNUstep applications an appearance that is consistent with 99% of Linux desktops!  If it &lt;i&gt;was&lt;/i&gt; possible to use GNUstep to make applications that looked like Gtk+ apps, I bet it would be a lot more attractive to developers. The practical advantages of such a decision are dismissed completely in the face of architectural/technical advantages that probably have little practical use.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:18071</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/18071.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=18071"/>
    <title>How to make a program just run</title>
    <published>2009-12-10T13:05:58Z</published>
    <updated>2011-12-14T13:31:28Z</updated>
    <content type="html">Starting with Windows Vista, Windows limits the privileges that are given to normal users, running programs as the Administrator user only when necessary.  To smooth over the fact that  install programs for most software need to run as Administrator, it uses heuristics to detect whether a program is an installer.  One of these is to look at the file name - if it contains &amp;quot;setup&amp;quot; in the name (among others), it is treated as an installer.&lt;br /&gt;&lt;br /&gt;This is a problem if you develop &lt;a href="http://www.chocolate-doom.org/wiki/index.php/Textscreen" rel="nofollow"&gt;a program&lt;/a&gt; that is not an installer but has &amp;quot;&lt;a href="http://doom.wikia.com/wiki/Setup_program" rel="nofollow"&gt;setup&lt;/a&gt;&amp;quot; in the name, because Windows treats it as though it is an installer and prompts you for administrator privileges. &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;User Account Control&lt;/h3&gt;&lt;br /&gt;The first problem is that it prompts the user for administrator privileges.  This is part of the &lt;a href="http://en.wikipedia.org/wiki/User_Account_Control" rel="nofollow"&gt;User Account Control&lt;/a&gt; system.  Fortunately, there's a way around this - it's possible to embed a special &amp;quot;manifest&amp;quot; XML file inside the EXE that tells Windows that Administrator privileges aren't necessary.&lt;br /&gt;&lt;br /&gt;Here's the magic manifest file to do this:&lt;blockquote&gt;&lt;pre&gt;

&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;yes&amp;quot;?&amp;gt;

&amp;lt;assembly xmlns=&amp;quot;urn:schemas-microsoft-com:asm.v1&amp;quot; manifestVersion=&amp;quot;1.0&amp;quot;&amp;gt;
  &amp;lt;assemblyIdentity version=&amp;quot;0.0.0.0&amp;quot; processorArchitecture=&amp;quot;X86&amp;quot;
                    name=&amp;quot;foo.exe&amp;quot; type=&amp;quot;win32&amp;quot;/&amp;gt;
  &amp;lt;trustInfo xmlns=&amp;quot;urn:schemas-microsoft-com:asm.v3&amp;quot;&amp;gt;
    &amp;lt;security&amp;gt;
      &amp;lt;requestedPrivileges&amp;gt;
        &amp;lt;requestedExecutionLevel level=&amp;quot;asInvoker&amp;quot; uiAccess=&amp;quot;false&amp;quot; /&amp;gt;
      &amp;lt;/requestedPrivileges&amp;gt;
    &amp;lt;/security&amp;gt;
  &amp;lt;/trustInfo&amp;gt;
&amp;lt;/assembly&amp;gt;
&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;The important part here is the &amp;quot;requestedExecutionLevel&amp;quot; statement, that specifies to run the program as the invoker.  I think the &amp;quot;uiAccess&amp;quot; element is necessary as well.  I'm not entirely sure what this control does, and there are some people who say &lt;a href="http://blogs.msdn.com/cjacks/archive/2009/10/15/using-the-uiaccess-attribute-of-requestedexecutionlevel-to-improve-applications-providing-remote-control-of-the-desktop.aspx" rel="nofollow"&gt;it should be set to true&lt;/a&gt;.  However, it seems that if set to true, the executable has to be digitally signed with a certificate, which all looks like a massive hassle, so I've just left it turned off.&lt;br /&gt;&lt;br /&gt;The "assemblyIdentity" tag here matches the executable name, but I'm not sure it's actually necessary.  The version number is a dummy value.&lt;br /&gt;&lt;br /&gt;Embedding it inside an executable is a matter of writing a resource file containing a statement to include the manifest file.  Here's the magic statement for that:&lt;br /&gt;&lt;blockquote&gt;&lt;code&gt;1 24 MOVEABLE PURE &amp;quot;setup-manifest.xml&amp;quot;&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;The resource file is then compiled to a .o (using windres) and incorporated into the build.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Compatibility Assistant&lt;/h3&gt;&lt;br /&gt;So far, so good.  If the above is done properly, Windows won't prompt to run the program with administrator privileges any more.  However, that's not the end of the story.  Windows still thinks the program is an installer, just an installer that &lt;i&gt;doesn't need administrator privileges&lt;/i&gt;.  The next problem is the &amp;quot;Program Compatibility Assistant&amp;quot;.&lt;br /&gt;&lt;br /&gt;If your program exits without writing any files to disk (in Chocolate Setup, it's possible to quit without saving configuration file changes, for example), the compatibility assistant appears.  Because Windows thinks the program is an installer, and it hasn't written any files to disk, it assumes that something must have gone wrong with installation, and it might be a compatibility problem with a program designed for an older version of Windows.  The assistant is supposed to help you resolve the problems you've encountered.&lt;br /&gt;&lt;br /&gt;To work around this requires an addition to the manifest file to state that Vista (and Windows 7) are supported OSes; therefore, if no files are written, it's no problem.  Here's the new version of the manifest:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;yes&amp;quot;?&amp;gt;

&amp;lt;assembly xmlns=&amp;quot;urn:schemas-microsoft-com:asm.v1&amp;quot; manifestVersion=&amp;quot;1.0&amp;quot;&amp;gt;
  &amp;lt;assemblyIdentity version=&amp;quot;0.0.0.0&amp;quot; processorArchitecture=&amp;quot;X86&amp;quot;
                    name=&amp;quot;foo.exe&amp;quot; type=&amp;quot;win32&amp;quot;/&amp;gt;
  &amp;lt;trustInfo xmlns=&amp;quot;urn:schemas-microsoft-com:asm.v3&amp;quot;&amp;gt;
    &amp;lt;security&amp;gt;
      &amp;lt;requestedPrivileges&amp;gt;
        &amp;lt;requestedExecutionLevel level=&amp;quot;asInvoker&amp;quot; uiAccess=&amp;quot;false&amp;quot; /&amp;gt;
      &amp;lt;/requestedPrivileges&amp;gt;
    &amp;lt;/security&amp;gt;
  &amp;lt;/trustInfo&amp;gt;

&lt;b&gt;  &amp;lt;!-- Stop the Program Compatibility Assistant appearing: --&amp;gt;

  &amp;lt;compatibility xmlns=&amp;quot;urn:schemas-microsoft-com:compatibility.v1&amp;quot;&amp;gt;
    &amp;lt;application&amp;gt;
      &amp;lt;supportedOS Id=&amp;quot;{35138b9a-5d96-4fbd-8e2d-a2440225f93a}&amp;quot;/&amp;gt; &amp;lt;!-- 7 --&amp;gt;
      &amp;lt;supportedOS Id=&amp;quot;{e2011457-1546-43c5-a5fe-008deee3d3f0}&amp;quot;/&amp;gt; &amp;lt;!-- Vista --&amp;gt;
    &amp;lt;/application&amp;gt;
  &amp;lt;/compatibility&amp;gt; &lt;/b&gt;
&amp;lt;/assembly&amp;gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt; References &lt;/h3&gt;&lt;ul&gt;&lt;li&gt; &lt;a href="http://www.cygwin.com/ml/cygwin/2006-12/msg00580.html" rel="nofollow"&gt;The same problem as it occurred in Cygwin&lt;/a&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="http://msdn.microsoft.com/en-us/library/dd371711%28VS.85%29.aspx" rel="nofollow"&gt;Microsoft documentation on manifest files and compatibility&lt;/a&gt;&lt;br /&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:17838</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/17838.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=17838"/>
    <title>Python's braindamaged scoping rules</title>
    <published>2009-05-07T11:37:54Z</published>
    <updated>2009-05-07T11:37:54Z</updated>
    <content type="html">Python distinguishes between local and global variables from assignment statements.  If a variable is assigned within a function, that variable is treated as a local variable.  This means that you cannot do this:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;
my_var = None

def set_my_var():
    my_var = "hello world"

set_my_var()
print my_var
&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;As &lt;i&gt;my_var&lt;/i&gt; is assigned within the function, it is treated as a local variable that is separate to the global variable with the same name.  Instead, you have to explicitly tell the compiler that you want to assign the global variable, like this:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;
my_var = None

def set_my_var():
    &lt;b&gt;global my_var&lt;/b&gt;
    my_var = "hello world"

set_my_var()
print my_var
&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;This all strikes me as rather brain-damaged.  If assignments are used to detect the declaration of a variable, is it really so difficult to just examine the surrounding context to see if there is already a variable with the same name?</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:17509</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/17509.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=17509"/>
    <title>Creative defacement</title>
    <published>2009-04-30T22:38:23Z</published>
    <updated>2011-12-14T13:40:59Z</updated>
    <content type="html">Something funny I saw attached to a sign on the car park down the road from my flat:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.soulsphere.org/img/cctv-eyes.jpg" rel="nofollow"&gt;&lt;img src="http://www.soulsphere.org/img/cctv-eyes-small.jpg"&gt;&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:17181</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/17181.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=17181"/>
    <title>IPv6</title>
    <published>2009-03-20T22:03:27Z</published>
    <updated>2011-12-14T13:29:51Z</updated>
    <content type="html">&lt;a href=""&gt;IPv6&lt;/a&gt; is something that I've been interested in for a while; I was even &lt;a href="http://www.soulsphere.org/hacks/ipv6/" rel="nofollow"&gt;employed&lt;/a&gt; to do some v6 porting work a few years ago.  Unfortunately, even though it's been several years and &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/IPv4_address_exhaustion" rel="nofollow"&gt;address exhaustion is rapidly approaching&lt;/a&gt;, uptake remains slow.&lt;br /&gt;&lt;br /&gt;As I see it there are several problems with IPv6 adoption:&lt;br /&gt;&lt;ol&gt;&lt;li&gt; Software doesn't support it&lt;br /&gt;&lt;li&gt; Hardware doesn't support it&lt;br /&gt;&lt;li&gt; ISPs don't provide it&lt;/ol&gt;&lt;br /&gt;As these go, (1) isn't actually that big a problem now.  A lot of the most important software already supports v6.  Ubuntu/Debian seems to just work with IPv6 (and presumably other Linux distributions as well), and even Windows supports it by default &lt;a href="http://www.microsoft.com/technet/network/ipv6/ipv6faq.mspx" rel="nofollow"&gt;as of Vista&lt;/a&gt; (there's also a downloadable package for XP).  Software packages like Firefox work out of the box.&lt;br /&gt;&lt;br /&gt;(2) is still a big issue for a lot of hardware but I suspect that there's a lot of hardware now that supports it, but has it turned off (routers, etc).  (3) is simply a fact; I haven't heard of any ISPs supporting v6, and I suspect a lot of that is dependent on (2).&lt;br /&gt;&lt;br /&gt;&lt;h3&gt; 6to4 &lt;/h3&gt;&lt;br /&gt;&lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/6to4" rel="nofollow"&gt;6to4&lt;/a&gt; (not to be confused with &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/6in4" rel="nofollow"&gt;6in4&lt;/a&gt; or &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/6over4" rel="nofollow"&gt;6over4&lt;/a&gt;, thanks for the clear naming, guys), is in my opinion an excellent piece of engineering and exactly what is needed to fuel IPv6 adoption.  It solves the hardware/ISP problems by tunneling v6 traffic over v4; however, the clever part about it is that it does this without the need to register an account with a tunnel provider or explicitly configure it.  I first became aware of 6to4 when I heard that the Apple Extreme base station has it enabled by default, which I think demonstrates its potential; it's possible to circumvent the remaining hardware/ISP problems with IPv6 just by getting manufacturers of broadband routers to adopt 6to4.&lt;br /&gt;&lt;br /&gt;With 6to4, tunnels are made &lt;i&gt;opportunistically&lt;/i&gt; between v4 addresses, which means that if you have two machines using 6to4, they can communicate directly, without the overhead that routing through a third party would cause (If this sounds a bit pointless, consider that it means two machines both behind NAT gateways in the v4 world can have end-to-end connectivity in the v6 world). Any other v6 data is sent to a magic &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Anycast" rel="nofollow"&gt;anycast&lt;/a&gt; address that automatically routes v6 data to the closest v6 gateway.&lt;br /&gt;&lt;br /&gt;With 6to4, a machine has an IPv6 address range that is derived from its public IPv4 address.  For example, if your IPv4 address is 1.2.3.4, your IPv6 subnet range is 2002:0102:0304::/48.  IPv6 traffic for that range automatically gets sent to that IPv4 address. What really happens is that your 6to4-enabled broadband router assigns addresses from this range to machines on your home LAN.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt; Setting up 6to4 &lt;/h3&gt;&lt;br /&gt;My DSL router doesn't support 6to4; however, I managed to work around this. My router &lt;i&gt;does&lt;/i&gt; support port forwarding (actually, protocol forwarding in this case), and I have a Linux machine in my lounge that I use as a media centre/server.&lt;br /&gt;&lt;br /&gt;The first step was to set up a rule on the router to forward 6to4 data to the server machine.	I have a &lt;a href="http://corz.org/comms/hardware/router/bt.voyager.205_router.how-to.php" rel="nofollow"&gt;BT Voyager&lt;/a&gt; router which is helpfully quite flexible in this respect. 6to4 data is IP traffic with a protocol number of 41. From the router's command line interface, this did the job:&lt;br /&gt;&lt;blockquote&gt;&lt;tt&gt;&lt;br /&gt;create nat rule entry ruleid 41416 rdr prot num 41 lcladdrfrom 192.168.1.6 lcladdrto 192.168.1.6 &lt;br /&gt;&lt;/tt&gt;&lt;/blockquote&gt;&lt;br /&gt;It was then a case of configuring the server to do 6to4.  As it is running Ubuntu, I added this to &lt;tt&gt;/etc/network/interfaces&lt;/tt&gt;:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;
iface tun6to4 inet6 v4tunnel
	address 2002:0102:0304::1
	netmask 16
	endpoint any
	local 192.168.1.6
	ttl 255
	remote 192.88.99.1
	post-up ip -6 route add 2000::/3 via ::192.88.99.1 dev tun6to4
	post-down ip -6 route flush dev tun6to4

auto tun6to4
&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;A simple "&lt;tt&gt;sudo ifup tun6to4&lt;/tt&gt;" and the tunnel device should come up.  It should then be possible to ping IPv6 addresses:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;
$ ping6 ipv6.google.com
PING ipv6.google.com(2001:4860:a003::68) 56 data bytes
64 bytes from 2001:4860:a003::68: icmp_seq=1 ttl=61 time=53.8 ms
64 bytes from 2001:4860:a003::68: icmp_seq=2 ttl=61 time=52.5 ms
64 bytes from 2001:4860:a003::68: icmp_seq=3 ttl=61 time=45.5 ms
64 bytes from 2001:4860:a003::68: icmp_seq=4 ttl=61 time=51.5 ms
&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt; Routing &lt;/h3&gt;&lt;br /&gt;At this point, the server has IPv6 connectivity, but what I really want is every machine on the network to have it.  So the next step is to set up the server as an IPv6 router.&lt;br /&gt;&lt;br /&gt;To do this, other machines need to know that the server is a router and acquire IPv6 addresses.  In IPv4, this is usually done with a &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/DHCP" rel="nofollow"&gt;DHCP server&lt;/a&gt; handing out addresses from a pool.  Instead, with IPv6, routers &lt;i&gt;advertise&lt;/i&gt; their address ranges, and the clients automatically construct an address.  This is possible because of the vast address range in IPv6.&lt;br /&gt;&lt;br /&gt;A package called &lt;tt&gt;radvd&lt;/tt&gt; (router advertisement daemon) sends router advertisements.  It's in the Debian package repository and very easy to configure.  This is my &lt;tt&gt;/etc/radvd.conf&lt;/tt&gt; file:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;
interface eth0
{
	AdvSendAdvert on;
	prefix 2002:0102:0304:face::/64
	{
		AdvOnLink on;
		AdvAutonomous on;
		AdvRouterAddr on;
	};
};
&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;Notice that I've defined a subnet range for clients.  The address range given by 6to4 is 2002:0102:0304::/48, while radvd assigns addresses in the 2002:0102:0304:face::/64 range.  Next, I statically assign an address in this range in &lt;tt&gt;/etc/network/interfaces&lt;/tt&gt; by adding this:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;
iface eth0 inet6 static
        address 2002:0102:0304:face::1
	netmask 64
&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;Now the router advertisements are handing out v6 addresses to other machines on the network, and the server has an address within the subnet range to communicate with them.  It's then just a matter of turning on routing.  Add this to &lt;tt&gt;/etc/sysctl.conf&lt;/tt&gt;:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.default.forwarding=1
&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;Or to make it take effect immediately:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;
sudo sysctl net.ipv6.conf.all.forwarding=1
sudo sysctl net.ipv6.conf.default.forwarding=1
&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;That's it!  Here's the output from &lt;tt&gt;ifconfig&lt;/tt&gt; on another machine on my network:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;
wlan0     Link encap:Ethernet  HWaddr 00:1c:10:63:63:d0
          inet addr:192.168.1.25  Bcast:192.168.1.255  Mask:255.255.255.0
          &lt;b&gt;inet6 addr: 2002:0102:0304:face:21c:10ff:fe63:63d0/64 Scope:Global&lt;/b&gt;
          inet6 addr: fe80::21c:10ff:fe63:63d0/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:7658 errors:0 dropped:0 overruns:0 frame:0
          TX packets:7228 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:4073660 (4.0 MB)  TX bytes:903010 (903.0 KB)
&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;And here's Google IPv6:&lt;br /&gt;&lt;blockquote&gt;&lt;a href="http://www.soulsphere.org/img/screenshots/ipv6-google.png" rel="nofollow"&gt;&lt;br /&gt;&lt;img src="http://www.soulsphere.org/img/screenshots/ipv6-google-thumb.png"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;Note that in the examples above, I've obscured my 6to4 address range to 2002:0102:0304::, to hide my IPv4 address, for privacy.  If you want to follow my instructions, this needs to be replaced with your own public IPv4 address.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:16955</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/16955.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=16955"/>
    <title>Stock photos</title>
    <published>2009-02-13T13:07:45Z</published>
    <updated>2009-02-13T13:07:45Z</updated>
    <content type="html">BBC News' obsession with filling their articles with stock photos that contain no relevant information is &lt;a href="http://news.bbc.co.uk/1/hi/technology/7887577.stm?lss" rel="nofollow"&gt;reaching absurd extremes&lt;/a&gt;.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:16486</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/16486.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=16486"/>
    <title>ebay</title>
    <published>2009-01-20T01:15:28Z</published>
    <updated>2009-01-20T01:15:28Z</updated>
    <content type="html">Buying things on eBay became more fun once I started &lt;a href="http://feedback.ebay.co.uk/ws/eBayISAPI.dll?ViewFeedback2&amp;amp;userid=fraggle_uk_uk&amp;amp;ftab=FeedbackLeftForOthers" rel="nofollow"&gt;getting creative&lt;/a&gt; with the feedback that I leave for people.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:16374</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/16374.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=16374"/>
    <title>12 inch pianist</title>
    <published>2009-01-19T20:17:48Z</published>
    <updated>2009-01-19T20:17:48Z</updated>
    <content type="html">&lt;a href="http://www.aarons-jokes.com/joke-168.shtml" rel="nofollow"&gt;For anyone who doesn't get&lt;/a&gt; &lt;a href="http://xkcd.com/532/" rel="nofollow"&gt;today's xkcd&lt;/a&gt; (I did, but there seem to be quite a few people who haven't heard that joke before).</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:15872</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/15872.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=15872"/>
    <title>The Buddha Lounge</title>
    <published>2008-12-23T00:11:29Z</published>
    <updated>2011-12-14T13:30:10Z</updated>
    <content type="html">The Indian restaurant opposite my house, which was called &lt;a href="http://www.natrajbalti.co.uk/Main/home/index.php" rel="nofollow"&gt;The Natraj&lt;/a&gt;, has reinvented itself as a trendy bar, called "The Buddha Lounge".  This is ironic on multiple levels.&lt;br /&gt;&lt;br /&gt;Firstly, the &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Five_Precepts" rel="nofollow"&gt;Five precepts&lt;/a&gt; of Buddhism forbid the consumption of alcohol or intoxicating substances. Secondly, the more strict &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Eight_precepts#Eight_Precepts" rel="nofollow"&gt;Eight precepts&lt;/a&gt; encourage followers to abstain from music and dancing, and also from all sexual activity (and the main purpose of these types of bar is basically to find willing sexual partners).  Finally, followers also refrain from "luxurious places for sitting or sleeping", so even the "lounge" part is out.&lt;br /&gt;&lt;br /&gt;What's next, the Jesus Casino?</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:15818</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/15818.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=15818"/>
    <title>Does this make me an Internet star?</title>
    <published>2008-09-26T01:04:47Z</published>
    <updated>2008-09-26T01:07:15Z</updated>
    <content type="html">I was reading the Wikipedia article about Ken Silverman's &lt;a href="http://en.wikipedia.org/wiki/PNGOUT" rel="nofollow"&gt;PNGOUT&lt;/a&gt;, which is a program for creating optimised versions of PNG images. However, it was the &lt;a href="http://en.wikipedia.org/wiki/Image:PNGOUT_Screenshot.PNG" rel="nofollow"&gt;screenshot&lt;/a&gt; in that article that intrigued me the most.  Upon further investigation, it seems that a group of Wikipedia users have been running a minor contest amongst themselves to create the most optimised version possible of an &lt;a href="http://en.wikipedia.org/wiki/Image:Sopwith-screenshot.png" rel="nofollow"&gt;image&lt;/a&gt; I originally uploaded three years ago. &lt;br /&gt;&lt;br /&gt;It's really weird when you stumble across things like this.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:15518</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/15518.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=15518"/>
    <title>c-algorithms 1.2.0</title>
    <published>2008-09-15T11:28:01Z</published>
    <updated>2008-09-15T11:31:03Z</updated>
    <content type="html">Version 1.2.0 of my C Algorithms library is &lt;a href="http://c-algorithms.sourceforge.net/" rel="nofollow"&gt;up&lt;/a&gt;. The biggest changes in this release are the improvements to the test suite.  I've written a bit about the &lt;a href="http://c-algorithms.sourceforge.net/testing.html" rel="nofollow"&gt;test process&lt;/a&gt; that I've been using for improving the library.&lt;br /&gt;&lt;br /&gt;Learning about coverage tools has been an interesting process.  I liken writing tests without using coverage analysis to trying to optimise code without doing any profiling. With optimisation, it's easy to pick something that you &lt;i&gt;think&lt;/i&gt; is a bottleneck and waste lots of time optimising it; in the same way, I've found that it's possible to write tests that you think are exercising the code in a satisfactory way, but actually aren't.  Profiling helps to show exactly what's going on. In the course of analysing the library, I found a bug that should have been shown up in the tests, but wasn't, because the tests weren't exercising all of the code as I assumed they were.&lt;br /&gt;&lt;br /&gt;Testing how code behaves in failure conditions is as important as testing how it behaves normally, so I wrote &lt;a href="http://c-algorithms.svn.sourceforge.net/viewvc/c-algorithms/tags/c-algorithms-1.2.0/test/alloc-testing.c?view=markup" rel="nofollow"&gt;some code&lt;/a&gt; that uses &lt;tt&gt;#define&lt;/tt&gt; macros to wrap the standard C allocation functions and allow the tests to simulate memory allocation failures. Again, coverage analysis is helpful here, too.&lt;br /&gt;&lt;br /&gt;All in all, I'm not entirely sure why I'm writing a data structures and algorithms library, considering that all of these things have already been implemented hundreds of times over by different people.  I originally wrote the library to remove the dependency of &lt;a href="http://irmo.sourceforge.net/" rel="nofollow"&gt;Irmo&lt;/a&gt; on GLib.  Since then it's taken on a life and direction of its own, probably due to my own slightly obsessive nature. I think I just like the process of crafting something to the highest quality I possibly can.&lt;br /&gt;&lt;br /&gt;(Also: Open source software with a test process? World coming to an end!)</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:15116</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/15116.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=15116"/>
    <title>New screensaver</title>
    <published>2008-09-09T00:11:17Z</published>
    <updated>2008-09-09T00:11:17Z</updated>
    <content type="html">&lt;a href="http://www.gridpp.ac.uk/cubes/5.jpg" rel="nofollow"&gt;Large Hadron Collider&lt;/a&gt; + &lt;a href="http://www.jwz.org/xscreensaver/screenshots/" rel="nofollow"&gt;GLeidoscope&lt;/a&gt; = &lt;a href="http://www.soulsphere.org/img/lhk.jpg" rel="nofollow"&gt;Large Hadron Kaleidoscope&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.soulsphere.org/img/lhk-thumbnail.jpg"&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:14879</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/14879.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=14879"/>
    <title>4 gigs of pain</title>
    <published>2008-08-04T11:59:27Z</published>
    <updated>2008-08-04T11:59:27Z</updated>
    <content type="html">We're rapidly reaching (or have reached?) the point where it's standard to have at least 4 gigabytes of RAM in desktop PCs.  This presents an interesting dilemma, because most people run 32 bit operating systems; 32 bits doesn't allow more than 4GB of RAM to be addressed.  The ideal alternative is to move to 64 bits; all modern CPUs support x86-64.  Unfortunately, it requires a massive porting effort to get everything working on x86-64 (drivers from third party vendors are likely to be the biggest problem), so we're not quite there yet.&lt;br /&gt;&lt;br /&gt;In the meantime, there's a useful feature called &lt;a href="http://en.wikipedia.org/wiki/Physical_Address_Extension" rel="nofollow"&gt;PAE&lt;/a&gt; which allows up to 64GB to be addressed by a 32 bit OS. I was surprised to see, however, that neither Windows XP or even Vista support it, although the server-based versions of Windows do!&lt;br /&gt;&lt;br /&gt;The cynic in me wondered if this was a deliberate attempt by Microsoft to stop people from using the normal desktop version of Windows for running big servers, but this seemed a bit too much, even for them.  But the Wikipedia article has the actual reason: "desktop versions of Windows (Windows XP, Windows Vista) limit physical address space to 4 GB for driver compatibility reasons". &lt;br /&gt;&lt;br /&gt;So poor Microsoft appear to be stuck between a rock and a hard place.  They cannot enable PAE, which is, in a sense, a backwards compatibility feature, because doing so would break driver backwards compatibility.  This would appear to be an example of a situation where the Linux-style &lt;a href="http://lxr.linux.no/linux/Documentation/stable_api_nonsense.txt" rel="nofollow"&gt;hatred of stable APIs&lt;/a&gt; wins over maintaining backwards compatibility.  One part of the problem is that Microsoft relies on third-party vendors for drivers. They can't just update their platform and the drivers with it, because they don't have any control over them.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:14756</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/14756.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=14756"/>
    <title>Gnome 3.0</title>
    <published>2008-07-15T20:55:13Z</published>
    <updated>2008-07-15T20:55:13Z</updated>
    <content type="html">The &lt;a href="http://arstechnica.com/news.ars/post/20080714-gnome-3-0-officially-announced-and-explained.html" rel="nofollow"&gt;Gnome 3.0 announcement&lt;/a&gt; is a win for sanity and demonstrates the maturity of the people running the project.  There's an elegance about a project that aims to be boring-but-functional, rather than exciting-and-unstable. Rather ironic for a project that was once described as a &lt;a href="http://www.jwz.org/doc/cadt.html" rel="nofollow"&gt;"cascade of attention-deficit teenagers"&lt;/a&gt;.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:14559</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/14559.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=14559"/>
    <title>What's so bad about shell scripts?</title>
    <published>2008-06-19T21:25:47Z</published>
    <updated>2008-06-20T11:40:32Z</updated>
    <content type="html">I think that probably almost all smart people have realised that scripting using the Bourne shell is a bad idea if the script in question is more complicated than simply automating what can be typed by hand.  I mostly avoid writing shell scripts, preferring to write scripts in either Ruby or Python. However, the ability to write shell scripts is still a useful skill; there are certain situations where writing a shell script really is the easier thing to do - mostly situations that involve &lt;i&gt;mostly&lt;/i&gt; revolve around executing commands, or where they're the "standard" thing to do - init.d scripts, for example. It's also useful to be able to debug shell scripts that other people have written. To this end, I recently set about honing my shell scripting skills.&lt;br /&gt;&lt;br /&gt;To this end, I wrote a script called &lt;a href="http://www.soulsphere.org/tools/branch_helper" rel="nofollow"&gt;branch_helper&lt;/a&gt;, which is for automating some of the drudge of managing Subversion branches.  The main aim of this was to make maintenance of &lt;a href="http://doom.wikia.com/wiki/Strawberry_Doom" rel="nofollow"&gt;Strawberry Doom&lt;/a&gt; easier, as it is developed as a &lt;a href="http://chocolate-doom.svn.sourceforge.net/viewvc/chocolate-doom/branches/strawberry-doom/" rel="nofollow"&gt;branch&lt;/a&gt; within the Chocolate Doom repository and needs periodic updates.&lt;br /&gt;&lt;br /&gt;The result is a script that is probably as complicated a shell script as I am ever going to write; certainly the most complicated that I am ever going to &lt;i&gt;want&lt;/i&gt; to write.  The process did, however, give me deeper insight into why shell scripts, as a "programming language" are quite so unscalable and only suitable for very simple scripts.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; One of the most fundamental drawbacks of shell scripts is the lack of a proper list construct.  Almost all programming languages give you arrays of some form or other; the closest that you can get with shell scripts is "a string containing a list of items separated by spaces".  While this sort-of suffices for some situations, the most obvious drawback is that you can't put items in the "list" that contain spaces themselves.  The result of all this is that almost all semi-complex shell scripts are broken if you try to use them with files/directories that contain a space.  To demonstrate this, try running a configure script in Cygwin from a directory containing a space (eg. "Documents and Settings").&lt;br /&gt;&lt;br /&gt;Bash has arrays as an extension, but, obviously, that won't work with any other Bourne shells. However, the standard Bourne shell &lt;b&gt;does&lt;/b&gt; have one type of list - namely, the list of arguments to a function. It's sometimes possible to make use of this if you structure the script in the right way.&lt;br /&gt;&lt;br /&gt;&lt;li&gt; Semi-related to the first problem is the problem of how variables are expanded.  &lt;tt&gt;command "$arg"&lt;/tt&gt; and &lt;tt&gt;command $arg&lt;/tt&gt; have different meanings, for example, as they expand into either one argument or (potentially) several arguments, respectively.  One useful thing to do trying to write "correct" shell scripts is to continually ask yourself - "what would happen if this variable contained a space?"&lt;br /&gt;&lt;br /&gt;&lt;li&gt; The inability to easily "return" useful information from a function is one annoying drawback.  Every function acts as a "mini-subprogram", which is rather aesthetically pleasing in a way, and actually incredibly useful in some situations.  However, it suffers from the fact that the only result that programs in Unix can return is a single 8-bit value (exit code).  &lt;br /&gt;&lt;br /&gt;The result is that the typical way to pass a value back from a function to its caller is to do something slightly hideous like this:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;    result=`myfunction "$arg1" "$arg2"`&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt; You can also get all kinds of insidious "gotchas" from the fact that the shell will sometimes fork.  For example, the following give different output:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;result=0

while true; do
    result=1
    break
done

echo $result&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;and&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;result=0

echo broken | while true; do
    result=1
    break
done

echo $result
&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;(In the latter, the loop runs in a separate process, so the "result" variable is set in that separate process, and the value lost when the loop finishes).&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;s&gt;This is actually another manifestation of the previous problem, but handling error situations can be problematic.  The simple requirement of "check if a program runs correctly; if it fails, exit the script with an error" can actually be quite tricky to achieve.  As the shell can fork to run different parts of the script (especially if you use the backticks trick to pass back values from functions), the "exit" command does different things in different places.  If you're in a main script, "exit" &lt;b&gt;will&lt;/b&gt; exit the script, but if you're in a section of code that has been forked off into a separate process, it only exits from that other process.&lt;br /&gt;&lt;br /&gt;I wrote a function called "error" to exit with an error, and used it to check that functions run correctly and, if they don't, chain back up to the top and exit properly.  So in the end, calling a function looks like this:&lt;/s&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;s&gt;result=`myfunction "$arg1" "$arg2"` || error&lt;/s&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Jon &lt;a href="http://fragglet.livejournal.com/14559.html?thread=68575#t68575"&gt;points out&lt;/a&gt; that error handling can be significantly simplified by using "set -e", which causes commands to exit if they return an error status.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt; Portability issues.  This isn't so much of a problem nowadays because you can pretty much rely on bash being installed on most systems and take advantage of its extensions.  However, if you really do want to write a proper "portable" Bourne shell script, there are some things that catch you out.  For example, bash lets you define functions using "&lt;tt&gt;function myfunction() {&lt;/tt&gt;" but this isn't supported elsewhere.  Similarly, when doing comparisons, bash lets you do eg. "&lt;tt&gt;[ "$value" == "shoes" ]&lt;/tt&gt;" in addition to the standard syntax, which is "&lt;tt&gt;[ "$value" &lt;b&gt;=&lt;/b&gt; "shoes" ]&lt;/tt&gt;".  &lt;br /&gt;&lt;br /&gt;Some very old systems have quirky interpreters that mean you have to do tricks like "&lt;tt&gt;[ "x$value" = "xshoes" ]&lt;/tt&gt;", because, without the "x", if "value" was empty, that would expand to "&lt;tt&gt; [ = shoes ]&lt;/tt&gt;", which is a syntax error.&lt;br /&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;All in all, some rather nasty quirks that rapidly turn into gigantic annoyances when you try to do anything complicated.  However, it's not to say that shell scripting is completely without merits.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:14291</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/14291.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=14291"/>
    <title>Valgrind with autotools</title>
    <published>2008-06-10T00:20:25Z</published>
    <updated>2008-06-10T00:20:25Z</updated>
    <content type="html">&lt;a href="http://www.gnu.org/software/automake/" rel="nofollow"&gt;Automake&lt;/a&gt; helpfully provides the ability to run tests with "make check" - you can give it a list of test programs to run, and it will go through each in turn and check that they exit with a success status (0).  However, when running test cases for stuff written in C, it's nice to run them in &lt;a href="http://valgrind.org/" rel="nofollow"&gt;Valgrind&lt;/a&gt; - that way, you can pick up on any memory leaks or other subtle memory errors that you wouldn't otherwise notice.&lt;br /&gt;&lt;br /&gt;Automake allows you to set a variable called "TESTS_ENVIRONMENT" that is prefixed to all your test commands, so you can run your tests in valgrind with something like:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;code&gt;make check TESTS_ENVIRONMENT=valgrind&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;Unfortunately, this isn't perfect.  First of all, it's rather tedious having to type that every time you want to run some tests, and secondly, it doesn't automatically fail in error cases.&lt;br /&gt;&lt;br /&gt;So I wrote some automake magic to make it all a bit more streamlined.  Firstly, a &lt;a href="http://c-algorithms.svn.sourceforge.net/viewvc/c-algorithms/trunk/c-algorithms/configure.ac?r1=171&amp;amp;r2=170&amp;amp;pathrev=171" rel="nofollow"&gt;--enable-valgrind&lt;/a&gt; flag to configure, to run tests with valgrind.  It's then a simple matter of &lt;a href="http://c-algorithms.svn.sourceforge.net/viewvc/c-algorithms/trunk/c-algorithms/test/Makefile.am?r1=171&amp;amp;r2=170&amp;amp;pathrev=171" rel="nofollow"&gt;tweaking Makefile.am&lt;/a&gt; to set TESTS_ENVIRONMENT when we have valgrind enabled.  Finally, a short &lt;a href="http://c-algorithms.svn.sourceforge.net/viewvc/c-algorithms/trunk/c-algorithms/test/valgrind-wrapper?view=markup&amp;amp;pathrev=171" rel="nofollow"&gt;wrapper script&lt;/a&gt; for valgrind to fail the test on any valgrind error output.  I run with the -q (quiet) option to hide the normal valgrind blurb.&lt;br /&gt;&lt;br /&gt;One thing that is important is to ensure that the tests are real executables and not magic libtool wrapper scripts (automake does this if you build against a .la file).  Valgrind gets confused otherwise.&lt;br /&gt;&lt;br /&gt;All in all, fairly straightforward.  I guess autotools isn't always such a pain after all.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:13734</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/13734.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=13734"/>
    <title>Scientology "war"</title>
    <published>2008-01-25T13:26:06Z</published>
    <updated>2011-12-14T13:38:37Z</updated>
    <content type="html">Ah, &lt;a href="http://technology.timesonline.co.uk/tol/news/tech_and_web/article3250934.ece" rel="nofollow"&gt;Internet drama&lt;/a&gt;.  So a bunch of kids have decided to "destroy" the Church of Scientology by DDoS'ing the Scientology website and making lots of prank calls to the various church buildings. Now, I'm thoroughly anti-Scientology and think that it's an incredibly dangerous and subversive cult; however, the &lt;a href="http://chanology.blogspot.com/2008/01/why-we-fight.html" rel="nofollow"&gt;rhetoric&lt;/a&gt; being thrown around by the members of "Anonymous" is almost as hilarious as the idea that a multi-million dollar business is going to be "destroyed" by a few kids ordering pizzas to the Scientology buildings and flooding their website off the Internet.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Perhaps the most stupid part of this whole affair is that it's possibly the worst possible action to take.  Scientology likes to smear any of its critics as &lt;a href="http://en.wikipedia.org/wiki/Suppressive_person" rel="nofollow"&gt;suppressive persons&lt;/a&gt;, effectively labelling them as hopelessly mentally ill people with anti-social and destructive tendencies. By "attacking" Scientology, the members of "Anonymous" are fitting themselves exactly into the role that the Scientologists would like to portray them as: "The antisocial personality supports only destructive groups and rages against and attacks any constructive or betterment group". Now it's easy for Scientology to dismiss any Internet criticism as having been concocted by antisocial "suppressives". &lt;br /&gt;&lt;p&gt;&lt;br /&gt;While people continue to believe in Hubbard's teachings, Scientology will continue to exist.  The way to destroy Scientology is to destroy those beliefs, to show the lies that the church propagates and all the crazy &lt;a href="http://en.wikipedia.org/wiki/Xenu" rel="nofollow"&gt;stories about aliens&lt;/a&gt; found in the upper levels.  The greatest weapon against Scientology is the truth, and the Internet is the most effective way to disseminate it. Of course, now, the church has an excuse to get more of its members running &lt;a href="http://www.xenu.net/archive/events/censorship/" rel="nofollow"&gt;censorship software&lt;/a&gt; - "protect yourself from dangerous Internet subversives, out to destroy Scientology!".  David Miscavige himself couldn't have come up with such an effective scheme.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;There is obviously a large group of people participating in the "war".  What a shame that so much energy has been put towards such an utterly counterproductive effort.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:fragglet:13492</id>
    <link rel="alternate" type="text/html" href="http://fragglet.livejournal.com/13492.html"/>
    <link rel="self" type="text/xml" href="http://fragglet.livejournal.com/data/atom/?itemid=13492"/>
    <title>Macbook Air</title>
    <published>2008-01-24T10:41:54Z</published>
    <updated>2008-01-24T10:42:28Z</updated>
    <content type="html">The minimum price for a &lt;a href="http://www.apple.com/macbookair/" rel="nofollow"&gt;Macbook Air&lt;/a&gt; is £1199.  For this, you get a slow processor, 2 gig of RAM with no option to upgrade ever, mono speakers - although I guess it doesn't need decent speakers, since there is no DVD drive to watch movies on anyway, tiny (and slow) hard drive (just in case you thought you could download movies to watch instead), no Ethernet port, and a single USB port just to fuck you over in case you thought you could plug in a USB ethernet dongle and external USB hard drives and DVD drives to work around the above inadequacies.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;The best part of all is that if you pay £2000, you can get the higher spec model, which has a slightly faster processor and even less storage.</content>
  </entry>
</feed>

