IO-SocketAlarm
view release on metacpan or search on metacpan
SocketAlarm_action.c view on Meta::CPAN
// Get the 'command' name of the action
action_spec= (AV*) SvRV(spec[spec_i]);
n_el= av_count(action_spec);
if (n_el < 1 || !(el= av_fetch(action_spec, 0, 0)) || !SvPOK(*el))
croak("First element of action must be a string");
act_name= SvPV(*el, act_namelen);
// Dispatch based on the command
switch (act_namelen) {
case 3:
if (strcmp(act_name, "sig") == 0) {
if (n_el > 2)
croak("Too many parameters for 'sig' action");
common_signal= (n_el == 2 && (el= av_fetch(action_spec, 1, 0)) != NULL && SvOK(*el))?
parse_signal(*el) : SIGALRM;
common_pid= getpid();
goto parse_kill_common;
}
if (strcmp(act_name, "run") == 0) {
common_op= ACT_RUN;
goto parse_run_common;
}
case 4:
if (strcmp(act_name, "kill") == 0) {
if (n_el != 3)
croak("Expected 2 parameters for 'kill' action");
el= av_fetch(action_spec, 1, 0);
if (!el || !SvOK(*el))
croak("Expected Signal as first parameter to 'kill'");
common_signal= parse_signal(*el);
el= av_fetch(action_spec, 2, 0);
if (!el || !SvIOK(*el))
croak("Expected PID as second parameter to 'kill'");
common_pid= SvIV(*el);
goto parse_kill_common;
}
if (strcmp(act_name, "exec") == 0) {
common_op= ACT_EXEC;
goto parse_run_common;
}
case 5:
if (strcmp(act_name, "sleep") == 0) {
if (n_el != 2)
croak("Expected 1 parameter to 'sleep' action");
el= av_fetch(action_spec, 1, 0);
if (!el || !SvOK(*el) || !looks_like_number(*el))
croak("Expected number of seconds in 'sleep' action");
if (action_pos < *n_actions) {
actions[action_pos].op= ACT_SLEEP;
actions[action_pos].orig_idx= spec_i;
actions[action_pos].act.slp.seconds= SvNV(*el);
}
++action_pos;
continue;
}
if (strcmp(act_name, "close") == 0) {
common_op= ACT_x_CLOSE;
goto parse_close_common;
}
case 6:
// The repeat feature opens the possibility of infinite busy-loops,
// and probably creates more problems than it solves.
//if (strcmp(act_name, "repeat") == 0) {
// int act_count= spec_i;
// if (!act_count)
// croak("'repeat' cannot be the first action");
// if (n_el != 1) { // default is to repeat all, via act_count=i above
// if (n_el != 2)
// croak("Expected 0 or 1 parameters to 'repeat'");
// el= av_fetch(action_spec, 1, 0);
// if (!el || !SvOK(*el) || !looks_like_number(*el) || SvIV(*el) <= 0)
// croak("Expected positive integer of actions to repeat");
// act_count= SvIV(*el);
// }
// if (action_pos < *n_actions) {
// int dest_act_idx, dest_spec_idx= spec_i - act_count;
// // Locate the first action record with orig_idx == dest_spec_idx;
// for (dest_act_idx= 0; dest_act_idx < spec_i; dest_act_idx++)
// if (actions[dest_act_idx].orig_idx == dest_spec_idx)
// break;
// actions[action_pos].op= ACT_JUMP;
// actions[action_pos].orig_idx= spec_i;
// actions[action_pos].act.jmp.idx= dest_act_idx;
// }
// ++action_pos;
// continue;
//}
if (strcmp(act_name, "shut_r") == 0) {
common_op= ACT_x_SHUT_R;
goto parse_close_common;
}
if (strcmp(act_name, "shut_w") == 0) {
common_op= ACT_x_SHUT_W;
goto parse_close_common;
}
case 7:
if (strcmp(act_name, "shut_rw") == 0) {
common_op= ACT_x_SHUT_RW;
goto parse_close_common;
}
default:
croak("Unknown command '%s' in action list", act_name);
}
if (0) parse_kill_common: { // arrive from 'kill' and 'sig'
// common_signal, common_pid will be set.
// Is there an available action?
if (action_pos < *n_actions) {
actions[action_pos].op= ACT_KILL;
actions[action_pos].orig_idx= spec_i;
actions[action_pos].act.kill.signal= common_signal;
actions[action_pos].act.kill.pid= common_pid;
}
++action_pos;
}
if (0) parse_run_common: { // arrive from 'run' and 'exec'
char **argv= NULL, *str;
STRLEN len;
int j, argc= n_el-1;
// common_op will be set.
if (n_el < 2)
croak("Expected at least one parameter for '%s'", act_name);
( run in 2.850 seconds using v1.01-cache-2.11-cpan-99c4e6809bf )