-> Forking of executed program is now performed without getting zombie process.
modified: README
modified: action.cpp
modified: apppbx.h
modified: route.c
modified: route.h
- chan_lcr: Open b-channel if asterisk indicates "PROGRESS".
-> Also if tones are available, asterisk gets "PROGRESS" indication.
- lcradmin displays TEI values in NT-mode PTMP
- chan_lcr: Open b-channel if asterisk indicates "PROGRESS".
-> Also if tones are available, asterisk gets "PROGRESS" indication.
- lcradmin displays TEI values in NT-mode PTMP
+- Added patch from Daniel
+ -> Improved forking
+ -> Execution action can now be done on call init or on call hangup.
+/*
+ * process init 'execute'
+ */
+void EndpointAppPBX::action_init_execute(void)
+{
+ struct route_param *rparam;
+ int executeon = INFO_ON_HANGUP; /* Use Hangup as a default for compatibility */
+
+ /* Get the execute on parameter */
+ if ((rparam = routeparam(e_action, PARAM_ON)))
+ executeon = rparam->integer_value;
+
+ /* Execute this action if init was specified */
+ if (executeon == INFO_ON_INIT)
+ {
+ trace_header("ACTION execute ON init", DIRECTION_NONE);
+ end_trace();
+ action_execute();
+ }
+}
/*
* process hangup 'execute'
/*
* process hangup 'execute'
void EndpointAppPBX::action_hangup_execute(void)
{
struct route_param *rparam;
void EndpointAppPBX::action_hangup_execute(void)
{
struct route_param *rparam;
+ int executeon = INFO_ON_HANGUP; /* Use Hangup as a default for compatibility */
+
+ /* Get the execute on parameter */
+ if ((rparam = routeparam(e_action, PARAM_ON)))
+ executeon = rparam->integer_value;
+
+ /* Execute this action if init was specified */
+ if (executeon == INFO_ON_HANGUP)
+ {
+ trace_header("ACTION execute ON hangup", DIRECTION_NONE);
+ end_trace();
+ action_execute();
+ }
+}
+
+/*
+ * process 'execute' from action_init_execute or action_hangup_execute
+ */
+void EndpointAppPBX::action_execute(void)
+{
+ struct route_param *rparam;
+ pid_t pid2;
+ int iWaitStatus;
char *command = (char *)"";
char isdn_port[10];
char *argv[11]; /* check also number of args below */
char *command = (char *)"";
char isdn_port[10];
char *argv[11]; /* check also number of args below */
end_trace();
break;
case 0:
end_trace();
break;
case 0:
- execve("/bin/sh", argv, environ);
- break;
+ /* To be shure there are no zombies created double fork */
+ if ((pid2 = fork()) == 0)
+ {
+ execve("/bin/sh", argv, environ);
+ }
+ else
+ {
+ /* Exit immediately and release the waiting parent. The subprocess falls to init because the parent died */
+ exit(0);
+ }
+ break;
default:
trace_header("ACTION execute", DIRECTION_NONE);
add_trace("command", NULL, "%s", command);
end_trace();
default:
trace_header("ACTION execute", DIRECTION_NONE);
add_trace("command", NULL, "%s", command);
end_trace();
+
+ /* Wait for the pid. The forked process will exit immediately so there is no problem waiting. */
+ waitpid(pid, &iWaitStatus, 0);
void action_dialing_help(void);
void action_dialing_deflect(void);
void action_dialing_setforward(void);
void action_dialing_help(void);
void action_dialing_deflect(void);
void action_dialing_setforward(void);
+ void action_init_execute(void);
void action_hangup_execute(void);
void action_hangup_execute(void);
+ void action_execute(void);
void action_hangup_file(void);
void action_init_pick(void);
void action_dialing_password(void);
void action_hangup_file(void);
void action_init_pick(void);
void action_dialing_password(void);
{ PARAM_EXTEN,
"exten", PARAM_TYPE_STRING,
"exten=<extension>", "Give exten parameter to the remote application. (overrides dialed number)"},
{ PARAM_EXTEN,
"exten", PARAM_TYPE_STRING,
"exten=<extension>", "Give exten parameter to the remote application. (overrides dialed number)"},
+ { PARAM_ON,
+ "on", PARAM_TYPE_STRING,
+ "on=[init|hangup]", "Defines if the action is executed on call init or on hangup."},
{ 0, NULL, 0, NULL, NULL}
};
{ 0, NULL, 0, NULL, NULL}
};
NULL},
// "The call forward is set within the telephone network of the external line."},
{ ACTION_EXECUTE,
NULL},
// "The call forward is set within the telephone network of the external line."},
{ ACTION_EXECUTE,
- "execute", NULL, NULL, &EndpointAppPBX::action_hangup_execute,
- PARAM_CONNECT | PARAM_EXECUTE | PARAM_PARAM,
+ "execute", &EndpointAppPBX::action_init_execute, NULL, &EndpointAppPBX::action_hangup_execute,
+ PARAM_CONNECT | PARAM_EXECUTE | PARAM_PARAM | PARAM_ON,
"Executes the given script file. The file must terminate quickly, because it will halt the PBX."},
{ ACTION_FILE,
"file", NULL, NULL, &EndpointAppPBX::action_hangup_file,
"Executes the given script file. The file must terminate quickly, because it will halt the PBX."},
{ ACTION_FILE,
"file", NULL, NULL, &EndpointAppPBX::action_hangup_file,
case PARAM_TYPE_DESTIN:
case PARAM_TYPE_TYPE:
case PARAM_TYPE_YESNO:
case PARAM_TYPE_DESTIN:
case PARAM_TYPE_TYPE:
case PARAM_TYPE_YESNO:
key[0] = '\0';
if (*p==',' || *p==' ' || *p=='\0')
{
key[0] = '\0';
if (*p==',' || *p==' ' || *p=='\0')
{
SPRINT(failure, "Caller ID type '%s' unknown.", key);
goto parse_error;
}
SPRINT(failure, "Caller ID type '%s' unknown.", key);
goto parse_error;
}
+ if (param_defs[index].type == PARAM_TYPE_ON)
+ {
+ param->value_type = VALUE_TYPE_INTEGER;
+ if (!strcasecmp(key, "init"))
+ {
+ param->integer_value = INFO_ON_INIT;
+ break;
+ }
+ if (!strcasecmp(key, "hangup"))
+ {
+ param->integer_value = INFO_ON_HANGUP;
+ break;
+ }
+ SPRINT(failure, "Execute on '%s' unknown.", key);
+ goto parse_error;
+ }
if (param_defs[index].type == PARAM_TYPE_CAPABILITY)
{
param->value_type = VALUE_TYPE_INTEGER;
if (param_defs[index].type == PARAM_TYPE_CAPABILITY)
{
param->value_type = VALUE_TYPE_INTEGER;
PARAM_TYPE_PORTS,
PARAM_TYPE_TYPE,
PARAM_TYPE_CALLERIDTYPE,
PARAM_TYPE_PORTS,
PARAM_TYPE_TYPE,
PARAM_TYPE_CALLERIDTYPE,
+ PARAM_TYPE_ON,
+};
+
+enum { /* defines when a statement should be executed */
+ INFO_ON_INIT,
+ INFO_ON_HANGUP,
};
/* parameter ID bits */
};
/* parameter ID bits */
#define PARAM_APPLICATION (1LL<<44)
#define PARAM_CONTEXT (1LL<<45)
#define PARAM_EXTEN (1LL<<46)
#define PARAM_APPLICATION (1LL<<44)
#define PARAM_CONTEXT (1LL<<45)
#define PARAM_EXTEN (1LL<<46)
+#define PARAM_ON (1LL<<47)
/* action index
* NOTE: The given index is the actual entry number of action_defs[], so add/remove both lists!!!
/* action index
* NOTE: The given index is the actual entry number of action_defs[], so add/remove both lists!!!