(As you aleady know...but to give context...)
If your process happens to be executing your perl function 'command' then it is interupted and your signal handler called. This then does a 'die' and your eval catching mechanism picks up and carries on.
If you have started another process (this is your case when you have an external command started with system or backticks) then it neither knows nor cares that your process has received an alarm...which is why it continues to run.
I think what you want to do is pretty much in your second example. When you receive the SIGALRM you'll want to kill the child...which means you need the child pid.
Zigster mentioned a good point. 'kill -9' is a bit rude (it depends on what the subprocess does if you care about being rude to it). I differ about the best signal to kill with initially though. The unix default for the 'kill' command is SIGTERM (15), which means 'please die'.
This is all assuming Unix because you mentioned the 'alarm' function. If you want to achieve a similar effect on Win32, the last time I looked at this the best (only?) way was to use the Win32::Process::Create, which creates a handle to the new process upon which you can then wait for a specified period.
Lastly, a quick bit of CPANning shows up:
"This is a generic interface for placing processes in background on both Unix and Win32 platforms. This module lets you start, kill, wait on, retrieve exit values, and see if background processes still exist."
Which (if it does what it says on the tin) sounds interesting...