This is one of those ones where you only realise the answer is one line in the documentation after an hour or two of fruitless googling…

I was using ctypes to access a C function which returns a pointer to a buffer and the size of the buffer, along the lines of:

char *get_data (size_t *len);

Mapping this into Python wasn’t hard:

get_data = lib["get_data"]
get_data.restype = POINTER(c_char)
get_data.argtypes = [ POINTER(c_size_t) ]

...

len = c_size_t()
data = get_data(byref(len))

(Note that you don’t use c_char_p as the return type, because that’s used for NULL-terminated strings, whereas our function returns binary data which may include NULLs.)

I then wanted to write the data to a file. However, a Python File object’s .write() method takes a string (or bytes object), so I can’t pass it ‘data’ as is (because ctypes doesn’t know how to cast it to a string, which isn’t unreasonable given that it also doesn’t know how long it is).

So the question is: how do you cast a pointer to data to a Python string?

The answer is to use the ctypes string_at() function:

len = c_size_t()
data = get_data(byref(len))

outfile.write(string_at(data, len))

I’m not 100% sure whether this copies the buffer or simply shares the pointer, but my understanding from various forum posts out there is that it is the latter, and so much more efficient than converting the data to a string by iterating over the bytes and constructing the string.

Advertisements

Update 16/10/2014: it looks like all this continues to work in Yosemite as well as Mavericks

Until recently I’d been using Snow Leopard on my MacBook Pro. I also have a wee NAS, and had configured it to share its folders via NFS. I’d mounted these on my Mac using the fairly obscure NFS menu items in Disk Utility.

But after upgrading to Mavericks, my NFS mounts had disappeared. My Google-fu didn’t turn up anything that looked like user-level documentation on this issue, so I put on my UNIX hat and went rummaging in /etc.

What we’re dealing with here is the automounter, aka autofs. I know how this works on older UNIXes and Linux, but OS X does things differently. I found some information from 2009 which seems to still be accurate:

Here’s how I got my mounts working again.

First, I edited /etc/auto_master to add a line for my NAS mount points:

/nas          auto_nas

What this means is, “for directories under /nas, consult the file /etc/auto_nas to see how to mount them”. I added this before the final /- line, which I believe is a wildcard, but I’m not sure whether order is significant in this file (the linked document would probably answer that).

So secondly, I added the file auto_nas:

music    storage.local:/nfs/music
data     storage.local:/nfs/data

This lets me access the music and data folders on my NAS from my Mac as /nas/music and /nas/data respectively.

Finally, I told the automounter that I’d changed its configuration:

sudo automount -vc

After that I was able to access my network data again, happy times.

10 or so years ago I worked on a CD-ROM product which continues to sell from time to time. At the time, we used a product called PC-Install to make the installer; since then we’ve moved on to Inno Setup.

Unfortunately, although our software was 32-bit, the installer produced by PC-Install was 16-bit, and some flavours of recent versions of Windows no longer run 16-bit software. So although the application could run, there was no way for users to install it.

So I set about using Inno Setup to create an installer which would work against the existing stock of CD-ROMs (binning them and issuing a new version isn’t financially viable).

The basic idea was for the installer to detect the CD-ROM, copy the files across, and set up the icons. Obviously, I couldn’t rely on the D: drive always being the optical drive, so I’d need to detect it dynamically. This stackoverflow post links to the code I used and adapted (it doesn’t work out of the box). It implements a function to discover the optical drive letter, and then uses a scripted constant to invoke it for use as the file source.

So, I got the function working, and then used it in my Source line:

Source: "{code:GetCdromDrive}\*.*"; DestDir: "{app}"; Flags: recursesubdirs;

However, when compiling/running this, I got the error:

Unknown filename prefix "{code:"

suggesting one couldn’t use scripted constants in Source lines. After a bit of fruitless experimentation and googling though I returned to the original example code and spotted I’d missed one of the Flags: ‘external’. This turns out to be the key:

Source: "{code:GetCdromDrive}\*.*"; DestDir: "{app}"; Flags: recursesubdirs external;

Apparently the source directory is ordinarily determined at compile time, and the ‘external’ keyword defers it to run time. (This is hardly obvious from the documentation though.)

Recently, we were looking for a server for a CPU intensive, single-threaded website. We needed lots of cores, for simultaneous load (traffic spikes), but also fast CPUs if possible.

We had to choose between a faster machine with 16 cores, or a slower one with 32 cores. The latter machine was marginally slower per core than our existing server; however, we learnt that the Opteron CPUs it used had AMD “Turbo core” support.

Turbo core is a technology whereby the CPU, if it detects that there is high load on some cores, will shut down unused cores and boost the ones in use, provided the temperature of the CPU remains within tolerance. This requires OS support, and the Linux kernel has had support since early 2010. Phoronix has some Linux benchmarks if you’re interested.

That tipped it for us, because with Turbo Core enabled, the 32-way machine would be faster under light load than our existing server, while also providing breadth for spikes.

However, once we’d commissioned the machine, our tests didn’t show turbo core being used. (We tested by monitoring CPU status files in /proc/ while simulating high web load using wget.) After some head scratching, poking around in dmesg, checking the BIOS settings etc, we discovered that CentOS 6.4, released in February 2013, uses a kernel from late 2009 (2.6.32) which would suggest it doesn’t support turbo core (available from 2.6.35).

However, that didn’t necessarily mean Turbo Core wasn’t supported – the version of the 2.6.32 kernel CentOS 6.4 uses has had many revisions (358 according to Wikipedia).

The way to check definitively is firstly to look in /var/log/dmesg for this boot message:

powernow-k8: Core Performance Boosting: on

Secondly, install the cpufrequtils package and run cpufreq-aperf, which monitors core speeds more accurately. When you then put the system under load, you’ll see whether CPU frequency goes above the rated speed of the CPU, i.e. into turbo mode. In our case, with CPUs rated at 2.1 GHz, we saw speeds in the region of 2.8 GHz:

CPU   Average freq(KHz)   Time in C0      Time in Cx              C0 percentage 

021   2835000             01 sec 000 ms   8784163844 sec 623 ms   100

I wanted to add a signature to the bottom of every post, and it seemed the way to do this was to use a plugin. However, my WordPress dashboard doesn’t have a “Plugins” menu item, which should be below “Appearance” according to the help pages and various screenshots you’ll find when googling.

It turns out that blogs hosted at wordpress.com don’t support plugins, presumably because installing a plugin involves uploading files to the server, and it’s not your server.

I’ve been banging my head for a couple of hours trying to work out why W3C geolocation was working in Firefox but not IE9. Using the F12 developer tools I was able to step through the javascript and see that it was calling getCurrentPosition(), but nothing would happen at that point – neither the success nor error handlers were called.

Various internet suggestions I tried before finally arriving at the answer:

  • Using window.navigator.geolocation rather than just navigator.geolocation. You should do this (or find a toolkit that abstracts it for you – jquery doesn’t seem to).
  • Temporarily changing my DOCTYPE to the HTML5 declaration <!doctype html>. The Microsoft geolocation pages say that geolocation is only supported in standards mode, and that using the HTML5 doctype is the easiest way to do this. However, I could see from F12 developer tools that I was already in IE9 standards mode.
  • Changing the IE9 privacy settings. There’s a checkbox to prevent sites from requesting your location; it wasn’t checked, but there’s a “Clear sites” button next to it so I gave that a go. No dice.
  • Combing through the security settings to see if there was a magic radio button. Nope.

Finally, I created a minimal page on my desktop with just a hyperlink to invoke getCurrentPosition(). That worked, so I assumed there was something subtly broken in my real page. So, I saved the source to the desktop so I could start butchering it to find the problem. However, when I loaded the unmodified page in IE9, it worked.

So I figured it was something to do with the page’s URL. It was being served on an intranet server, so I used the old trick of using a qualified domain (http://foo.internal rather than http://foo) to trick IE into thinking it was an internet site (it seems that dots in the domain are how IE decides). Lo and behold, that did it, and geolocation started working.

However, that wasn’t the end of the story. It turns out that when IE9 prompts you to ask whether you want to share your location, if you click the ‘X’ close button rather than making a selection, it will no longer prompt you thereafter. Restarting the browser clears it. I then went back to my unqualified domain, and that fixed that too.

TL;DR: try restarting your browser.

 

 

Every year I go skiing for a week in Austria. It’s nice to be able to get online to check mail and more, but wi-fi is still inexplicably not universal in holiday apartments, and roaming data charges are preposterous. However, it turns out that Austria has one of the most competitive mobile markets, and prices for mobile services seem really reasonable (compared to the UK at least).

After a bit of research, I settled on a “3SuperSIM” from Three (“Drei”). The tariffs seemed really good – 10GB for €9 would do just fine for a week, letting me surf and use Spotify etc without having to worry. I have an Android phone, so popping in the SIM and turning on the wi-fi hotspot function meant everyone on the trip could use it just like normal wi-fi internet.

Incidentally – it also turns out that you can use it in a few other countries. At the time of writing: the UK, Denmark, Sweden, Italy and Hong Kong.

So how does it work?

Firstly, you need to get hold of a SIM packet. You can order them online, but I doubt you can get them to ship it to an overseas address. Three have shops dotted about in major cities, but I bought mine in a general telecomms shop in Landeck. I think it cost me about €10. If they ask you (I can’t remember whether they did), opt for “Wertkarte” (pay-as-you-go) rather than “mit Anmeldung” (monthly contract).

IMG_20130311_094815

You’ll also need some credit (“Guthaben” in German), which comes in multiples of €10. You can buy it online with a credit card, but for the first trip you might want to buy it from the person who sells you the SIM. It’s also available in lots of other places (petrol stations, supermarkets etc). It’s sold in the form of a code on a printed till receipt which you load up online, and is called a “Ladebon”. Have a look at the tariffs and decide what you want, and get enough to cover that. Be aware though that the tariff rolls over automatically every month. (In other words, if you get the €4 tariff and load up €10 credit, it’ll eat €4 for the first month and then another €4 the next month when you’re probably long gone.) You can’t stop it – I phoned and asked them, because I’d initially loaded up €20.

Next, you’ll need to activate it and choose your tariff. When you put it in your phone (or your unlocked computer USB modem thingy if you have one) you’ll be asked for the PIN. This is printed on the plastic card you detached the SIM from. Once it’s in your phone, you’ll be able to at least get to the Three Austria website in your phone’s web browser, where you can do the activation. This is where you have to choose your tariff; you can’t change it later, so choose wisely.

You can also load up your credit on the site. If you’re not already logged in, you can log in with your phone number and your PIN. (If you’re having trouble logging in, try entering the phone number without the leading zero.)

In theory the SIM expires if you don’t use it for 12 months, but I popped it into my phone in the UK a few months beforehand to check, and got a “welcome to the UK” SMS from Three, so maybe that was enough to keep it alive.

That should be just about everything you need to know. The main downside I guess is that you’ll probably need a fair bit of German to be able to navigate the website.

%d bloggers like this: