Tuesday, 23 February 2010

Bash/shell scripts aren't working on Ubuntu

I was just writing a shell script - it all worked fine on the command line so I put it in a file and ran it:
% sh myscript.sh
But it generated an error - specifically I was trying to use brace expansion (a Bash only feature) which it now didn't seem to like. What the heck?

It turns out that on Ubuntu they have switched to a faster-simpler default shell (/bin/dash) - which does actually help to improve boot times - but is no longer bash compliant (so no fancy features - just POSIX 1003.2 features only). So what's happening is that my script is being run by dash - despite it the fact it starts with the usual #!/bin/bash - which confused the hell out of me. Anyway watch out if you've got lazy old habits like assuming that sh is bash.

Friday, 19 February 2010

unconnect() a UDP socket

So you've got a UDP socket and you've called connect() on it to make it send or listen to a particular IP address, but then you need to disconnect it again, without destroying it. Why would you want to do that?? Well on some OSes (ie Mac OSX, BSD) if you're connected to UDP socket on a machine you can only do that once with the same address (even when you're using the REUSEADDR stuff). So anyway you can disconnect() or unconnect() your socket by the doing the following:
int disconnect_udp_sock(int fd) {
 struct sockaddr_in sin;        

 memset((char *)&sin, 0, sizeof(sin));
 sin.sin_family = AF_UNSPEC;
 return (connect(fd, (struct sockaddr *)&sin, sizeof(sin)));
}
On some OSes you may get a dodgy return value but according to the connect() man page it's ok.

Monday, 8 February 2010

Stop Windows [re]installing [dodgy] drivers

If you have the issue where an 'official' driver that comes down with Windows Update is basically broken then you need to disable the update mechanisms for that device. In Windows (Vista, and probably WinXP, Win7) you can stop Windows from updating drivers for specific hardware by using Windows' Local Group Policy Editor:
  • Start Device Manager by going to 'Start' button and typing devmgmt.msc and hitting return
    • Locate your dodgy device and click on Properties
    • Copy the 'Hardware ID' from Properties->Details->Hardware ids
    • Right click on device and select uninstall
  • Start Policy Editor by going to 'Start' button and typing gpedit.msc and hitting return
    • Edit the following key(s): Local Computer Policy->Computer Configuration->Administrative Templates->System->Device Installation->Device Installation Restrictions->Prevent installation of devices that match any of these IDs.
    • Paste in previously copied dodgy Hardware Ids. e.g:
      PCI\VEN_10DE&DEV_0042&SUBSYS_97511462&REV_A1
      PCI\VEN_10DE&DEV_0042&SUBSYS_97511462
      PCI\VEN_10DE&DEV_0042&CC_030000
      PCI\VEN_10DE&DEV_0042&CC_0300


  • Reboot
In my case the dodgy driver in question is for an oldish NVidia card - Vista thinks it is an GeForce 6800 LE (whilst Linux thinks it's a Quadro NVS 280 SD - where it actually works ok) and the latest drivers (11 Jan 10) still result in total system crashes (machine just freezes - no 'screen of death') when I do mundane things like bringing a PDF document up in Adobe Acroreader or clicking on the 'office button' in Office 2007?!

    Friday, 5 February 2010

    Handy iphone tips

    A few things I've discovered with my iphone:
    • Use Caps lock on the keyboard
      1. Make sure it's enabled it in prefs: Settings->General->keyboard
      2. To use when using typing - double tap the shift key and goes blue!
    • European variant letters (accents, umlaut etc) on keyboard
      • Tap and hold "e", "a", etc
    • Add .com or .co.uk when typing an web/email address:
      • Tap and hold on the '.' key
    • Go to top of any scrolled window/app:
      • Tap on the very top bar (with the time in it)
    • Kill any app (OS3+ only):
      1. Push and hold power button till "Slide to power off" shows
      2. Let go of power button
      3. Push and hold 'home' button for more than 5 secs and the app dies
    • Reset your iphone:
      • Push and hold both the power button and home button for more than 10 secs
    • Take a screen shot:
      • Push home button, then click power button