Julius Plenz – Blog

Reisebericht Sudan

Die letzten beiden Wochen habe ich nichts gebloggt, weil ich an einem kleinen Projekt geschrieben habe, das nun endlich fertig ist: Mein Reisebericht Von Kairo nach Khartoum über die Sudan-Reise.

Der Bericht ist eine hoffentlich amüsante und interessante Zusammenstellung von Erlebnissen; ich habe mich bemüht, auch Leuten, die noch nicht in Afrika gereist sind, zu vermitteln, wie das Leben dort abläuft.

Falls ihr's lesen wollt, plant ein bisschen Zeit ein: Es sind über 150 Fotos und ca. 40 DIN A4-Seiten Text.

posted 2012-04-30 tagged egypt, sudan and life

I'm back

I'm back from Sudan! – After six weeks of travelling in the desert, mostly taking cheap sleeping options and uncomfortable local transport it is a huge relief to have these certain luxury items again: Water from the tap (which you can drink!), a hot shower, a washing machine and a nice bed.

I wrote a travel diary and will use excerpts to write up a travelog with some photos from the journey. (This will take some days, naturally.) Already I tried stitching together a panorama image of Marawi, taken in the first morning light from the top of Jebel Barkal near Karima. It's a very typical pattern which you can see anywhere along the Nile: a few hundred meters of fields, then the main village, a tarmac road – built by the Chinese, mostly – and then: hundreds of kilometers of desert.

It is shivery-cold here in Berlin; already I miss Khartoum's every-day-above-40°C weather.

posted 2012-04-10 tagged life and sudan

Travelling up the Nile

I'm so excited! Tomorrow afternoon, together with a good friend of mine I'll board a plane to Cairo, Egypt. There, we'll try to acquire visas to enter Sudan. Essentially, we will travel up the river Nile from Cairo via Aswan, Wadi Halfa, and Atbara to Khartoum. If we have time, we'll also visit Port Sudan. In total, we have six weeks of time on our hands.

I hope I'm prepared well: I've been learning a bit of Arabic at university for the past two semesters; also, I've been reading the Sudan Tribune the past few months to stay up to date about the situation there. – Other than that, it's the usual stuff you should bring: insect repellent, anti-malaria tablets, water purifier, sunblocker, a good book and a (paper) notebook. Oh, and they don't have ATMs in Sudan, so it's all cash. Better hide it well. (Correction: There are no ATMs for international CCs like Master, Visa oder AmEx. For the local banks, there are quite a few.)

I had to cut down on my initial travel plans, which would have led from Cairo to Dar es Salaam (via Khartoum, Juba, Kampala), crossing five countries in total. This is not feasible any more, however, due to the high tension and violence in Southern Sudan (especially in the Abyei region). – On the upside, it'll be a rather relaxed journey now!

In Khartoum it's 36°C right now... – See you in April!

posted 2012-02-23 tagged life, nile, egypt and sudan

Bookdump

Cover of Kahneman's »Thinking, fast and slow« Ein Buch, das man sich wirklich nicht entgehen lassen sollte, ist Thinking, fast and slow von Nobelpreisträger Daniel Kahneman. Es ist sicherlich kein sehr mitreißendes Buch, aber auch nicht allzu trocken oder komplex. Thema des Buches sind die zwei Akteure System I und System II – die Intuition, die zwar schnell, dafür aber ungenau arbeitet und leicht zu täuschen ist, und das, was wir "angestrengtes Nachdenken" nennen.

Im Wesentlichen geht es darum, was für Mechnismen gewissen für uns typischen Denkmustern zugrund liegen, wie wir sie analysieren können, und was für Fehlinformationen sie uns glaubhaft machen können. Als wissenschaftliche Grundlage dienen dafür Gedankenexperimente, die großteils auch an Gruppen von Probanden getestet werden. (Jeweils gegen monetäre Entschädigung, häufig ist die Höhe der Entschädigung auch Grundlage des Experiments; wer finanziert sowas eigentlich? Und warum mache ich nie bei solchen Studien mit, wo man durch Beantworten einiger weniger Fragen ein paar Dutzend Euro erhalten kann? –)

Kahneman erklärt anhand einiger simpler kognitiver Illusionen, denen wir tagtäglich erliegen und die uns als scheinbar rationale Wesen objektiv völlig irrationale Handlungen unternehmen lassen, wie wir diese Illusionen a) erkennen können und teilweise auch b) dagegen vorgehen können.

Das Buch hat übrigens einen guten Index, so dass ich auch die äußerst passende Zusammenfassung aus dem Nachwort wiederfinden konnte:

The way to block errors that originate in System 1 [intuition] is simple in principle: recognize the signs that you are in a cognitive minefield, slow down, and ask for reinforcement from System 2 [careful thinking, as in: doing the math, considering statistics]. This is how you will proceed when you next encounder the Müller-Lyer illusion. When you see lines with fins pointing in different directions, you will recognize the situation as one in which you should not trust your impression of length. Unfortunately, this sensible procedure is least likely to be applied when it is needed most. We would all like to have a warning bell that rings loudly whenever we are about to make a serious error, but no such bell is available, and cognitive illusions are generally more difficult to recognize than perceptual illusions. (p. 417)

Im Nachwort räumt Kahneman übrigens mal eben so mit der Chicago School auf, die ja wesentlich auf der Illusion eines "rationalen Menschen" aufbaut: The economists of the Chicago school do not face that problem [whether to protect people from themselves], because rational agents do not make mistakes. For adherents of this school, freedom is free of charge. (p. 412) – –

Etwas leichtere Kost war Philip Roths Nemesis. Im Sommer 1944 geht es ums Überleben: Für die einen, weil sie in den Krieg ziehen müssen, für die anderen, weil sie zu jung sind, und sich zu Hause mit einer Polioepidemie konfrontiert sehen. Auch wenn der Protagonist diesmal nicht krebskrank in der Midlife-Crisis steckt, gelingt es Roth doch leider nicht, mal einen Roman zu schreiben, in dem es nicht um Tod, Verfall und Bedauern über das eigene Leben geht. Nichts also, womit ich mich identifizieren kann. – Viel eher kam ich dagegen mit Charles Bukowskis autobiographischem Character Chinaski in Das Liebesleben der Hyäne zurecht: Ein herrliches Buch, das ich an einem Abend gelesen habe. Hoffentlich bin ich mit 50 auch noch so gut drauf!

Mal wieder zwei nicht zu Ende gelesene Bücher, die mich nicht vom Hocker gehauen haben: Thomas Pakenham: Der kauernde Löwe, eine monumentale, aber doch etwas schwerfällige Biographie der Eroberung und Kolonialisierung der Mitte des afrikanischen Kontinents (also im Wesentlichen auch die Suche nach der Quelle des Nil) – Anne Michaels: Wintergewölbe, ein Roman über den Ab- und Wiederaufbau des Abu-Simbel-Tempels. Die Abschnitte über die forcierte Umsiedlung der Nubier (und das Pendant in Kanada) ist spannend und ergreifend, aber alles pseudo-bedeutungsschwere dazwischen langweilt nach den ersten drei Seiten, leider.

posted 2012-02-22 tagged bookdump

"Shouting in the Dark"

Al Jazeera's documentary about the Bahrain protests, Shouting in the Dark, has received a prestigeous award. The documentary is really worth watching.

I found the insidious practices of the Bahraini prince – and the Arab league's suport – extremely unnerving.

posted 2012-02-21 tagged documentary and bahrain

Bundespräsident

Ich vermeide es größtenteils, über Politik zu schreiben. Das liegt im wesentlichen daran, dass es einfach sehr viele Leute gibt, deren Tagesgeschäft das ist und die folglich darin um einige Größenordnungen besser sind als ich. Außerdem ist es so, dass mich die Beschäftigung mit Politik fast ausnahmslos wütend macht: Täglicher Politik-Nachrichten-Konsum ist bestens dazu geeignet, den Glauben an Fortschritt in unserer Gesellschaft zunichte zu machen.

Aktueller Anlass ist natürlich die Einigung vierer von fünf im Bundestag vertretenen Parteien auf Gauck als neuen Bundespräsidenten. Man bemüht sich dort noch nicht einmal, diesem Gauck irgendwelche Qualitäten, die ihn als Bundespräsidenten auszeichnen würden, zuzusprechen: Merkel sagte, mit Gauck verbinde sie vor allem die gemeinsame Vergangenheit in der DDR. Für Gauck habe sich der Weg von der Kirche in die Politik von fast alleine ergeben. Ihn zeichne aus, ein "wahrer Demokratielehrer" geworden zu sein. – Ja, Demokratielehrer schön und gut. Aber Aufgabe des Bundespräsidenten sollte es ja nicht sein, Demokratie zu lehren. Seine Aufgabe sollte es vor allem auch sein, den Fokus auf Probleme im Land und im politischen Diskurs zu lenken. Das kann man von Gauck wohl eher weniger erwarten.

Im wesentlichen scheint ein schlagendes Argument zu sein, dass sich viele Deutschen Gauck als Präsidenten wünschen. Das klingt auch vernünftig, bis man die Hintergründe recherchiert. Kaliber "Guttenberg ist so nett", sag ich nur.

Ein Pastor soll Präsident in Deutschland werden. – Pastoren: Das sind diejenigen, die professionell, das heißt um ihr täglich Brot zu verdienen, Tag für Tag, Woche für Woche Unwahrheiten predigen. Das sind diejenigen Menschen, die die evangelische Kirche repräsentieren – und somit im Grunde ihres Wesens gegen Fortschritt und Selbstverantwortlichkeit sind. (Man darf sich wohlgemerkt nicht von der Tatsache blenden lassen, dass auch Gutes aus diesen Kreisen kommt!) – – Wenn wir eines in diesem Land nicht gebrauchen können, dann einen zahnlosen, anti-sozialen, christlichen Bundespräsidenten.

Auch wenn man Fefes Ratschläge vielleicht nicht immer erst nehmen sollte: Die Nominierung Georg Schramms wäre in der Tat ein Geniestreich der Piraten – gewesen. Ich habe heute zwei Stunden lang alte TV-Mitschnitte von Schramm geschaut – die nota bene alle in öffentlich-rechtlichen Kanälen liefen, das hat mich doch positiv überrascht! – und da ist wirklich mal ein Mann, der mit der Faust auf den Tisch haut, ein Loblied auf den Zorn singt und wirklicht etwas zu sagen hat.

Update: Sag ich doch, andere können das besser. So zum Beispiel Deniz Yücel in seinem Replik auf die Kritik Lobos, der dessen Kolumne kritisierte: Der Holocaust, meint er [Gauck], ist eine Ersatzreligion der Gottlosen. Damit stellt er sich in die Tradition von Leuten, die ein Leben und Denken ohne Gott für unvorstellbar halten und den Nationalsozialismus gerne für ein Produkt der Gottlosigkeit halten, anstatt darin auch das in Ideologie wie Praxis modernisierte und radikalisierte Ergebnis des christlichen Antijudaismus zu erkennen.

posted 2012-02-19 tagged politik

C Programming Exam Fail

I just wrote an exam for the course Technische Informatik III which was about operating systems and network communication. In the exercises throughout the semster, we had to program in C a lot. Naturally, in the exam was one task about interpreting what a C program does.

It was really simple: Listening on a UDP socket and print incoming packets along with source address and port. The program looked somewhat like this (from what I remember; also some things were done in a not so clever way on the exercise sheet, and they had obfuscated the variable names to a non-descriptive a, b, etc.):

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <error.h>

int main(int argc, char *argv[])
{
    int sockfd;
    struct sockaddr_in listen, incoming;
    socklen_t incoming_len;

    char buf[1024];
    int len; /* of received data */

    /* listen on 0.0.0.0:5000 */
    listen.sin_family = AF_INET;
    listen.sin_addr.s_addr = INADDR_ANY;
    listen.sin_port = htons(5000);

    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
        perror("socket");

    if(bind(sockfd, (struct sockaddr *) &listen, sizeof(listen)) == -1)
        perror("bind");

    while(1) {
        len = recvfrom(sockfd, buf, 1024, 0, (struct sockaddr *) &incoming,
                        &incoming_len);
        buf[len] = '\0';
        printf("from %s:%d: \"%s\"\n", inet_ntoa(incoming.sin_addr),
                ntohs(incoming.sin_port), buf);
    }
}

I lol'd so hard when I saw this. It's a classic off-by-one error. (Can you spot it, too?)

If you want to store x bytes of data in a string, reserve x+1 bytes for the NULL termination character. Here, if you send a message that is exactly 1024 bytes long (or longer, as it'll get truncated), buf[len] will actually be the 1025th byte. Which might just be anything.

And those guys want to teach network and filesystem programming – hilarious. :-D

posted 2012-02-17 tagged life, university and c

Momente im Winter

In manchen Momenten hasse ich das Leben hier: Habe gerade eben den Zug in Dresden verpasst, und der nächste fährt erst in zwei Stunden. Der Gutschein der Deutschen Bahn, den ich vor ein paar Wochen per Post bekam und den ich nun einzulösen gedachte, ist nur für Fahrkarten gültig, deren Wert fünfzig Euro übersteigt (wohlgemerkt nach 50% BC-Rabatt) – hat man ja auch eher seltener, wenn's keine ganz große Reise ist.

Und so sitze ich am Hauptbahnhof bei frostigen Graden. Na immerhin macht es sich bezahlt, dass ich UMTS eingerichtet habe – das funktioniert nämlich.

Wäre doch bloß Sommer, dann wär's sicher ganz angenehm hier.

posted 2012-02-13 tagged life

minimizing Linux filesystem cache effects

Last weekend I toyed around a bit and tried to write a shared object library that can be used via LD_PRELOAD to minimize the effect a program has on the Linux filesystem cache.

Basically the use case is that you have a productive system running, and you don't want your backup script to fill the filesystem cache with mostly useless information at night (files that were cached should stay cached). I didn't test whether this brings measurable improvements yet.

The coding was really fun and provided me with yet another insight how the simple concept of file descriptors in UNIX is just great. (GNU software is tough, though: I got stuck once, and found help on Stackoverflow, which I had never used before.)

posted 2012-02-09 tagged linux, c and hack

Fragen

Gute Vortragende – seien es Dozenten, Professoren oder einfach nur Leute, die etwas referieren oder präsentieren – zeichnen sich unter anderem dadurch aus, dass sie mit den Zuhörern interagieren, an den richtigen Stellen Pausen machen und weiterführende Fragen stellen, statt monoton zu reden. Man kann dieses "Fragen stellen" aber in zweierlei Hinsicht falsch bzw. kontraproduktiv einsetzen.

Zunächst sind Suggestivfragen nur teilweise angebracht. Fragen wie "Fällt Ihnen hieran etwas auf?", die bewirken sollen, dass das Publikum die Situation kritisch unter die Lupe nimmt und eventuelle Ungereimtheiten aufspürt, sind gut. Aber rhetorisch anmutende Fragen wie "Alles verstanden?", bei denen spürbar wird, dass ein Ja erwartet wird, sind meist nicht produktiv: Die wenigsten werden sich melden, falls sie etwas nicht verstanden haben, und der Vortragende wiegt sich in falscher Sicherheit. Eine gute Alternative ist: "Gibt es Fragen bis hierher?", und eine anschließende kleine Besinnungspause.

In meinen Augen wirklich desaströs ist eine zu lose, offene, aber zugleich extrem erwartungsvolle Fragetaktik. "Wie können wir X erreichen?", ohne dass das Auditorium auch nur ansatzweise weiß, wie das Problem angegangen werden kann. Dann macht sich Verwirrung breit, und spätere Fragen, die möglicherweise sehr einfach zu beantworten sind, werden möglicherweise gar nicht oder zumindest nur sehr zögerlich beantwortet, weil das Publikum meint, die Fragestellung missverstanden zu haben, genau weil die Lösung auf der Hand liegt. – Das lähmt die Interaktion nachhaltig.

Zwei solcher Fragen, die eine kaum zu beantworten, die nachfolgende trivial, seien hier als Beispiel angeführt:

– Was haben wir nun für ein Problem bei der kanonischen Wahl der Basis des Tangentialraumes? (Gesuchte Antwort: Weil M nicht in einem umgebenden Raum betrachtet werden kann, muss TpM mit Hilfe von Äquivalenzklassen der Differentiale von Kurven, die in M durch p verlaufen, untersucht werden.)

– Welche Struktur hat TpM dann? (Gesuchte Antwort: Vektorraumstruktur.)

posted 2012-02-02 tagged thoughts

Pizzabäcker

In letzter Zeit mache ich mehrmals pro Woche selbst Pizza. Das schmeckt nicht nur besser und ist viel billiger als Fertigpizza, es macht auch einfach Spaß und hat etwas meditatives.

Ich mache einmal die Woche Teig aus einem Würfel Hefe, ca. 700g Mehl und 0.35L Wasser – der reicht für drei große Pizzen. (Den Teig eine Stunde gehen lassen, ab dann aber im Kühlschrank abgedeckt aufbewahren!)

Lecker!

posted 2012-02-01 tagged life and food

Krebsgeschwüre dieser Welt

Ich habe eben versucht, meinen altes Notebook auf Ebay einzustellen. Schließlich und endlich hat es dann auch geklappt. Nicht, dass das einfach war: Anscheinend kann man den Ebay Richt Text Editor nicht mit Firefox benutzen. Zumindest ich kann das nicht. Deswegen konnte ich keine Artikelbeschreibung einstellen. Mangels Alternativen habe ich dann Windows XP in einer KVM gebootet, und das Angebot mit dem Internet Explorer erstellt. Der funktioniert aber auch nur teilweise: Das Tutorial über die neue Art und Weise, wie eBay Geld überträgt, musste ich durch"klicken", indem ich oben in der URL die pageNr-Parameter hochgezählt habe. Die "Weiter"-Buttons waren leider nicht sichtbar, außer auf der letzten Seite.

Ich habe lange nicht mehr eine so inkompetent aufgebaute und unübersichtliche Seite wie eBay benutzt. Ein pures Wunder, wie das Leute tagtäglich benutzen können.

Merken die Leute nicht, dass es benutzbare und unbenutzbare Webseiten gibt? Gibt eBay kein Geld für Usability-Tester aus?! – Unbegreiflich für mich.

posted 2012-01-30 tagged rant and x41

shredding

I'm currently shredding my old X41's hard drive, because I want to sell it (if you are interested, contact me). I'm overwriting it with zeros, ten passes:

$ shred -vfz -n 10 /dev/sda

Luckily, the disk was fully encrypted all the time. So it's just a precaution.

posted 2012-01-30 tagged x41 and linux

Ten Years of Vim

About ten years ago, I began using Vim. Since about eight years ago, I have been using Vim for every email, every piece of code, literally every text I write. Today, I want to write a short text about how I came to use Vim and what I like about it.

I don't really remember when I first used Vim. It must have been around the time when I was programming PHP a lot. I had access to a "real" computer at home – running Windows XP – in 2002 for the first time; before that, I could only use older Macintoshs. It's typical for first-time Vi users to stumble into believing – by hear-say, I guess – that it is indeed a really superior editor, until they try it out the first time and can't even save, because they don't know how to. That were my first experiences too, probably.

Anyhow, at some point in time I ditched PHP Zend Studio for SciTE. Later, I got to know Vim (i.e., by reading a tutorial about it and actually understanding it) and was instantly hooked. Probably, the guys over at #html.de talked me into it. Ironically, I used Vim before I ever used a UNIX-like operating system.

In my Vim learning curve, I identify seven important advances:

  1. Understanding the Modes Concept. – This, of course, is something everybody needs to grok. It's fairly straight-forward, once you think about it.
  2. Understand the Visual Mode and Yank/Paste. – Line-wise selection already gives you more power than a regular editor when moving code.
  3. Understand Mappings and Macros. – Even today I am amazed how few people automate things. If it's one line, do it manually. If it's three lines, carefully think about the task while recording a macro for it!
  4. Unterstanding Windows. – Multiple files and stuff.
  5. Consequently using [h], [j], [k], [l]. – This actually was a much bigger step that you might think. I went to great lengths to achive this: I configured the arrow mapping to :echoerr a message. Today, I configure all programs to use Vim key bindings, especially for horizontal and vertical navigation. It's the first thing to do. I only use the arrow keys for Mplayer seeking.
  6. Using Text Objects. – See :help text-objects, if you don't know about them.
  7. Switching to a US keyboard layout. – Once you do this, all the Vim commands begin to make sense. (I used a German layout before.)

Steps 1–5 happened in the first two years. The text object only came with more recent Vim development, and I'm not quite sure when I adopted them. Learning the US layout was around 2006, maybe.

When I switched to using Debian in 2004, using Vim for all tasks already felt natural. Of course, at that point I finally came to understand Vim not merely as a text editor, but as a philosophy. And that is what fascinates me to this day: The Vi way of editing text is much more than a set of clever key bindings. It's a language.

Vi-vs.-Emacs fight In a way, I'm really professional at using Vim. If I think of the tasks I do, I suspect there are very few superfluous keys I press during editing. I have acquired a really good intuition of how to skip to a particular line, to a particular function parameter or a certain word in a sentence. (I use [H], [M], [L] for global on-screen navigation a lot, and I heavily use the [f], [t], [F] and [T] jump commands.) Just as you don't actually think about the letters you type when you become a good typist, I don't think about what command keys I press in Normal mode. I just press them, and the cursor magically moves around to where my eyes rest. This is good.

On the other hand, I am just using core Vim features, most of which are already found in original Vi implementations. My really conservative .vimrc change history shows that I pretty much settled my editing habits. – But: I have never used a third-party plugin before. Strange as it may sound, I never felt the urge to do so. Command-T certainly looks like it could be of use; however, I usually start a new Vim instance and go with the Z Shell completion, which I suspect to be superior in more than one way, to find the file(s). – Thus I must acknowledge that there might be vast possibilities yet do discover. (Oh, and while confessing, there's another big one: I have never used Emacs. All I know about it is hear-say.)

For keyboard enthusiasts, there are two quirks with Vim: It mainly relies on Escape for mode switches, and the keys for many combinations are aligned for QWERTY layouts. There's just no way around it: while [c] and [d] are mnemonic for cut and delete, [h], [j], [k], [l] simply aren't. There's no way justify their use when switching to Dvorak, and that's why I didn't (switch). I also once tried mapping [j][j] to Escape, or using the Caps Lock key as Escape replacement; I can't really stick to using it. (I also stick to calling vim on the command line instead of a shorter alias. It is the fourth most command I type, after sudo, git, and man.)

For me, text editing is equal to using Vim. I feel like a four-year old moving a mouse when I'm forced to use another editor on other people's computers. And because text editing is really clumsy with regular text editors, I no longer wonder why people don't really bother to correct errors: the effort is just not worth it.

If I had to sum up the difference between Vim and other editors in one sentence, it is this: While other editors are great for creating text, Vim is also great at manipulating text. And text manipulation, for most programmers and authors, is what it's all about.

:wq

posted 2012-01-30 tagged linux and vim

Kamikazes

Gerade mal zweistellige View-Zahlen? Das wundert mich. – Ich embedde das mal direkt, vielleicht hilft das...

posted 2012-01-30 tagged hiphop

Rapzeugs

Was so liegen geblieben ist:

Bei mir läuft die Königsmische auf Repeat.

posted 2012-01-22 tagged hiphop

vlock and suspend to ram

I've had weird race conditions when using vlock together with s2ram. It appears suspend to ram wants to switch VTs, while vlock hooks into the switch requests and explicitly disables them. So some of the time, the machine would not suspend, while at other times, vlock wouldn't be able to acquire the VT.

To solve this, I wrote a simple vlock plugin, which simply clears the lock mechanism, writes mem to /sys/power/state and later reinstates the locking mechanism. This plugin is called after all and new. Thus, the screen will be locked properly before suspending.

Here's my suspend.c:

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

/* Include this header file to make sure the types of the dependencies
 * and hooks are correct. */
#include "vlock_plugin.h"
#include "../src/console_switch.h"

const char *succeeds[] = { "all", "new", NULL };
const char *depends[] =  { "all", "new", NULL };

bool vlock_start(void __attribute__ ((__unused__)) **ctx_ptr)
{
    int fd;

    unlock_console_switch();

    if((fd = open("/sys/power/state", O_WRONLY)) != -1) {
        if(write(fd, "mem", 3) == -1)
            perror("suspend: write");
        close(fd);
    }

    lock_console_switch();

    return true;
}

Simply paste it to the vlock modules folder, make suspend.so and copy it to /usr/lib/vlock/modules. I now invoke it like this:

env VLOCK_PLUGINS="all new suspend" vlock

posted 2012-01-20 tagged linux and c

Xorg, really?!

Are you fucking kidding me? You reintroduce broken behaviour that possibly has devastating security consequences and and make it the default?! Yeah I agree the "usual" X server locking approach is not the best way to do it – but to knowingly smash the security of people's computers on a grand scale... that's priceless.

(My locking solution is env USER=feh vlock -a -n, again.)

Update: Why it happened

posted 2012-01-20 tagged linux and rant

zsh: complete words from tmux pane

Today I wrote a rather cool Z-Shell completion function: It will present all words that are found in the current tmux pane in a zsh completion menu. That means you can actually complete words from the output of commands that you just executed. (In a way it's a little bit like the keeper function, without the overhead of remembering to call keeper in the first place.)

The code below defines two keybindings:

Here's the code:

_tmux_pane_words() {
  local expl
  local -a w
  if [[ -z "$TMUX_PANE" ]]; then
    _message "not running inside tmux!"
    return 1
  fi
  w=( ${(u)=$(tmux capture-pane \; show-buffer \; delete-buffer)} )
  _wanted values expl 'words from current tmux pane' compadd -a w
}

zle -C tmux-pane-words-prefix   complete-word _generic
zle -C tmux-pane-words-anywhere complete-word _generic
bindkey '^Xt' tmux-pane-words-prefix
bindkey '^X^X' tmux-pane-words-anywhere
zstyle ':completion:tmux-pane-words-(prefix|anywhere):*' completer _tmux_pane_words
zstyle ':completion:tmux-pane-words-(prefix|anywhere):*' ignore-line current
zstyle ':completion:tmux-pane-words-anywhere:*' matcher-list 'b:=* m:{A-Za-z}={a-zA-Z}'

How does it work? _tmux_pane_words will just capture the current pane's contents (capture-pane), print out the buffer that contains it (show-buffer) and then delete it again (delete-buffer). – The rest of the magic happens via Zsh's excellent completion mechanisms.

See it in action (after typing spm^X^X):

posted 2012-01-19 tagged zsh, tmux and linux

Wenn der kleine Hunger kommt...

... Rucolasalat mit Tomaten!

posted 2012-01-17 tagged life

trying pthreads

Today I played around with POSIX threads a little. In an assignment, we have to implement a very, very simple webserver that does asynchronous I/O. Since it should perform well, I thought I'd not only serialize I/O, but also parallelize it.

So there's a boss that just accepts new inbound connections and appends the fds to a queue:

clientfd = accept(sockfd, (struct sockaddr *) &client, &client_len);
if(clientfd == -1)
    error("accept");
new_request(clientfd);

The new_request function in turn appends it to a queue (of size TODOS = 64), and emits a cond_new signal for possibly waiting workers:

pthread_mutex_lock(&mutex);
while((todo_end + 1) % TODOS == todo_begin) {
    fprintf(stderr, "[master] Queue is completely filled; waiting\n");
    pthread_cond_wait(&cond_ready, &mutex);
}
fprintf(stderr, "[master] adding socket %d at position %d (begin=%d)\n",
    clientfd, todo_end, todo_begin);
todo[todo_end] = clientfd;
todo_end = (todo_end + 1) % TODOS;
pthread_cond_signal(&cond_new);
pthread_mutex_unlock(&mutex);

The workers (there being 8) will just emit a cond_ready, possibly wait until a cond_new is signalled, and then extract the first client fd from the queue. After that, a simple function involving some reads and writes will handle the communication on that fd.

pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond_ready);
while(todo_end == todo_begin)
    pthread_cond_wait(&cond_new, &mutex);
clientfd = todo[todo_begin];
todo_begin = (todo_begin + 1) % TODOS;
pthread_mutex_unlock(&mutex);

// handle communication on clientfd

(Full source is here: webserver.c.)

Now this works pretty well and is fairly easy. I'm not very experienced with threads, though, and run into problems when I do massive parallel requests.

If I run ab, the Apache Benchmark tool with 10,000 requests, 1,000 concurrent, on the webserver it'll go up to 9000-something requests and then lock up.

$ ab -n 10000 -c 1000 http://localhost:8080/index.html
...
Completed 8000 requests
Completed 9000 requests
apr_poll: The timeout specified has expired (70007)
Total of 9808 requests completed

The webserver is blocked; its last line of output reads like this:

[master] Queue is completely filled; waiting

If I attach strace while in this blocking state, I get this:

$ strace -fp `pidof ./webserver`
Process 21090 attached with 9 threads - interrupt to quit
[pid 21099] recvfrom(32,  <unfinished ...>
[pid 21098] recvfrom(23,  <unfinished ...>
[pid 21097] recvfrom(31,  <unfinished ...>
[pid 21095] recvfrom(35,  <unfinished ...>
[pid 21094] recvfrom(34,  <unfinished ...>
[pid 21093] recvfrom(33,  <unfinished ...>
[pid 21092] recvfrom(26,  <unfinished ...>
[pid 21091] recvfrom(24,  <unfinished ...>
[pid 21090] futex(0x6024e4, FUTEX_WAIT_PRIVATE, 55883, NULL

So the children seem to be starving on unfinished recv calls, while the master thread waits for any children to work away the queue. (With a queue size of 1024 and 200 workers I couldn't reproduce the situation.)

How can one counteract this? Specify a timeout? Spawn workers on demand? Set the listen() backlog argument to a low value? – or is it all Apache Benchmark's fault? *confused*

posted 2012-01-17 tagged linux and c

"Wofür Deutschland Krieg führen darf. Und muss."

Ich habe unter der Woche Bernd Ulrichs Streitschrift Wofür Deutschland Krieg führen darf. Und muss. vom Oktober 2011 gelesen. Das Buch war für mich unter mehreren Aspekten interessant. Einerseits beleuchtet es die Hintergründe der Kriege, die ich damals als Kind noch nicht mitbekommen habe – den Namen UÇK kannte ich zwar aus den Nachrichten, wusste aber damit nichts zu verbinden – und bietet so eine gute Perspektive auf die jüngere Deutsche Geschichte, gerade auch in Hinblick auf die Auswirkungen der Wiedervereinigung auf die geopolitische Sicherheitslage Europas und der Welt, sowie das politische Selbstbewusstsein Deutschlands. Andererseits meldet sich hier aus der Generation meiner Eltern ein Kriegsdienstverweigerer und ehemaliger Mitarbeiter des Fraktionsvorstandes der Grünen im Deutschen Bundestag zu Wort, der mittlerweile stellvertretender Chefredaktuer und Leiter des Politik-Ressorts der Zeit ist.

Das ganze ist flüssig zu lesen, aber natürlich kontrovers – und das soll es ja auch sein. Zunächst muss gesagt werden, dass das Buch eine Reihe interessanter Einsichten enthält, die auch sehr treffend ausformuliert sind. Über die Tatsache, dass sich in der deutschen Bevölkerung nur sehr schwierig eine stabile Mehrheit für einen Einsatz der Bundeswehr finden lässt, bemerkt er ganz richtig (S. 53):

Hinzu kommt ein ganz profaner Umstand. In Deutschland finden unablässig irgendwelche Wahlen statt, weshalb eine kriegführende Bundesregierung einem andauernden Plebiszit ausgesetzt ist, das sie nur überstehen kann, solange andere als die militärischen Fragen wahlentscheidend sind.

Und weiter:

Die Regierung wird infolgedessen dazu tendieren, die Fragen von Krieg und Frieden möglichst nicht zu thematisieren, ja, ihre Thematisierung aktiv zu verhindern.

Eine weitere interessante Beobachtung stellt Ulrich über die "spezielle Verbindung" zwischen Deutschland und Israel an (S. 73):

In der wachsenden Distanz zu Israel und in die zunehmende Skepsis gegen Militäreinsätze hinein bringt nun die Merkel-Doktrin Deutschland näher an einen Militäreinsatz für Israel. Hier liegt eine enorme latente Spannung.

Schaut man auf das Inhaltsverzeichnis, so kann man das Buch in einige wesentliche Thesen zusammenfassen:

  1. Aufweichung der Bündnistreue: Emanzipation von der Bündnispflicht, hin zu Von-Fall-zu-Fall-Entscheidungen.
  2. Die Kriege im Irak und in Afghanistan waren falsch; die auf dem Balkan und in Libyen richtig.
  3. Künftige Militäreinsätze im Ausland sollten "Polizeicharakter" haben, Völkerrecht ist teilweise überholt.

Meine Generation, also die zur Zeit des Niedergangs der DDR oder nach dem Mauerfall Geborenen, sind in meinen Augen sehr pazifistisch eingestellt, und das ist gut so. Rundheraus würde ich sagen: Krieg ist immer falsch.

Leider stimmt das nicht. Ja, wenn man an all die Kriege denkt, die Amerika so geführt hat im Südosten Asiens, oder wie die Kriege in Afghanistan und dem Irak laufen: das ist abgrundtief falsch. – Andererseits muss man sich immer wieder den Ruandischen Genozid vor Augen halten, und die damalige Passivität der UN. Dadurch, dass westliche Mächte nicht eingegriffen haben, obwohl sie ziemlich gut wussten, dass ein riesiger Völkermord passierte, das ist unverantwortlich. – Wenn man sagt "Krieg ist in keinem Fall tragbar", dann öffnet man dem Kulturrelativismus Tür und Tor. Profan ausgedrückt, sagt man: "Lass die Anderen doch mit sich selbst klarkommen. Wenn sie sich abschlachten, dann ist das nicht mein Problem, und nicht einmal notwendigerweise falsch." – eine solche Einstellung ist sehr, sehr gefährlich. Von daher ist für den Pazifisten die Fragestellung, ob es überhaupt legitime Kriege gibt, eine sehr viel schwierigere, als sie auf den ersten Blick scheint.

Im Nachhinein kann man möglicherweise sagen, dass der Einsatz der Bundeswehr als Teil des NATO-Bündnisses in Libyen gerechtfertigt gewesen wäre. Der Einsatz ist mittlerweile beendet, und der Aufbau des Landes kann beginnen. Wenn ein Präsident die Luftwaffe gegen das eigene Volk einsetzt, dann sollte es schwer sein, wegzuschauen. – Natürlich muss man sich überlegen, wer denn die Machtposition Gaddafis über Jahrzehnte gefestigt hat. Aber man kann und darf die Frage nach militärischer Intervention nicht mit einer antiimperialistischen Floskel à la "hätten wir nicht X gemacht ... wäre nicht Y passiert" abtun. Dort sterben Leute.

Ich tue mich auch schwer in der Frage, zumal ich von einer anderen Prämisse ausgehe, was die Situation zugegebenermaßen leichter macht: Ich empfinde nichts für das Staatenkonstrukt Deutschland. Deutsche Kultur, insbesondere die deutsche Sprache und Literatur, sowie klassische Musik bedeutet mir etwas – das geht aber über Staatengrenzen hinaus. Der Großteil von Deutschland – das heißt, alles außerhalb von Hamburg und Berlin – bedeutet mir nichts, ganz einfach nichts. Ich habe da schließlich nie gelebt. Aber ohne die Grundlage von konstruierten Staaten, die gemeinsam agieren, entfällt natürlich die Notwendigkeit zur Verantwortung gegenüber anderen Staaten – es bleibt die Verantwortung von Menschen gegenüber anderen Menschen, und dort sind die Menschenrechte ein ziemlich allgemein akzeptierter Konsens.

Zusammenfassend lässt sich sagen, dass das Buch einige spannende Einsichten, auch in das Wirken von Presse und Politik, bereit hält. Und es ist beeindruckend zu sehen, wie ein ehemaliger überzeugter pazifistischer Aktivist heute Kriege zu legitimieren versucht.

posted 2012-01-08 tagged politik and bookdump

mutt sidebar patch improvements

It is generally accepted as an almost universal truth that mutt sucks, but is the MUA that sucks less than all others. While people use either Vim or Emacs and fight about it, I hardly see any people fight about whether mutt is good or bad. There is, to my knowledge, no alternative worth mentioning.

Mutt dates back well into the mid-nineties. As you might imagine, with lots of contributors over the course of almost two decades, the code quality is rather messy.

When development had stalled for quite a while in the mid-2000's, a fork was attempted. While mutt-ng was quite popular for a while, most changes were incorporated back into mainline mutt at some point. (Ironically, the latest article in the mutt-ng development blog is from October 2006 and is titled "mutt-ng isn't dead!"). The development of main mutt gained some momentum again, triggered in large parts by the contributions of late Rocco Rutte.

I remember two big features that the original mutt authors just wouldn't integrate into mainline: The headercache patch and the sidebar patch. About the former I can't say anything, but lately I've been fixing the Sidebar patch in various places. (We use mutt at work and rely heavily on e-mail communication, so we'd like a bug-free user agent, naturally.)

When all the mutt forking went about five years ago, I didn't know much about it. Retrospectively, I see the people did a hell of a job. Long before mutt-ng was forked, Sven told me he and Mika met in Graz for several weeks to sift and sort through the availbale patches, intending to do a "super patch".

Mutt's code quality is arguably rather messy.

On top of that, the Sidebar patch tries to make it even worse. Imagine this: mutt draws a mail from position (line=x,char=0) to the end of the line. Now the sidebar patch will introduce a left "margin", such that the sidebar can be drawn there. Thus, all code parts where a line is started from the leftmost character has to be rewritten to check if the sidebar is active and possibly start drawing at (line=x,char=20).

The sidebar code quality is a fringe case of bad code. Really, it sucks. However, there's no real way to "do it right", since original mutt never planned for a sidebar.

Who maintains the sidebar patch? – Not sure. There's a version at thomer.com, but he says:

July 20, 2006 I quit. Sadly, there seems to be no desire to absorb the sidebar patch into the main source tree.

The most up-to-date version is found at Lunar Linux. Last update is from mid-2009.

Debian offers a mutt-patched package that includes the sidebar patch, albeit in a different version than usually found 'round the net. In short, this patch is a mess, too.

But since I made all the fixes, I decided to contact the package's maintainer, Antonio Radici. He promptly responded and said he'd happily fix all the issues, so I started by opening two bug reports. Nothing has happened since.

The patches run quite stable for my colleagues, so I think it's best to release them. Maybe someone else can use them. Please note that I have absolutely no interest in taking over any Sidebar patch maintainance. ;-)

For some of the patches I provide annotations. They all feature quite descriptive commit messages, and apply cleanly on top of the Debian mutt repository's master branch.

The first four patches are not by me, they are just the corresponding patches from the debian/patches/ directory applied to have a starting point.

The first few patches fix rather trivial bugs.

Now come the performance critical patches. They are the real reason I was assigned the task to repair the sidebar:

This patch fixes a huge speed penalty. Previously, the sidebar would count the mails (and thus read through the whole mbox) every time that mtime > atime! This is just an incredible oversight by the developer and must have burned hundreds of millions of CPU cycles.

This introduces a member `sb_last_checked' to the BUFFY struct. It
will be set by `mh_buffy_update', `buffy_maildir_update' and
`buffy_mbox_update' when they count all the mails.

Mboxes only: `buffy_mbox_update' will not be run unless the
condition "sb_last_checked > mtime of the file" holds. This solves
a huge performance penalty you obtain with big mailboxes. The
`mx_open_mailbox' call with the M_PEEK flag will *reset* mtime and
atime to the values from before. Thus, you cannot rely on "mtime >
atime" to check whether or not to count new mail.

Also, don't count mail if the sidebar is not active:

Then, I removed a lot of cruft and simply stupid design. Just consider one of the functions I removed:

-static int quick_log10(int n)
-{
-        char string[32];
-        sprintf(string, "%d", n);
-        return strlen(string);
-}

That is just insane.

Now, customizing the sidebar format is simple, straight-forward and mutt-like:

sidebar_format

    Format string for the sidebar. The sequences `%N', `%F' and
    `%S' will be replaced by the number of new or flagged messages
    or the total size of the mailbox. `%B' will be replaced with
    the name of the mailbox. The `%!' sequence will be expanded to
    `!' if there is one flagged message; to `!!' if there are two
    flagged messages; and to `n!' for n flagged messages, n>2.

While investigating mutt's performance, one thing struck me: To decode a mail (eg. from Base64), mutt will create a temporary file and print the contents into it, later reading them back. This also happens for evaluating filters that determine coloring. For example,

color   index  black green  '~b Julius'

will highlight mail containg my name in the body in bright green (this is tremendously useful). However, for displaying a message in the index, it will be decoded to a temporary file and later read back. This is just insane, and clearly a sign that the mutt authors wouldn't bother with dynamic memory allocation.

By chance I found a glib-only function fmemopen(), "fmemopen, open_memstream, open_wmemstream - open memory as stream".

From the commit message:

When searching the header or body for strings and the
`thorough_search' option is set, a temp file was created, parsed,
and then unlinked again. This is now done in memory using glibc's
open_memstream() and fmemopen() if they are available.

This makes mutt respond much more rapidly.

Finally, there are some patches that fix various other issues, see commit message for details.

There you go. I appreciate any comments or further improvements.

Update 1: The original author contacted me. He told me he's written most of the code in a single sitting late at night. ;-)

Update 2: The 16th patch will make mutt crash when you compile it with -D_FORTIFY_SOURCE=2. There's a fix: 0020-use-PATH_MAX-instead-of-_POSIX_PATH_MAX-when-realpat.patch (thanks, Jakob!)

posted 2012-01-08 tagged mutt, linux and c