computers

You are currently browsing the archive for the computers category.

I use a lot of xterms – dozens of them, each one runs an ssh session. When I first started working for The Written Word, Inc. I used to start each xterm, manually place it on the screen on the desktop I wanted it on, type ‘exec ssh <host>‘ in each one, and start/resume a screen session. Whenever the connection dropped, I had to do it all over again. What a pain. So I scripted part of it.

The first thing I scripted was starting all those xterms and running exec ssh in each. If you start an xterm with the -ls argument, it starts a login shell in the terminal. So your login scripts will get run. Using this idea, I edited my login script (~/.bash_profile) and appended:

if test -n "${_SSH_HOST}"; then
exec ssh ${_SSH_HOST}
fi

Then I wrote a quickie “commute” script:

#!/bin/bash
: ${_SSH_HOSTS="every host that I wanted to connect to"}
for _SSH_HOST in ${_SSH_HOSTS}; do
export _SSH_HOST
xterm +sb -ls -geometry 79x25 -title $_SSH_HOST &
done

This script starts xterms with no scrollbar, running a login shell, 79 columns, 25 rows, and sets the window title to the host that the login script will exec ssh to. The strange geometry for the xterms is so that I can fit 12 terminals per virtual desktop. Using a more standard geometry would only allow 9, with a lot of unused space.

So things were improved, now I only had to manually place each xterm, and start the screen sessions in each one. For a little while I was ok, but then I thought to eliminate the manual screen session starting. Using expect I was able to easily record these actions, and edit the generated script. Now all I had to do in the event of a network timeout, or reboot etc was to manually place all these xterms in the correct location, on the correct desktop.

Of course, I wasn’t happy with that either, so I changed the -geometry argument to xterm to note the screen location. With each xterm being 479×349 pixels, it was easy to calculate where I wanted the next terminal to go. I had had to put in several “sleep” statements in my script previously to allow time for the terminals to actually appear on the screen etc. and some of these had to stay, but now all that was required to do manually was wait for the desktop to fill up with xterms, and click the mouse wheel to move to the next virtual desktop 4 or 5 times. Easy! :)

Last week, a switch decided it was time to die, dropping connections a couple of times a day, which meant I had connectivity problems for a couple of days until I discovered that it was the switch that was the problem and not the new router as I had assumed. This meant that I had to do the mouse wheel click to new desktop procedure 4 or 5 times over the course of two days. Doing it once a month or so was an acceptable imposition, but now it was again a pain.

At first, I installed the python bindings for libwnck and attempted to script the xterm window placement, however, I failed to get anything working as quickly as I had expected (would have been easier if I had found wnck_example.py). Another quick google search led me to devilspie. This seemed perfect. Now, at the beginning of my commute script, I generate a devilspie config file:

# Initialize variables
_workspace=2
_col=0
_row=0
# Create new empty config file
:> /home/pogma/pies
# populate config file
for _SSH_HOST in ${_SSH_HOSTS}; do
 echo "(if (matches (window_name) \"${_SSH_HOST}\")\
 (begin (geometry \"479x329+$((480*_row))+$((350*_col))\")\
 (set_workspace ${_workspace})))" >>/home/pogma/pies
 _col=$((_col+1))
 if test ${_col} -gt 2; then
   _col=0
   _row=$((_row+1))
 fi
 if test ${_row} -gt 3; then
   _row=0;
   _workspace=$((_workspace+1))
 fi
done
devilspie /home/pogma/pies >/dev/null 2>&1 &
# We'll kill devilspie later
_pid=$!
...
[snip rest of file to start xterms, start/resume screen sessions etc]

The geometry is a little odd because the window height does not include the title bar. Now, I can start my dozens of xterms, ssh to all those hosts, start the screen sessions if necessary, place the xterms properly, all with one script.

The other day I wanted to know when I had done something in my shell history, I asked on irc, and dre^ answered -> fc -d for zsh

Now I find myself looking at fc -l -d even when I don’t really need timestamps :-)

% fc -l -d
[snip]
  356  14:56  vim sem.c
  357  18:09  gmake
  358  18:10  vim buffer.c

It is possible to get similar behavior with bash:

$ HISTTIMEFORMAT="%T " history 3
 1386  09:36:54 grep -rl afio .
 1387  09:37:55 vim ChangeLog
 1388  12:56:57 HISTTIMEFORMAT="%T " history 3

Where HISTTIMEFORMAT uses an strftime string.

Yet another useless bit of knowledge!

I released libtool 2.2.6b today. Yes, I have already taken flak for the stupid version numbering. I apologize.

The release has only 2 real patches from 2.2.6, both for libltdl. See the announcement for slightly more detail.

Some users may be stuck using an older libltdl for whatever reason, for those users the same changes are provided by this untested patch.

[Update 2009-11-21]
The change to libltdl to not search in the current working directory for modules when lt_dlopen() is called without an absolute path breaks at least mpg123. This patch should work around the problem until the mpg123 folks fix it.

[Update 2009-12-02]
This release was to fix the now published CVE-2009-3736. If you have not already updated, doing so soon is advisable.

Yesterday tjcarter was complaining in #fink about offlineimap not working on Snow Leopard, so last night I thought I’d take a look.

Indeed, it doesn’t work, and the reason is that ‘import locale’ is being called on a thread, which loads _locale.so, which requires that the CoreFoundation framework also be loaded. A simple reproducer in python is:

import os, sys
import threading
class Foo(threading.Thread):
	def __init__(self):
		threading.Thread.__init__(self)
	def run(self):
		import locale

t = Foo()
t.start()

The CoreFoundation framework must be loaded on the “main” thread, its initialization expects that, if it is loaded on some other thread, then it causes the application to exit rather abruptly. You can reproduce the same thing easily in C with:

#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void* do_open(void* unused) {
        void * handle = dlopen("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation", RTLD_GLOBAL);
        if (! handle) fprintf(stderr,"ERROR: %s\n",dlerror());
        pthread_exit(NULL);
}

int main() {
        pthread_t t;
        pthread_attr_t a;
        if (pthread_attr_init(&a)) exit(1);
        if (pthread_create(&t,&a,do_open,NULL)) exit(2);
        pthread_attr_destroy(&a);
        sleep(5);
        return 0;
}

The failure can be avoided/worked around by ensuring that CoreFoundation is loaded on the main thread. For offlineimap, a simple way to do this is to put ‘import locale’ in the main script before init.startup is run. This will load _locale.so and thus CoreFoundation. CoreFoundation will run its initializers, and all will be well.

I am pretty sure that I have seen it documented somewhere that Apple’s frameworks must be loaded on the main thread, but I don’t seem to be able to find that documentation this morning (perhaps I just need more coffee?). In any case, loading any libraries that you need at application startup before you go spinning off threads is, in my opinion, a reasonable solution.

I released odcctools today, no changes for the last month or so, so I thought I had better put something out there.

http://svn.macosforge.org/repository/odcctools/release/odcctools-20090808.tar.bz2

« Older entries