The main indicators of egotism as I intend it here are are loud self-display, insecurity, constant approval-seeking, overinflating one’s accomplishments, touchiness about slights, and territorial twitchiness about one’s expertise. My claim is that egotism is a disease of the incapable, and vanishes or nearly vanishes among the super-capable.

I’m the crippled kid who became a black-belt martial artist and teacher of martial artists. I’ve made the New York Times bestseller list as a writer. You can hardly use a browser, a cellphone, or a game console without relying on my code. I’ve been a session musician on two records. I’ve blown up the software industry once, reinvented the hacker culture twice, and am without doubt one of the dozen most famous geeks alive.

No prizes for guessing who this was.


A horrible little ElementTree gotcha

What does this print:

from lxml import etree
doc = etree.fromstring('<a><b><c/></b></a>')
newdoc = etree.ElementTree(doc.find('b'))
print newdoc.xpath('/b/c')[0].xpath('/a')

The answer is: [<Element a at 817548c>]. The first point to note is that xpath() against an element is only relative to that element: any absolute XPaths enumerate from the top of the containing tree. The second point is that the shallow copying of etree means that _Element::xpath, unlike _ElementTree::xpath, evaluates absolute paths from the top of the original underlying tree! So even though there's no <a> in newdoc, an absolute XPath on a child element can still reach it.


YouTube annoyance

How much time would it really take to order multi-part videos, so the suggestion at the end of the video is the next part? Please!


An annoying Python gotcha

Imagine you have this in mod.py:

import foo

class bar(object):

def __del__(self):

Seems fine right? In fact, there's a nasty bug here. If I try to use this module in client.py like so:

import mod
mybar = bar()

Then you're likely to get an exception when the program exits. This is because Python, for some bizarre reason, Nones out the globals in mod.py when taking down the interpreter. The actual __del__ method can be called sometime after this, and it ends up trying None.cleanup(), with the resultant AttributeError. It seems extremely bizarre that it happens in this order, but it does (a real example).


Kernel solipsism

Thomas Gleixner:

Exactly that's the point. Adding dom0 makes life easier for a group of users who decided to use Xen some time ago, but what Ingo wants is technical improvement of the kernel... The kernel policy always was and still is to accept only those features which have a technical benefit to the code base.

It boggles the mind that someone could get things so backwards. The kernel exists to provide services to the outside world, not the other way around. By all means criticise the details of the Xen dom0 code, but this argument makes zero sense. How precisely did x86_64 support provide a technical benefit to the code base?



Charlie Brooker on the BNP party political broadcast:

Nick Griffin's first line is "Don't turn it off!", which in terms of opening gambits is about as enticing as hearing someone shout "Try not to be sick!" immediately prior to intercourse.


Outputting XML in standard Python

Is it really this ugly? I expected something like this:

doc = xmldoc()
doc.start('foo', { 'id': 'blah' })
print doc

and I thought I had it in SimpleXMLWriter. However, I have to jump hoops to get it to output to a string, and it doesn't have any pretty-print. I tried using ElementTree, but that also doesn't pretty print! libxml2 is horribly low-level. lxml seems to do pretty printing, but it's still just as ugly as the best option I've found so far, xml.dom.minidom:

from xml.dom.minidom import Document
foo = doc.createElement('foo')
foo.setAttribute('id', 'blah')
sub = doc.createElement('sub')

Yuck! If I'm building up a document, I almost always want to append directly at the last point: why do I have to keep track of all these elements by hand? I presume I'm missing some small standard helper module, but #python didn't know about it. Anyone?


Scoble sets a new record

I really hate the word “friend.” It has no meaning anymore. No one can define what a friend is. Believe me, I’ve asked dozens of people to define it for me. My wife is my most “true” friend, for instance but if you trust her with picking a great wine (she doesn’t drink much) or picking a great sushi restaurant (she hates the stuff) you’ll be very disappointed. You’d be better off asking @garyvee about the wine even though you’ve never met him and he probably wouldn’t be listed among your “true” friends.

- Scoble

Might I gently suggest friendship isn't about wine recommendations?



Apparently applications should be prepared to lose 60 minutes of data to work around the file system now.

Of course the notion that application should have explicit load/save operations is a nonsense already. Now we should "fix" one of the few places that never had this (ever seen a browser where you have to save your bookmarks explicitly when you quit?) to expose this implementation detail in a data-losing way again.


It's a shame that it's basically impossible to compete with Amazon when it comes to online book selling, because their website is so horribly awful to use. Not fair.


It's not just atol(), Nicholas

Nicholas Nethercote warns us against atol(). Sadly, he recommends using strtol() instead. This interface is almost as bad. If atol() is impossible to get right, strtol() has to be classified under the obvious use is wrong.

As a perfect example of how horrible strtol() is, let's look at his example code:

int i1 = strtol(s, &endptr, 0); if (*endptr != ',') goto bad;
int i2 = strtol(endptr+1, &endptr, 0); if (*endptr != ',') goto bad;
int i3 = strtol(endptr+1, &endptr, 0); if (*endptr != '\0') goto bad;
bad: /* error case */

Can you spot the bug? What about an input like ",2,3" ? Nicholas does mention that this code is broken for underflow or overflow (you must wrap every singe call like this: "errno = 0; strtol(...); if (errno...)") but either missed this or considered it irrelevant. It's just too hard to get right.

Just use the *scanf() family (yes, that's hard to use too). Be suspicious of any code using either strtol() or atol().


Comics I Don't Understand

Comics I Don't Understand. One for Seinfeld fans. What I don't understand is how someone can have a Wordpress design that has no "Previous" button. Blech.


Heston Blumethal's Feasts

I've just watched last week's episode of this series, Heston Blumenthal's Victorian Feast. The guy is the epitome of the mad scientist (his dessert was strawberry, elderflower and absinthe dildo jelly with earl grey ice cream).

I had one of his inventions a while back: strawberry, olive and leather vanilla sundae. It was pretty nice, though the rather more staid chocolate wine popsicle was much nicer.

You should watch Tuesday's...


Tomcat on Centos 5.2: just don't

If you were thinking of trying to use CentOS 5.2's tomcat packages: don't. You just get a silent 400 Bad request error on the holding page for no reason. Download it from upstream, and use that directly. It's very poorly documented, sadly, so to get started:

  1. Install the Sun JRE and set $JAVA_HOME appropriately - gcj is ... lacking
  2. Grab the Tomcat 'core' tarball and unpack it in place
  3. edit conf/tomcat-users.xml to add a user that has the 'manager' role
  4. start Tomcat with ./bin/startup.sh
  5. Go to http://yourhost:8080/ and log in to "status" with the manager user you added
  6. This will list any of the apps you installed (by dumping their .war file in webapps/)
I also set up a virtual host with Apache (for OpenGrok) like this:

<VirtualHost *.80>
ServerName grok.example.org
ProxyPreserveHost On
ProxyPass / http://example.org:8080/
ProxyPassReverse / http://example.org:8080/


Gas no gas abadie pizza please

Well this makes no sense:

Me: "Hi, your letter said I needed to arrange a visit with you to check the gas safety of my flat."
Them: "That's right, what's your details?"
*gives them*
Me: "There's no gas supply in the building, but apparently you have to come see that in person yourselves."
Them: "Yes, that's true. .... OK, we'll send you a letter with the appointment details."
Me: "Uh, I can't just do any time, it needs to be arranged."
Them: "That's OK - if you can't make the appointment on the letter, then you can ring us up after you receive it and tell us."
Me: "..."


Holocaust deniers

Somewhat unpleasantly, I'm a vague acquaintance of a couple of holocaust deniers (in the sense that I've been in the same place as them once or twice). Really weird people:

  1. They always bring it up at parties. Seriously, what? If I were a terrorism expert, I'd tend to keep off the subject at parties, since people might see it as a little sensitive. Even if I was just a huge fan of He-Man or something I'd probably only mention it if we were talking about 1980s kids' TV. Why do they always start talking about it?
  2. It's never a slight correction. It's always some ridiculous figure they claim, like "zero" or "thousands". Surely if the figures are really dubious, they're not going to be 6 million off? It's equivalent to claiming that nobody lives in Libya.
  3. They appear to believe in either the most expertly executed hoax of all time, and their only apparent response to this is to moan about it to people they don't know. How does that make any sense?


Javascript off

cdfrey: the fact that you've disabled JavaScript in your browser automatically qualifies you as irrelevant for anyone designing a modern user interface - sorry.

Dear Everyone

If you have a blog, and you ask questions in blog entries, have some way to leave comments, won't you?



Things I discovered yesterday

  1. Installing Firefox in an OpenVZ container can make you lose /dev/null
  2. OpenSolaris sleep(1) needs the network to be up
  3. People are injecting foreskins into their face
  4. Dubai is really screwed

Audacity is frustrating

You might think that recording and then splitting it into separate audio files based on silences
between each track would be easy to do - sadly not.

Aside from crashing a few times and failing to recover properly, I've been hit by these
enormous frustrations:

- despite claims to the contrary, even 1.3.7 does not correctly alter labels when you modify the
audio. That means there's no way to Truncate Silence without re-doing all your labels!
- you can't split into tracks (or, apparently, make selections) based on labels added by the silence finder, so you can't remove inter-track silences that way either
- the labels dialog has a fun bug where it removes all your labels that don't have names (as
none of them do by default). This gets frustrating fast.
- there's no way to start a recording on the current track - I have to have a new one, it seems. This was fine until I discovered that Mix and Render completely screwed up the merging of all the tracks.

Seriously, how do people actually use this thing?


openpty() and forkpty(): avoid

After dealing with more code that gets it wrong I was reminded of the numerous reasons why openpty() is such a broken API. The prototype of this "convenience" function is this:

int openpty(int *amaster, int *aslave, char *name, struct termios *termp, struct winsize *winp);

Now, sin number one should be obvious: the interface isn't const-correct. You're passing in the winp values, but there's no indication of that. Worse, you're doing the same with termp. Why worse? Well, think about how you use this API. Typically, you want to create the master/slave pair of the pseudo-terminal, then change the terminal settings of the slave. (Let's leave the master out of this for now - but the settings are not always symmetrical.)

But where do we get the terminal settings from? We don't have an open slave to base them on yet! So you find code doing a cfmakeraw() on stack junk and passing that in, because the API almost insists you do the wrong thing.

Indeed, doing it right, namely with a tcgetattr()/cfmakeraw()/tcsetattr() stanza, you'd expect term to be an out parameter, that you could then use - precisely opposite to how it actually works, and what const correctness suggests to the user. You can see some other amusing examples of how people worked around the API though.

I'm sure you will have spotted by now that the name parameter is outgoing, but has no len. It's therefore impossible to use without the risk of buffer overflow.

This API is not going to score well on the Rusty scale. What's worst of all about openpty(), though, is that it's non-standard, so almost every piece of code out there keeps its own private copy of this broken, pointless interface. Yay!


Review board review

I was bored so played around with Review Board a little more, including installing it myself.

Things seem to have got easier to install, at least to some degree. You can use easy_install, though at least
for CentOS 5.2, you'll need to install a newer version of setuptools first. It's also far from automated, missing
out basic dependencies like pysqlite2, patchutils, and even patch itself. Discovering these can be, and in my case was, rather tedious work.

After that it's pretty easy to install, for the sqlite version anyway. The documentation isn't exactly clear on
what permissions changes you need to make: you need to chown all of db/ to the apache user as well for anything to work. Expect to set up a virtual host for the installation, like I did above.

Don't forget to enable logging in the admin interface whilst you're messing around.

Sadly, the Mercurial support seems some way behind. For example, it doesn't pick up changeset comments.

The diff parser (how is this not in a library by now?) can't handle git diffs, and the failure mode is horrible (basically, silent failure, with no debugging messages). This is because hg git diffs don't contain the revisions being diffed, so Review Board can't pull the files from the repo. Undoubtedly a Mercurial misfeature, but it does make Review Board near useless for my purposes unfortunately.

It can handle ssh repositories (which is all opensolaris.org provides), but there's a horrible work around needed: you have to set up a correct known_hosts file in the apache user's home directory. Yuck.

As for the main interface, it's generally pretty slick. I can imagine it getting cumbersome quickly with large code reviews though. Compare and contrast Review Board's diff viewer with webrev. The latter to me at least, is much more scalable, even though the actual diff mechanism is less smart. In particular, I can review each file with webrev in a separate tab, whereas Review Board insists on one big (very big!) screen. I'd still give my right arm for a webrev-based Review Board :)

Another thing I'd like to see is more integration with the repository, so I can click on a file and it will take me off to the repo browser for looking through history.


My Real Dad

My favourite Wondermark for a while.


Pride And Prejudice And Zombies

I haven't read it, but I'm guessing this does exactly what it says on the tin.


I've only just read the XML-RPC spec. I knew it was simple, but I didn't know it was stupid. Seriously, no parameter names? Only 32-bit integers? And no "NULL"? WTF?


Harold Wobble Wedges

Talk about unnecessary. JUST USE SOME NEWSPAPER. Sheesh.


ASA to rule on the existence of god

I think atheists and believers alike should agree to abide by the Advertising Standard Agency's decision, when it comes - agreed?



After sitting through Expelled, I felt the need to cleanse my intellectual palate. Thankfully I had Bill Maher's Religulous to watch. Coming across like a mongrel of Borat and An Inconvenient Truth, it's an alleged documentary, played for laughs. And chunks of it are indeed very, very funny - the Cannabis Ministry guy comes to mind.

Consisting mainly of Maher tracking down the more comedic elements of out-there religion, it's a wonder he
got most of these people to sign the release forms. I'm especially thinking of the senator who admitted he
was religious because he was stupid. Maher uses his incredulity at these people's beliefs for humour, and he
does it rather well. It's not the kind of film that's supposed to make a serious point, though of course it does.

Particular highlights for me were the Vatican priest who dismissed Hell as a "silly idea", and the Professor
Frink style inventions of The Institute for Science and Halacha, devoted to technology to work around the absurd orthodox Shabbat rules (cue the pneumatic wheelchair).