Wednesday, June 26, 2013

C/C++: Async TCP Connection Failure Detection on OSX / BSD

As the hard-core C programmers know, the connect(2) function can operate in to modes:

  • blocking: the program will stop running until connection succeeds/fails/times out (latter can be as long as 30 seconds!)
  • non-blocking: connection is initiated only, and the socket's file descriptor can be checked if connection has completed or not (as a standard, check for writability with select(2)).
Whenever select(2) returns, we must be able to check if our connection attempt was the triggering event, that is, if the connection attempt has been finished or not.


One might believe the manuals and tutorials, which basically tell following:

To check the state of an asynchronous connection attempt, use getsockopt(2) to retreive the SO_ERROR value. If this is 0 (ESUCCESS), the connection has succeeded. If EINPROGRESS, the attempt has not been finished yet. Otherwise, the attempt has failed.
Problem: this is only true for Linux. On BSD (and yes, this includes OSX), when a connection is refused, getsockopt(2) will still return ESUCCESS. Even more strange, a write attempt to this socket simply makes the program exit - without a core dump.

What then?

According to this excellent summary, we are best off double-checking the state of the socket. The best option listed is issuing a getpeername(2) call, which either succeeds (connection established!) or fails (connection failed).

In code:
  // assuming connection is already in progress, select(2) has returned,
  // socket file descriptor is fd_:

  int err = -1;
  int len = sizeof(err);
  if (getsockopt(fd_, SOL_SOCKET, SO_ERROR, (int*)&err,
                 (socklen_t*)&len) != 0) {
    handleConnectionError("getsockopt error");
    return;
  }   
    
  struct sockaddr sa;
  socklen_t saLen = sizeof(sa);
  int gpnErr = getpeername(fd_, &sa, &saLen);
  
  if (err == 0 && gpnErr == 0) {
    handleConnected();
    return;
  }

  if (err == EINPROGRESS) {
    // do one more select(2) run on the file descriptor fd_
  }





Tuesday, June 18, 2013

Speeding Up Motorola Droid 2 / Milestone 2

I expect my phone to run smooth and fast. I mean, it _has_ the hardware to do so! My old server has a Pentium III processor ticking at 1GHz, it has 512M RAM. I even used Eclipse + Tomcat to code a web application for my thesis program in java!

The Milestone 2 has similar specs. Okay, different architecture, but still, I expect it to be pretty fast. And since I installed Viber, it became unusable and slow, sometimes having to wait ~10 seconds just to see the dialpad appear!

Buy a new phone? Galaxy S4 or Xperia Z, for ~$1000?? Naaaay.


Jelly Bean: a New Phone for Free

Thanks to the guys at xda-developers.com, Jelly Bean, the shiny new operating system is available for the Milestone 2 as well, via the CyanogenMod custom ROM.

Installing CyanogenMod in X Steps

  • Root the phone; see http://wiki.rootzwiki.com/Motorola_Milestone_2 for details. If you're paranoid, download the rooter from here and compile and run yourself.
  • Install Droid 2 Bootstrap Recovery; download for free from here (I did this manually, ie just gaining root on the phone but not installing the "su" command; just checking the error messages the installer gave me and typing the commands myself. Call me paranoid, but I like to see what's being done.)
  • Download CyanogenMod onto the sdcard - from here: http://code.google.com/p/cm-milestone2/downloads/list
  • Do the same with the official Google Apps - from here: http://goo.im/gapps

Speed Issue

While very happy with the slick UI, all the new features of Jelly Bean, the phone continued to crawl after Viber got reinstalled. What now?
Fortunately, CyanogenMod has a great built-in option: you can change the CPU governor. If a CPU supports it, Linux can decrease the clock speed if there's no demand, to save battery. Go to System Settings => Performance => CPU Governor, and select "Performance". Also, tick the Set on boot option, to make this change permanent.
While the phone got much snappier, I did not notice considerably less battery time. I think this is due to the fact that when the screen is off (most of the time), the phone sleeps (ie, CPU speed has no effect), and when it's on, the CPU usage is high anyway - due to all the effects, etc.
Another tip: turn off background data (maybe enable it selectively for a handful of applications). This will save bandwidth and battery.
Update: recently I installed LINE, but I had to realize it drains my battery extremely fast. Switching back to "Ondemand" governor solved this issue.

CyanogenMod too Risky?

In this case, "just" root the phone, and install an application that is able to set the CPU governor. (If you're a Linux guru, edit the boot scripts yourself from the terminal to issue "echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor" on every bootup.) 

Monday, June 17, 2013

Just Another HOWTO on Subversion-to-Git Conversion

I found many blogs detailing how to do this -- each tailored for different circumstances, some working, some producing strange error messages. Here is the workflow I used -- bare in mind, my SVN repositories are _very_ simple, contain no branches, no tags, and only I committed to them.

Set Up authors-transform.txt

This file is used to map SVN users to Git committers. The authors-transform.txt file should be plain text, containing lines like:
joe = Joe Smith <joe@smith.com>
jane = Jane Smith <jane@smith.com>

Clone the Subversion Repository

git svn clone <Subversion_URL> --no-metadata -A ~/authors-transform.txt --stdlayout
 Note: the URL should not contain "trunk".

Manual Fixes

The git svn clone creates a bidirectional repository, ie you can commit your changes back to SVN, and also make further updates. This is not what we want here - we want to migrate away from SVN for good.

The fixes I like to do manually:
  • create .gitignore file (use svn propget svn:ignore on a checked out svn rep)
  • check unhandled stuff in .git/svn/refs/remotes/trunk/unhandled.log -- e.g. keywords ($Id$, etc) are not supported by git
  • remove links to the Subversion repository (more might be needed, check your .git directory sturcture):
    • rm .git/refs/remotes/trunk
    • rm -r .git/svn
    • edit .git/config -- remove Subversion specific parts

Push to a Remote Repository

This part is less related to the topic, just for reference. Assuming you have a different host storing repositories:

[on the remote host] mkdir <git_repo_dir>; git init --bare <git_repo_dir>
[on the local host] git remote add origin <user>@<host>:<git_repo_dir>; git push -u origin master



Friday, June 14, 2013

Want a Lean and Fast Linux Desktop?

At work I used to have an AMD desktop with an Athlon 4450B dual-core processor and 3G mem. Not the most recent config, but should not be bad either.

Software being run:
  • Ubuntu Unity as desktop
  • Firefox
  • Thunderbird
  • occasionally a terminal
The system was still dead slow, even with regular Firefox restarts (FF being the main memory hog).

The Change

I wanted change, and after trying and reading about LXDE and XFCE, I settled with WindowMaker as the least resource hungry desktop. I remember having used it - conveniently - on a 300MHz Pentium in the 90's (an old Linux intro I wrote in Hungarian is still available online and shows my old desktop). Why not give it a try again? Guess what, it works like a charm, it's fast, easy-to-use and to configure:


The Details

- use Google Chrome instead of Firefox
- PCManFM (part of LXDE)
- install WM
- in ~/GNUstep/Library/WindowMaker/autostart add:

xset m 20/10 4
wmsetbg -u YOUR_BEAUTIFUL_BACKGROUND.png &
xscreensaver -nosplash&
sleep 0.2;
gnome-settings-daemon &






Sunday, June 9, 2013

PHP (and WordPress): Command-line 'gettext' Workflow from Scratch

Let's assume you are creating brand new code (for now say a WordPress plugin in PHP) intended for multi-language (internationalized) usage.

Writing the Code

Make sure to use the _() gettext function (WordPress: __(), _e(), and _x() functions) wherever translatable string literals are used, properly specifying the text domain as needed.
When using WordPress, make sure to call load_plugin_textdomain() from the 'init' action callback.
(Note that WordPress does not use the PHP gettext built-in functions, it has its own .mo file reader code in wp-includes/pomo directory.)

Files Involved

  • .po (Portable Object) files: ascii files containing translations (strings from the source code paired with translated strings
  • .mo (Machine Object) files: binary files containing the same information, can be read faster by programs
  • .pot (PO Template) file: contains untranslated strings only; usually completely overwritten after any code change (think of it as a temporary file used for empty .po generation)

The Initial Template

When the initial code is completed, a template ".pot" file needs to be created:

find . -iname \*.php | xargs xgettext --from-code=utf-8 -k__ -k_e -k_n:1,2 -k_x:1,2c -k_ex:1,2c -k_nx:1,2,3c -kesc_attr__: -kesc_attr_e -kesc_attr_x:1,2c -kesc_html__ -kesc_html_e -kesc_html_x:1,2c -k_n_noop -k_nx_noop:1,2c  -ctranslators: -o lang/messages.pot

Starting a new translation

An empty .po file needs to be initialized before we can start translating. Assuming we are translating into German:

cd lang
msginit -l de -o de_DE.po

For some reason, msginit creates a "de.po" file by default.
"locale -a" command to list all the locales installed on your system.
msginit sets encoding to ASCII, needs to be updated.

Translation Memories, Compendia

TODO: read pinfo about compendia & try tmx files.
- create translation memory: po2tmx -l xx -i pofiles -o xx.tmx
- apply it pot2po --tm=xx.tmx -i wordpress.pot -o wordpress_xx.po

Translating the Strings

Work can finally begin! Being a command-line and terminal enthusiast, I use VIm to edit the .po file; it has a great plugin helping in common tasks: po.vim.

Wrapping Up: Creating .mo files

...is simple:

msgfmt de_DE.po -o de_DE.mo

When using WordPress, make sure to prepend the "domain" to the .mo file name, e.g. myplugin-de_DE.mo

When the Code Changes

  • Re-create .pot file - see above
  • issue msgmerge -U de_DE.mo messages.pot

Further Read

http://codex.wordpress.org/Translating_WordPress
HTML-ized form of "info gettext": http://www.gnu.org/software/gettext/manual/gettext.html
PHP gettext docs: http://php.net/manual/en/book.gettext.php

Wednesday, June 5, 2013

Go!

I am a programmer. I like helping others. Back in 1999, the Linux Absolute Beginner's HOWTO I wrote (in Hungarian) even got published in GameStar.

There are many problems we find solutions for during the course of our life. It really helps to share the solution when found -- and a blog is the best place to do this.

If there is only one man finding relief here, creating it has already been worth it.