Rust: Libraries

If you’re following the Rust line of posts, you’ve read Rust: “Hello world!”. If you were paying close attention you noticed a peculiar looking function call: println!("Hello, world!");

This function call isn’t actually a function call, it is a macro. Oh, OK, wait a minute. I never defined a macro in my Hello world! code! How did it even compile?

The answer is that the Rust compiler prefixes this line to every crate root:

extern mod std;

And the compiler also inserts this line into every module body:

use std::prelude::*;

The first line essentially imports the Rust Standard Library (std) into the crate, and provides std::println!. This is analogous to #include in C++.

The second line doesn’t have any effect on the Hello world! code, but it is important to note. It re-exports many common definitions from std so that we don’t need to use global names for things like std::string::String. This is analogous to using namespace std; in C++.

Wait. What are crates and modules? All we did was generate a Hello world! program with cargo! Well, in Rust, the source code that is compiled into a binary is a crate. Modules are divisions within a crate. Further, every crate has a root module by default; you don’t declare it, it is done automatically. So our Hello world! program is organized like this:

// the crate root module begins here and contains 
// only the main function

fn main() {
    println!("Hello, world!");
}

// the crate root module ends here

A more interesting example:

// the crate root module begins here and contains 
// the main function and module foo

mod foo {
    // module foo begins here and contains two 
    // functions fooD and fooE

    fn fooD() { println!("Foodie"); }
    fn fooE() { println!("Fooey"); }

    mod bar {
        // module bar begins here and contains the 
        // function barN
    
        fn barN() { println!("Barren"); }

    }   // module bar ends here
} // module foo ends here

fn main() {
    println!("A more interesting example.");
}
// the root module ends here

Note that Rust uses // for line comments. Rust also supports C-style block comments with /**/ but the Rust style guide discourages their use.

Putting it all Together:
Say we’d like to write program that uses the tcp module from the Rust Standard Library. Our program could look something like this:

use std::io::net::tcp;

fn main() {
    let listener = tcp::TcpListener::bind("127.0.0.1:80").unwrap();
    // do net stuff

}

Rust: “Hello world!”

Rust is a multi-paradigm, applications and systems programming language. It has yet to reach 1.0 but senior C++ developers are predicting it will supersede C++ in the future.

First, download Rust from its website. Then extract the tarball, run the install script and clean up.
install

$ tar -xf rust-nightly-i686-unknown-linux-gnu.tar.gz && sudo rust-nightly-i686-unknown-linux-gnu/install.sh && rm -r rust-nightly-i686-unknown-linux-gnu/ && rm rust-nightly-i686-unknown-linux-gnu.tar.gz

Now create a Hello World! project using Rust’s package manager Cargo:

$ cargo new hello_world --bin

Take a look around in the hello_world directory. You’ll find a manifest file and a source directory. The source directory has main.rs, the generated Hello World! program.

fn main() {
    println!("Hello, world!");
}

Compile and run our Hello World! program from the hello_world directory:

$ cargo run

A similar program in C++ looks like this:

#include <iostream>

int main(void) {
	std::cout << "Hello, world!" << std::endl;
	return 0;
}

Like most Hello world! programs these are trivially different in their result. The main difference is that the main method in the Rust program is a void method while it returns an int in the C++ program. This difference could change the behavior of a non-trivial program, but for Hello world! it has no effect.

A Little Perspective on NCAA Sports and University Education

The University of Alabama at Birmingham announced that it would implement cuts to its athletics program. The largest cut is the entire football program. The rifle and bowling programs also experienced cuts.

This is a photo of the reaction:
© AP Photo/AL.com, Joe Songer UAB Prsident Ray Watts is led through an angry mob by Birmingham and UAB Police

© AP Photo/AL.com, Joe Songer UAB Prsident Ray Watts is led through an angry mob by Birmingham and UAB Police
I particularly like the man in the blue polo shirt. I suspect his lips aren’t pursed due to the bowling team cuts.

On 13 April, 2013, the University of Southern Maine cut its Music program down to one professor.

This is a photo of the reaction:
© The Free Press/usmfreepress.org, Music students protest cuts to music program.

© The Free Press/usmfreepress.org, Music students protest cuts to music program.
While not the size of UAB’s athletics program – the department was cut in half from two faculty to one, this cut affects students’ course of study, not their extra-curricular activities. Also note that UAB is not cutting the budget to the athletics program, rather they are eliminating some sports so that their resources may be allocated to the retained sports. These photos speak volumes regarding the emphasis placed on athletics versus education in the US university system, particularly in NCAA schools. Take a look at the students’ reactions, they too are culpable in this apparent bias towards NCAA athletics.

PDT For Eclipse Install Error

I am installing the PHP Development Toolkit for Eclipse (PDT) and received this error:

"Cannot complete the install because one or more required items could not be found.
Software being installed: PHP Development Tools (PDT) Mylyn Integration 3.3.1.201409161013 (org.eclipse.php.mylyn.feature.group 3.3.1.201409161013)
Missing requirement: PHP Development Tools (PDT) Mylyn Integration 3.3.1.201409161013 (org.eclipse.php.mylyn.feature.group 3.3.1.201409161013) requires 'org.eclipse.dltk.mylyn.feature.group 0.0.0' but it could not be found"

The error is due to my Eclipse installation missing org.eclipse.dltk.mylyn.feature.group 0.0.0, obviously. The gotcha is that it should be readily available from one of the update sites listed in the Install New Software dialog, however, it is not. To fix this error, add http://download.eclipse.org/technology/dltk/updates-dev/5.0/ to your update sites and retry the install.

A Little Perspective on Ebola in America

In light of the Ebola news coming out of America, and some acquaintances’ propensity to fall for the mild hysteria being promoted by the mainstream media there, I’m going to use summary statistics to provide a bit of perspective on Ebola risk in the United States.

I make a few assumptions that are likely quite wrong, but given I have no domain knowledge in anything but the traffic stats they should be reasonable for the purpose of perspective.

  1. People in the USA are homogeneous, there is nothing one can do to change their risk of an event occurring
  2. a priori probabilities are sufficiently accurate at estimating risk given (1)

From Delaware Online

“We see in the news lots of information making us very concerned,” Michelle Parent, an associate professor and interim chair of medical laboratory sciences, said during a lecture. “But I think it’s important for us to know what the risks really are.”

In the U.S. it is estimated that the risk of contracting the disease is 1 in 13.3 million if there are 12 cases imported from other countries. There have been nine cases in the U.S. and one death. The chances are better that someone would die from lighting, bee stings or shark attacks.

The only way to get the disease is for bodily fluids from an infected person to come into contact with cuts or mucous membranes. It cannot be transmitted through the air or by insects, and it does not last long outside of the human body.

Bleach, alcohol and vinegar all kill the virus.

“When it comes to viral infections, it is actually relatively easy to kill,” Parent said.

The reason why the disease has been so deadly in West Africa is that the healthcare infrastructure there is so poor, the faculty said. Liberia, for example has an estimated doctor-to-patient ratio of 70,000 to 1, compared to a 400-to-1 ratio in the U.S.

That shortage has been exacerbated because many healthcare workers fled areas where the infection was spreading and creating a greater demand on remaining workers. In addition, those workers don’t have protective gear, cleaning materials and other supplies to properly treat the disease.

So, we start with the risk of contracting Ebola in the US: 1 in 13.3 million, or p = 0.0000075%. Yes, you read that correctly, the probability is very close to zero. In fact, I don’t think FOREX carries that many places after the decimal. Note that if you’re a math-type, that would be p = 0.000000075, but I’m going to use % here because it’s more familiar to a greater portion of the population.

As it turns out, people tend to perceive unfamiliar events as having greater risks than is supported by evidence so we’ll begin this comparison with equally unfamiliar events in the USA.

Please note that one’s familiarity with events is unique. The above are events which I have never felt the slightest possibility of experiencing. Your experience may be different. Also note that the lowest risk event, death by legal execution, is still three times, i.e. 300% more likely than contracting Ebola in the USA!

Let’s move on to events that I consider to be more familiar than the above.

You are about 1,400 times more likely to die in the next year by your own hand than you are to contract Ebola! In fact, the only event studied so far with a lower risk than contracting Ebola is death from ignition of sleepwear, and its risk is just slightly lower.

So far we’ve only looked at what I would call non-medical events. Being that Ebola is a medical event, let’s consider two other medical events.

One is more likely to die from complications due to pregnancy next year than to contract Ebola, in fact, one is almost 28 times more likely. I’ve never heard pregnancy discussed as a risky activity during my lifetime in the US. That being said, the mortality rate in the US due to pregnancy is on the rise, and the highest of any similar nation, but that is another story. Consider the AIDS epidemic in America, which pales in comparison to the AIDS epidemic in Africa. Now consider that one is over 2500 times more likely to be diagnosed with HIV next year in America. Further, the average risk of death from Ebola is 50%, much lower than the risk of death associated with HIV/AIDS so while half of Ebola diagnoses are followed by death, nearly all HIV diagnoses are followed by death.

I figured that the risk of contracting Ebola in the US was comparatively low before researching this post. A few surprises did pop out though. First, 18 out of 100,000 people suffocate in bed each year and is frighteningly similar to the reported rate of death due to autoerotic asphyxiation – 16 out of 100,000. We’re more likely to die while occupying a car than while riding a bike. As a long time bicycle commuter I was shocked, and pleased I’m usually on the better side of those odds.

In closing, I realize that statistics are to be used like a scalpel and I’ve wielded it like a flamethrower. It’s obvious that my risk of dying from complications due to pregnancy is 0. Similarly, my current risk of death by legal execution is also 0 since I have been convicted of no crime. The point is that Ebola is not some frightening epidemic in America yet. It is not even pandemic. I doubt Ebola could become epidemic in America or any other country with similar population density and sanitation, unless it mutates. We should be prepared, but not give in to hysteria.

TomTom GPS Watch For Linux

I recently purchased a TomTom Multisport Cardio and I love everything about it except that its MySports Connect app does not support Linux systems. The most troubling aspect of this is that the OS on the TomTom is largely taken from Linux. I say taken because they have yet to give anything back to the community which provided a critical key to their success.

I set out to find a way to get the MySports Connect app to run on a Linux system. I was partially successful in doing so through virtualization. So technically, I didn’t get MySports Connect to run in Linux, but with freely available virtualization software it’s good enough.

Before you go any further. I was successful in starting the MySports Connect software, downloading the data from the watch, and performing every function except connecting to mysports.tomtom.com and posting to external fitness sites. My solution won’t help you if you require these functions.

Solution
Install some virtualization software:
I downloaded VirtualBox 4.3.18 for Linux hosts and VirtualBox 4.3.18 Oracle VM VirtualBox Extension Pack from https://www.virtualbox.org/wiki/Downloads. Select the packages for your distribution – I run crunchbang “Waldorf” and used Debian “Wheezy” successfully – and follow the installation instructions.

Now you need a system image for an OS which is supported by both your virtualization software and MySports Connect. I chose Windows XP because I have only 1GB memory on my box and any newer version would require at least 1.5GB for the guest and host combined. Download a trial image from Microsoft at .

Fire up your VirtualBox, VMWare, etc., and install the System image you just downloaded. In VirtualBox you simply select “New” and follow the prompts. Now open the preferences for your new VM. You need to select “USB” and check the “Enable USB controller” and “Enable USB 2.0 (EHCI) controller” boxes. You’ll also need to add yourself to the vboxusers group.

# useradd -G vboxusers < user-name >

Start the windows virtual machine. The first thing you should do is install the guest additions. You’ll probably need to restart the VM. Now open a browser in your VM and download the MySports Connect app installer from TomTom. Follow the installation instructions from TomTom.

The MySports Connect app should automatically run anytime a TomTom GPS watch is connected to the VM. To connect your TomTom:

  1. Place TomTom in dock and connect USB cable to your computer
  2. Ensure TomTom is connected by clicking on the USB icon at the bottom of your VirtualBox/VMWare window – the TomTom’s name will appear if it is connected
  3. Click on the “Devices” menu and select your TomTom from the list

The MySports Connect app will start and you’ll likely need to wait a long time for it to update the firmware on your TomTom. Once the update is complete, you can use the app to download data from the watch, perform a factory reset, update firmware, manage user profile/settings, everything except the automatic post to mysports.tomtom.com and other fitness sites.

Now here’s my argument for why the reduced functionality really doesn’t matter yet. MySports is almost as impotent a web fitness site as mapmyfitness.com. I am a member on mapmyfitness but am in the process of moving to SportTracks because it comes highly recommended, though it is not free. TrainingPeaks is a free training log which also comes highly recommended. Note that SportTracks does not support Linux, but that doesn’t matter since you’re now a virtualization ninja!

So there’s how you use TomTom GPS watches on a Linux platform. I highly doubt TomTom plans to port MySports Connect to Linux anytime soon. Truthfully, I’d rather they put that effort into integrating great analytics into their MySports site because right now it’s just an electronic log and the UI is a bit cumbersome.

Lastly, some notes:

  • I only tried virtualization with Windows XP, Vista (unlikely), 7, 8, or 8.1 may perform better
  • Privilege issues may be keeping the MySports Connect app in the VM from connecting to TomTom’s site; I’ll play with them later

~/.xsession-errors Consumed My Hard Drive: My Best Solution

In my last two posts, I described the ~/.xsession-errors problem and proposed an OK solution using logrotate. I also made a case for logrotate not being a good solution. In this post I give my best solution. As before, I’ll post the code for those who just want to cut and paste without knowing what’s going on, and I’ll follow that with a more detailed explanation of the code.
note: <user> should be replaced with your username on your host.

Code Only (assuming you’ve already implemented the logrotate solution)

# apt-get install incron
# echo root >> /etc/incron.allow
# incrontab -e
/home/<user>/.xsession-errors IN_MODIFY sudo logrotate /etc/logrotate.d/xsession-errors
# nano /etc/logrotate.d/xsession-errors
/home/<user>/.xsession-errors
{
rotate 1
size 64k
copytruncate
missingok
compress
}
# incrond

or restart.

Full Solution
The first thing you need to do is install incron, a program which works like cron, but is triggered by file events rather than time. I did not need to add any new repos to my sources, but you may so I’ve included the code to do that as well. First try to install incron and if it fails due to apt not being able to find the package, add the repo.

# nano /etc/apt/sources.list
[...]
# Debian backports, added to install incron
deb http://backports.debian.org/debian-backports squeeze-backports main
[...]
# wget -O - http://backports.org/debian/archive.key | apt-key add - 
# apt-get update
# apt-get -t squeeze-backports install incron

The backports repo is inactive by default, so you’ll need that -t flag and argument. Also note that my version of crunchbang is based on debian squeeze. Replace squeeze with your distro’s nickname if it is based on some other version of debian. If you’re not using a debian derivative, you’ll need to search for incron in the repos applicable to your distro.

Now you add root to incron allowed users list.

# echo root >> /etc/incron.allow

The reason you need to allow root and not your user is that the logrotate command requires superuser privileges.

Now you create root’s table for incron.

# incrontab -e
/home/<user>/.xsession-errors IN_MODIFY sudo logrotate /etc/logrotate.d/xsession-errors

I’m not sure if that sudo needs to be there or not, but it’s not hurting anything. Someone could try omitting it and report back the results.
If you read the code only solution, hopefully you noticed that the /etc/logrotate.d/xsession-errors file is different from the previous solution. I changed the rotate number to 1 because I only want one compressed ~/.xsession-errors file not two. The size is obvious. Now for the key: copytruncate. Without it, logrotate just compresses the file to ~/.xsession-errors.1.gz, so we’re left with only the compressed log. Since ~/.xsession-errors doesn’t exist, the file descriptor in the processes that had access to it are now invalid. So why not just create a new ~/.xsession-errors? Processes don’t use file names to access files, they use file descriptors, and creating a file with the same name does not automatically update the file descriptor in the processes file descriptor tables. So, even though ~/.xsession-errors exists, the processes don’t have a way to access it. copytruncate solves this problem by sending the contents of ~/.xsession-errors to ~/.xsession-errors.1.gz without deleting ~/.xsession-errors, so the file descriptor to ~/.xsession-errors in each process’s file descriptor table is still valid! This problem could also be solved by immediately rebooting after logrotate runs since X will create a ~/.xsession-errors on startup if one doesn’t exist, but there are two issues to consider:

  • You may not want to reboot, e.g. the machine is a server
  • The ~/.xsession-errors spam may be occurring on reboot

The first case is obvious. The second case should be obvious. Consider that during boot, X starts up some process foo which immediately spams ~/.xsession-errors with garbage until incron gets the signal, calls logrotate, and then reboots. This results in an infinite loop of frustration! So just put copytruncate in /etc/logrotate.d/xsession-errors and be done with it.
Lastly, you need to start the daemon that services incron. You may either invoke it on the command line or just reboot your system.

# incrond

That’s it. I tested this solution, and all of the non-solutions leading up to it, by manually spamming ~/.xsession-errors from the terminal.

$ for i in {1..256}; do cat <file> ~/.xsession-errors; done

Where <file> is the path to some file with size greater than 256B -> logrotate limits ~/.xsession-errors to 64kB and 256 x 256kB = 64kB.
Yes, this solution is really just using incron as a pass-through to logrotate, and while that seems inefficient, consider that the most time consuming operation here is the compression called from logrotate. Another performance consideration is that incron runs each time ~/.xsession-errors is modified. If you have some broken process spamming ~/.xsession-errors with errors 64B at a time, incron and logrotate will have to run a lot of times before the 64kB limit is reached. I justify the expense of such a low probability situation two ways:

  • If you want to make sure ~/.xsession-errors never grows larger than some limit, you must check it each time it is modified
  • Chances are, the broken process is wreaking more havoc than incron and logrotate

So there you have it. Tomorrow, or um sometime this week, I’ll show how I got the TomTom Multisport Cardio to work on Linux.