Browse Tag

Programming

Perl sig-int and open

skip to solution

While recently re-writing our build script into a simple perl script I came across a problem.

I wanted to have the script put output from the commands that it was executing onto both the screen and into a file at the same time.

No problem, in perl you can open commands like you can files, by simply putting a pipe ‘|’ as the first character.

open(OUT, ">log.txt")
    || die "can't open log: $!";
open(STATUS, "netstat -an 2>&1 |")
    || die "can't fork: $!";
while () {
    next if /^(tcp|udp)/;
    print;
    print OUT;
}
close STATUS || die "bad netstat: $! $?";

This code will output the lines to both stdout and to a log file.

Great nice simple code that works using standard perl operations. However one thing that this does not provide is that the forked processes do not receive ‘Ctrl-C’ or ‘Sig-Int’ if you are more of a Unix head.

Which is really quite bad when you are creating a build script you want all processes to die if you need to pull the plug on a build.

So next I turned to calling a direct windows api call GenerateConsoleCtrlEvent calling this function on all child processes in a perl sig-int handler to send CTRL_C_EVENT (0) to each of these processes.

use Win32::Process::Info;
use Win32::API;

$SIG{INT} = 'killChildren';

sub killChildren
{
    print "Killing process\n";
    my $pi = Win32::Process::Info->new ();

    Win32::API->Import('Kernel32.dll',
'BOOL GenerateConsoleCtrlEvent(DWORD dwCtrlEvent,  DWORD dwProcessGroupId)');

    my %children = $pi->Subprocesses($$);
    foreach my $child (@{$children{$$}})
    {
        GenerateConsoleCtrlEvent(0, $child);
    }
    exit(1);
}

However if you read the documentation of GenerateConsoleCtrlEvent closely:

Sends a specified signal to a console process group

So then you realize that the process must be created in a process group by calling CreateProcess and passing a CREATE_NEW_PROCESS_GROUP flag. Which is getting to be way too much work there must be a simpler way surely.

The solution I eventually came up with was perl calling via the system command and running an inline script.

open(CMD, "$^X -e \"system(q{$cmd});\" |") || die "Failed to run \"$cmd\": $!\n";

However since the commands I were executing had ” in them as well there were too many variants that were requiring regex replacement to get the commands working correctly.

So like any good web monkey I ended up Base64 encoding the command I wish to execute and then un-encoding it in the sub perl process.

Final Solution

sub RunCommand
{
    my ($cmd, $dontStop) = @_;
	print "$cmd\n";
	print BUILDLOG "$cmd\n";
	# Run the command through another instance of perl so that it can all be
	# killed when Sig-C is sent to this build file.
	# However command contain characters such as \ and " which are hard
	# to pas through 2 interpreters so base64 endcode and decode the command
	# $^X is a special variable that is the path to perl
	my $encoded = encode_base64($cmd);
    open(CMD,
  "$^X -e \"use MIME::Base64;system(decode_base64(q{$encoded}));\" |")
  || die "Failed to run \"$cmd\": $!\n";

    while()
    {
        print "$_";
        print BUILDLOG "$_";
    }
    close(CMD);

    if(!$dontStop and $? != 0)
    {
        die "Command: $cmd\nFailed with code: $?\n";
    }

    return $?;
}

time_t and printf

The bane of my existence is work where I use c++ primarily with MFC.

Now today I have come up to one or the most strange occurrence while debugging the database code in our product. I was formatting a string with sprintf and all of my time values were being formatted as “(null)“.

I know we should really be using parameterized queries but this is legacy code created by PC software guys, and I really don’t know if ODBC supports it in a database agnostic way.

Now we have been using Visual Studio 2005 for years but this code has not been working for years, the problem showed up around the database purging code.

When looking in the debugger at the formed SQL I noticed “(null)” showing up instead the numbers I was expecting.

It turns out we were using time_t as the type being fed into sprintf which under this version of Visual C++ is actually a 64-bit integer, or unsinged long long.

So the solution to this rather strange error in formatting is also quite strange, as in how do you format a unsinged long long into sprintf. Well it’s rather simple just add another formatter charter so if you have a signed long long use %lld or if you have a unsinged long long use %llu.

I hope you don’t get tripped up like I did. And if you were wondering why there was “(null)” in the string it’s because the next token was a string, %s, and intel architeture is little endian making the upper 4 bytes all zero, ie null.

Vertical text align of radio buttons in java

I have been doing some GUI java code in both swing and SWT recently and find text alignment a niggling annoyance of mine. Often you want to align components with the text line vertically of combo or check boxes.

Here is the code for determining the width in pixels for the two most popular GUI libraries in java. Both are cross platform/look-and-feel solutions.

Swing

JRadioButton radio = new JRadioButton();
int raddioButtonOffset =
    UIManager.getIcon("RadioButton.icon")
        .getIconWidth()
    + radio.getIconTextGap()
    + radio.getInsets().left;

SWT

// get the width of a space
GC gc = new GC(parent);
int spaceWidth = gc.getAdvanceWidth(' ');
gc.dispose();

// create radio widget to get widths
Button radioButton = new Button(parent, SWT.RADIO);
Point baseSize =
    radioButton.computeSize(SWT.DEFAULT, SWT.DEFAULT);
radioButton.setText(" ");
Point withSpaceSize =
    radioButton.computeSize(SWT.DEFAULT, SWT.DEFAULT);
radioButton.dispose();

int radioButtonOffset =
    withSpaceSize.x
    - ((withSpaceSize.x - baseSize.x) / 2)
    - spaceWidth;

Asserting SwingWorker

I have had a chance to play around with some java code recently for a change of pace and I was excited to use the new SwingWorker class in JSE6. However I also am in the habit of programming with asserts which I found out to be a problem if one triggers while running in a SwingWorker thread.

If you look at the base class of SwingWorker, FurtureTask, in the inner class Sync, which is where the actual task is run there is this method:

boolean innerRunAndReset() {
    if (!compareAndSetState(0, RUNNING))
        return false;
    try {
        runner = Thread.currentThread();
        if (getState() == RUNNING)
            callable.call(); // don't set result
        runner = null;
        return compareAndSetState(RUNNING, 0);
    } catch (Throwable ex) {
        innerSetException(ex);
        return false;
    }
}

The observant reader will notice that this code will catch all Throwables, which is the base class of Exception and Error, and an assert in java will throw a AssertError so your code will bomb out silently without notification if any Throwable is thrown.

try {
    // do threadded work here
} catch (AssertionError e) {
    logger
        .log(Level.WARNING,
        "Assertion while processing: {0}\n{1}",
        new Object[] { e.getMessage(),
        e.getStackTrace()[0] });
} catch (Exception e) {
    logger.log(Level.SEVERE,
        "Exception throw during processing {0}\n{1}",
        new Object[] { e.getClass().getName(),
        e.getMessage() });
    throw e;
} catch (Error e) {
    logger.log(Level.SEVERE,
        "Error throw during processing {0}\n{1}",
        new Object[] { e.getClass().getName(),
        e.getMessage() });
    throw e;
}

I use the a statically defined Logger, logger, to print output from the Exceptions and Errors.

This allows the thread to throw asserts but keep going and if it does bomb out on any other Error or Exception you get notified in your log making debugging a SwingWorker a bit easier.

Open Java and Windows Options

Well it’s officially been announced that Java J2SE, J2ME, J2EE will all be released by sun as reference implementations under the Gnu GPL + classpath exception. Which I’m sure will bring a new era of Java, especially to Linux since Java will be able to be shipped with distributions without concern just like Mono is today.

I really hope this means the MVM will get done faster it would be a great thing for the platform.

On a unrelated note one of my pet peeves about Windows is the way that Explorer.exe works. The problem is that it is the window manager as well as the file browser. What I usually find is that the file manager will lock up the window manager which is most annoying. However there is an option to make them work in separate processes which users more memory but for the stability of the system it’s well worth it.
Edit In Seperate Process

Code Cutting

Well this page always seems to get a bit neglected when nothing much happens……

Something interesting that I have come across is the w3c DOM in java and how there isn’t a definitive guide to how to output it to pretty print, ie human readable, there were a few examples with xerces-j but I thought that wouldn’t work but I tried it for good measure and it works. Even with the option that appears to be for xerces. Heres the code.

TransformerFactory tFactory = TransformerFactory.newInstance();
try {
    Transformer transformer = tFactory.newTransformer();
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    transformer.setOutputProperty("{xml.apache.org/xslt}indent-amount", "4");

    DOMSource source = new DOMSource(document);
    transformer.transform(source, new StreamResult(f));
} catch (TransformerConfigurationException e) {
    e.printStackTrace();
} catch (TransformerException e) {
    e.printStackTrace();
}

Have fun and I found a great plugin for doing the code colouring, iG:Syntax Highligher.

Interesting Java Proposal

In the java community there has been a long and heated debate about adding delegates to the language. There is a white paper on Suns website explaining there position on the debate. Which is in response to Microsoft’s implementation of them in J++ which in tern could be deemed as the turning point for Microsoft to then create the entire .NET architecture. Although it doesn’t have a date on it using the way back machine we can see that the paper has been around at least since the beginning of 1999.

I hadn’t read the paper until just last week and I agree with what it’s saying functors/delegates are a quite strange structure in c/c++/.NET and can be difficult to explain. On a side not I have also read that Java is a much more strongly OO architecture than .NET, which is more an easy wrapper over windows as always (grr I can’t stand MFC) anyway… I was looking at some new features for c# 3.0 and in particular extension methods which I am of the opinion are really syntactic sugar for the lazy VB programmers out there, ducks for cover.

But in my search I also found a new paper that is proposed for Java written by three prominent figures including James Gosling, the farther of Java, Closures for Java, there is a pdf but this is a verbatim copy on Neal Gafter’s blog.

Neal has 4 other posts about them and I recommend reading them all if your head can get around them, it took me 2 goes at it. I can see how these constructs could be very useful in getting rid of boiler plate code from a lot of Java programming, which is always a good thing, but I can also see it becoming a problem as well when used too much. Since it is a way of almost changing the language itself you could quickly start having the same headaches you get for heavily preprocessed c/c++ code.

I am still not sure as to whether they would be a good thing for the language if introduced it will be something that will probably not make it into begging programming courses. One of the things I have always liked about Java is that once you understand the OO principles of the language which can be picked up in a short amount of time virtually all api’s and constructs can be created by the programmer. If not very well designed used but use none the less.

I’ll keep tracking Neal’s blog for more insights into uses before I am really sure but it is none the less a very radical and interesting proposal none the less.

Downtime

Hey all. It’s been a while but hey buildtolean’s mysql server was down for about 5 days making blogging impossible and made me start to thing whether or not it is time to move to a more stable provider. Possibly one I would pay for. But hey I’m a tight arse and I’m not going to start paying for webspace just yet.

We upgraded or mobile phones on the weekend and jumped on the 3G bandwagon because Orange in Australia is now dissolving because of Telstra’s decision to dismantle their CDMA network in 2 years time.

But my new phone has a camera so now I can shoot any time I want without having to remember the digital camera. Here’s a shot of my new laptop running the program I am working on at the moment.

Benq s52

Software Engineering

It’s been a long time since my last post, in that time I have moved house, done summer school and started full time work. And that goodness for that last point I am so sick of study. Only one more exam tomorrow to go yey.

Anyway today I came across such a great article that I just have to share it with the no readers I have here :P. Software Engineering, Not Computer Science it talks about how Software Development should really be thought as engineering and not a science or an art so much.

Lucky for me I am now a qualified Software Engineer however with the decline in numbers my Course at Swinburne will no longer be offered. And such a relevant course to do o well alot of maths isn’t for everyone.

Summer School

Well today I started summer school, o yey, doing Professional Issues in Information Technology and as most people who read this would know the first lecture consists of watch i, robot and writing an essay on it. But lucky me with the accelerated course doesn’t get the week to write the essay I get just one day so before I go off and start to write the next masterpiece I thought it was time for a bit of procrastination.

I have finished work for the year since this summer school stuff will just be too much work to even think about working in the afternoons and on top of that we are moving Thursday week so the house is a mess and you know that moving is a stress in itself at any time in your life.

We also finally upgraded our digital camera the other day. We went out and got a Canon S2 IS, which doesn’t have any RAW format but that is my only gripe about the camera it takes images and video and stores it fast which is a nice change from my previous camera, my trusty Kodak DC215 which in it’s time was the first cheap camera with optical zoom. But it just doesn’t cut it today anyway here is pic of me sized down from the giant 5MP which is just a bit too much to put on a blog :P.

I am also now working on a piece of software for my wife, scratching an itch as always however it is hers not mine. It is a teachers journal program for keeping track of different aspects of students and teaching. I am hoping to have a working alpha for her when school goes back in the new year but we will see. Software Development always takes longer than expected. It is written in Java of course but this time round I am going to use SWT instead of Swing which is a bit of an adventure. I will keep you posted, maybe a few screenshots when I get something working and a link to the site once it is release, open source of course.

Till the sands of time do we meet again, “Keep on truckin’”

  • 1
  • 2