Software rot and maintenance

Software doesn’t exist in a vacuum — the environment and its inputs and outputs change over time. So it’s likely to break at some point and will require maintenance.

I’ve got a now-ancient static webgallery generator that I’ve tweaked and used for more than a decade. I enhanced it so that it creates animated gif thumbnails for movie files using a combination of transcode and mencoder. Recently, I added an MP4 movie file along with my photos. The web gallery generator chugged away longer than usual, and I gave it no notice — until it filled up my hard drive.

It wasn’t expecting to encounter an additional movie file format, and when it did, it went with the default of using ImageMagick to generate the thumbnail, instead of using my alternate solution for movie files — and ImageMagick filled up my hard drive with a giant temporary file.

So I edited the Perl-based web gallery program and added .mp4 and .m4v files to the list of special cases to be handled separately. It will work until the next time another new movie file format is encountered, and then I’ll need to maintain it again.

Nearly all software is that way — it must be maintained, or else it rots.

When CTRL-C in gdb shuts down a program insted of interrupting it

According to The Linux Programming Interface, a well-behaved multi-threaded UNIX program should use sigwait() or sigwaitinfo() instead of signal() or sigaction(). A linux-only program could even use signalfd().

Unfortunately, Linux/UNIX programs using sigwait() are hard to interrupt in the debugger. Instead of interrupting the program, it terminates the program. How does one work around this problem? See my answer on stackoverflow.

 

C++ initializer lists

One of the cool new features in C++ is initializer lists. Here’s an example from Wikipedia:

struct Object { float first; int second; };

Object scalar = {0.43f, 10}; // One Object, with first=0.43f and second=10 Object anArray[] = {{13.4f, 3}, {43.28f, 29}, {5.934f, 17}}; // An array of three Objects

There’s another example over at stackoverflow.

IBM has published the useful C++0x feature support in GCC 4.5.

Autojump: Faster than ‘cd’

Here’s a cool tool: autojump, written by Joel Schaerer (thanks, Joel). I spend much of my day as a programmer navigating around in the linux filesystem. Built-in tools like ‘pushd’ and ‘popd’ are nice, as are subprocesses — e.g.

 (cd ~/Download && wget http://somewhere.com/path/to/file)
… and when it finishes downloading, I’m still in the directory I was in before the download was started.

Now there’s autojump to add in to the mix. After I ‘cd’ to various directories, later, I can type ‘j Down’ to cd to my Downloads directory. Very convenient. I just wish it were built into every distribution of linux.

Pitfalls of verifying signed jar files

In the Java world, it’s possible to digitally sign a jar file using ‘keytool’ to generate or import a digital signature, and ‘jarsigner’ to do the signing. What isn’t so obvious is that when we use ‘jarsigner’ to verify a signed jar, it doesn’t verify that we trust the signature that signed the file. It simply tells us whether the contents were signed by a public key that was included with the jar file.

Surprisingly, there’s no option to tell jarsigner to check for trusted signatures.

In code, we can use java.util.jar.JarFile to check the validity of a jar file. By default, the constructor to JarFile says we want to check the validity. Code must then iterate through each entry in the JarFile and seek to the end of each input stream, otherwise, the integrity isn’t checked. In other words, the java.util.jar.JarFile doesn’t give us the integrity checking with a simple method call such as isValid(), and it doesn’t give us an easy way to check that we trust the signature that the entries were signed with.

Anyone, anywhere, can create their own certificate, and sign a jar file — so if we want to establish trust for a signed jar, we get to do extra work. On stackoverflow.com, Jarek Przygódzki linked to code that shows how to check for trusted signatures.

I wonder why establishing trust for a signed jar isn’t easier. Could it be that signed jar files originated in the bygone era when we ran Java applets in our web browsers? Did web browsers use their certificate authority database to verify some level of trust for the signature contained in a jar file?

Verifying trust is a delicate issue, as demonstrated by the recently hacked certificate authorities including Diginotar and Comodo. Perhaps it’s a good thing that Java’s libraries and command line tools don’t make it deceptively simple to check jar files based on certificates trusted by Certificate Authorities.

Still, I wish the documentation for jarsigner and JarFile would shed more light on the limits of their default verification. I’d call it “hash checking” or “integrity checking based on hashing”.

 

ORM Solutions for C++ and sqlite: hiberlite, SOCI

I think SQLite is a great database for a C/C++ application to use. It sure is easy to query the data that way, without intrinsic support from the application. When the application changes, the database is still accessible via standard sqlite clients. Yet using SQLite in an application can require a lot of repetitive code to serialize objects to and from the database, so I wondered if there are ORM solutions for C/C++. It turns out that there are. I only had to turn to stackoverflow.com to find the following (among many):

  1. Hiberlite
  2. SOCI

Teriffic Linux Books

One of my QA coworkers had The Linux Phrasebook sitting on his desk. I noticed it was by Scott Granneman, and immediately thought, “if it’s by him, it’s got to be good.” As I thumbed through the pages of the book, I was impressed at the practical coverage of command line utilities including yum and rpm, apt and deb, etc. I highly recommend this book. It’s small so it’s easy to keep on hand.

For anyone wishing to write applications that take advantage of all that Linux has to offer, I recommend The Linux Programming Interface (also available from Amazon), aka TLPI. I used to recommend Stevens’ Advanced Programming in the UNIX Environment, but now I recommend TLPI because it is more comprehensive and just as readable. It’s not a small book, so a PDF makes it easier to keep on hand. I purchased my copy through the publisher, NoStarch with the coupon code “Mamaku” that gave me 30% off and a free PDF. The order total came to $80.00, including shipping.

Awesome Linux profiling tools: top -H and pstack

When I needed to figure out where the performance bottlenecks were in some Linux software, I found helpful answers at http://stackoverflow.com in the form of two tools: 1. naming threads in combination with “top -Hp <pid>” and 2. “pstack <pid>”. The first was helpful in watching which threads were consuming the most CPU. The second was useful in sampling the application over time to find the hot spots and their stack traces.

  • How to name a thread in Linux (or a process) — use prctl().
  • How to use stack sampling to find performance problems — use pstack.

Miscellaneous Linux tips and tricks

Gnome Key Bindings and IntelliJ IDEA

IntelliJ IDEA key bindings conflict with Gnome’s window manager. In IDEA, I can type CTRL-B to jump to a symbol definition. Normally, I’d type CTRL-ALT-LEFTARROW to navigate back to where I had come from. Gnome’s MetaCity intercepts that key mapping before IDEA sees it, and tries to move my desktop to the left. There are several other Gnome/Metacity key bindings that conflict with IntelliJ IDEA. Rather than remap the keys in Gnome, I found that on Fedora, I could add the Windows key to the mix, and Gnome would ignore it, and pass it along to IDEA. This means that I can type CTRL-ALT-WINDOWS-LEFTARROW to navigate backward, and so forth.

Unfortunately, this doesn’t work in RHEL 5 and CentOS 5. The solution is to Go to the Gnome menu bar and select System > Preferences > Keyboard (not Keyboard Shortcuts). Then select the “Layout Options” tab, and expand the “Alt/Win key behavior”. Then I select “Super is mapped to the Win-keys”.

Every time I log in after that, Gnome tells me that my X keyboard settings conflict with my Gnome Keyboard settings, and it asks which I want to use. Selecting the Gnome settings is what I want.

Bandwidth limiting downloads with ‘curl’ or ‘wget’

When downloading a large file, it’s nice to be polite to others on the network, so I use the --limit-rate option for curl and wget:

  • curl -O --limit-rate 20k http://server.com/linux.iso
  • wget --limit-rate=20k http://server.com/linux.iso

GDB TUI (text user interface)

After starting gdb, it’s possible to switch to its text user interface with CTRL-X, CTRL-A. Typing it a second time exits TUI mode.

Vim C++ Auto completion with ctags

I appreciate full blown IDEs in Linux, but I like the quick start up time of vim. Until recently though, I didn’t have C++ auto completion (also known as vim omni completion).

This got me up and running, and was a great resource: http://vim.wikia.com/wiki/C%2B%2Bcodecompletion

This would have been useful if I was a new comer to vim and ctags: http://www.justlinux.com/nhf/Programming/IntroductiontoC_Programming.html

xdg-open, gnome-open, start, cygstart

How to easily open files and URLs from the command line http://www.dwheeler.com/essays/open-files-urls.html

  • Linux: xdg-open filename_or_URL
  • Linux: gnome-open filename_or_URL
  • Mac: open filename_or_URL
  • Windows: cmd /c start filename_or_URL
  • Cygwin: cygstart filename_or_URL

Nomachine NX and ALT-TAB

I use the Nomachine NX client from time to time to get a remote-desktop like connection to a remote Linux machine. It’s faster than VNC, but it suffers from not forwarding all of my keyboard shortcuts to the remote end of the connection.

Usually, I start the nxlcient from within a Gnome login session. Gnome happily grabs ALT-TAB before the NX client gets to see it. That’s not what I want. To work around this limitation, I log into a virtual terminal, and start X manually as follows:

Type CTRL-ALT-F2 Login Run: startx -- :1 gnome-terminal

From the gnome-terminal, run: nxclient

And then I connect to the remote machine in full screen mode. There’s no local window manager to interfere with my keyboard shortcuts.

Remote desktop and dual screens

I’ve been using Remote Desktop to connect to Windows XP, Vista and 7 machines. Until Windows 7, there was no way for a local computer having dual monitors to connect and have the remote end display across both monitors.

So I used linux’s ‘rdesktop’ program to do it:

rdesktop -0 -a16 -f -rdisk:CLIENT=/home/jared/Desktop -r sound remote.host.com

I notice that in Windows 7, there are some new options in the Remote Desktop client (mstsc.exe): /multimon and /span. Or run mstsc /? to list all possible options.

Editing windows registry files on Linux

Use Gedit: gedit --encoding=UTF-16LE myfile.reg

Gvim: LANG=UTF-16LE gvim myfile.reg

If already in gvim: :e! ++enc=utf-16le or :e ++enc=utf-16le myfile.reg

Convert, edit, convert:

iconv -f UTF-16LE -t utf-8 myfile.reg > myfile.reg.utf8

Edit myfile.reg.utf8, then convert it back

iconv -f utf-8 -t UTF-16LE myfile.reg.utf8 > myfile.reg

How Firefox opens files and mime types

I needed to give Firefox some extra help knowing how to open a custom file type with a custom application. Here’s some helpful information.

https://developer.mozilla.org/en/HowMozilladeterminesMIMETypes

Firefox uses mime.types on Linux, as well as other things. I helped Firefox by the mime type to the link in the generated HTML file. Either one of the following seems to work:

  • <a href=”file:subdir/file1.cst” type=”application/octet-stream”> open file </a>
  • <a href=”file:subdir/file1.cst” type=”application/x-extension-cst”> open file </a>