fix issue with threaded ivrd, forking is back by default but threaded can be chosen with -t; in both modes the fd number is not passed as the first arg to the program but in threaded mode the stdin will no longer be mapped to the socket you will have to get the first command line arg instead of fileno stdin
This commit is contained in:
parent
086cbf1bfc
commit
163fffb3e8
|
@ -36,11 +36,56 @@
|
|||
#include <esl.h>
|
||||
#include <errno.h>
|
||||
|
||||
static void my_forking_callback(esl_socket_t server_sock, esl_socket_t client_sock, struct sockaddr_in *addr)
|
||||
{
|
||||
esl_handle_t handle = {{0}};
|
||||
char path_buffer[1024] = { 0 };
|
||||
const char *path;
|
||||
char arg[64] = { 0 };
|
||||
|
||||
if (fork()) {
|
||||
close(client_sock);
|
||||
return;
|
||||
}
|
||||
|
||||
if (esl_attach_handle(&handle, client_sock, addr) != ESL_SUCCESS || !handle.info_event) {
|
||||
esl_log(ESL_LOG_ERROR, "Socket Error\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (!(path = esl_event_get_header(handle.info_event, "variable_ivr_path"))) {
|
||||
esl_disconnect(&handle);
|
||||
esl_log(ESL_LOG_ERROR, "Missing ivr_path param!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
snprintf(arg, sizeof(arg), "%d", client_sock);
|
||||
|
||||
strncpy(path_buffer, path, sizeof(path_buffer) - 1);
|
||||
|
||||
/* hotwire the socket to STDIN/STDOUT */
|
||||
/* hotwire the socket to STDIN/STDOUT */
|
||||
if (!(dup2(client_sock, STDIN_FILENO)) && !(dup2(client_sock, STDOUT_FILENO))){
|
||||
esl_disconnect(&handle);
|
||||
esl_log(ESL_LOG_ERROR, "Socket Error hotwiring socket to STDIN/STDOUT!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* close the handle but leak the socket on purpose cos the child will need it open */
|
||||
handle.sock = -1;
|
||||
esl_disconnect(&handle);
|
||||
|
||||
execl(path_buffer, path_buffer, arg, (char *)NULL);
|
||||
close(client_sock);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void mycallback(esl_socket_t server_sock, esl_socket_t client_sock, struct sockaddr_in *addr)
|
||||
{
|
||||
esl_handle_t handle = {{0}};
|
||||
const char *path;
|
||||
|
||||
char path_buffer[1024] = { 0 };
|
||||
|
||||
if (esl_attach_handle(&handle, client_sock, addr) != ESL_SUCCESS || !handle.info_event) {
|
||||
close(client_sock);
|
||||
esl_log(ESL_LOG_ERROR, "Socket Error\n");
|
||||
|
@ -53,16 +98,13 @@ static void mycallback(esl_socket_t server_sock, esl_socket_t client_sock, struc
|
|||
return;
|
||||
}
|
||||
|
||||
/* hotwire the socket to STDIN/STDOUT */
|
||||
if (!(dup2(client_sock, STDIN_FILENO)) && !(dup2(client_sock, STDOUT_FILENO))){
|
||||
esl_disconnect(&handle);
|
||||
esl_log(ESL_LOG_ERROR, "Socket Error hotwiring socket to STDIN/STDOUT!\n");
|
||||
return;
|
||||
}
|
||||
snprintf(path_buffer, sizeof(path_buffer), "%s %d", path, client_sock);
|
||||
|
||||
if(system(path)) {
|
||||
|
||||
if (system(path_buffer)) {
|
||||
esl_log(ESL_LOG_ERROR, "System Call Failed! [%s]\n", strerror(errno));
|
||||
}
|
||||
|
||||
esl_disconnect(&handle);
|
||||
|
||||
}
|
||||
|
@ -71,24 +113,43 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
int i;
|
||||
char *ip = NULL;
|
||||
int port = 0;
|
||||
int port = 0, thread = 0;
|
||||
|
||||
for (i = 1; i + 1 < argc; ) {
|
||||
if (!strcasecmp(argv[i], "-h")) {
|
||||
ip = argv[++i];
|
||||
} else if (!strcasecmp(argv[i], "-p")) {
|
||||
port = atoi(argv[++i]);
|
||||
} else {
|
||||
i++;
|
||||
for (i = 1; i < argc; ) {
|
||||
int cont = 0;
|
||||
|
||||
if (i + 1 < argc) {
|
||||
if (!strcasecmp(argv[i], "-h")) {
|
||||
ip = argv[++i]; cont++;
|
||||
} else if (!strcasecmp(argv[i], "-p")) {
|
||||
port = atoi(argv[++i]); cont++;
|
||||
}
|
||||
}
|
||||
|
||||
if (cont) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcasecmp(argv[i], "-t")) {
|
||||
thread++;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if (!(ip && port)) {
|
||||
fprintf(stderr, "Usage %s -h <host> -p <port>\n", argv[0]);
|
||||
fprintf(stderr, "Usage %s [-t] -h <host> -p <port>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
esl_listen(ip, port, mycallback, 100000);
|
||||
if (thread) {
|
||||
printf("Starting threaded listener.\n");
|
||||
esl_listen_threaded(ip, port, mycallback, 100000);
|
||||
} else {
|
||||
printf("Starting forking listener.\n");
|
||||
esl_listen(ip, port, my_forking_callback);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -649,7 +649,64 @@ static void *client_thread(esl_thread_t *me, void *obj)
|
|||
|
||||
}
|
||||
|
||||
ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_listen_callback_t callback, int max)
|
||||
ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_listen_callback_t callback)
|
||||
{
|
||||
esl_socket_t server_sock = ESL_SOCK_INVALID;
|
||||
struct sockaddr_in addr;
|
||||
esl_status_t status = ESL_SUCCESS;
|
||||
|
||||
if ((server_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
|
||||
return ESL_FAIL;
|
||||
}
|
||||
|
||||
esl_socket_reuseaddr(server_sock);
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
addr.sin_port = htons(port);
|
||||
|
||||
if (bind(server_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||
status = ESL_FAIL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (listen(server_sock, 10000) < 0) {
|
||||
status = ESL_FAIL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
int client_sock;
|
||||
struct sockaddr_in echoClntAddr;
|
||||
#ifdef WIN32
|
||||
int clntLen;
|
||||
#else
|
||||
unsigned int clntLen;
|
||||
#endif
|
||||
|
||||
clntLen = sizeof(echoClntAddr);
|
||||
|
||||
if ((client_sock = accept(server_sock, (struct sockaddr *) &echoClntAddr, &clntLen)) == ESL_SOCK_INVALID) {
|
||||
status = ESL_FAIL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
callback(server_sock, client_sock, &echoClntAddr);
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
if (server_sock != ESL_SOCK_INVALID) {
|
||||
closesocket(server_sock);
|
||||
server_sock = ESL_SOCK_INVALID;
|
||||
}
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
ESL_DECLARE(esl_status_t) esl_listen_threaded(const char *host, esl_port_t port, esl_listen_callback_t callback, int max)
|
||||
{
|
||||
esl_socket_t server_sock = ESL_SOCK_INVALID;
|
||||
struct sockaddr_in addr;
|
||||
|
|
|
@ -391,7 +391,9 @@ ESL_DECLARE(esl_status_t) esl_attach_handle(esl_handle_t *handle, esl_socket_t s
|
|||
\param port Port to bind to
|
||||
\param callback Callback that will be called upon data received
|
||||
*/
|
||||
ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_listen_callback_t callback, int max);
|
||||
|
||||
ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_listen_callback_t callback);
|
||||
ESL_DECLARE(esl_status_t) esl_listen_threaded(const char *host, esl_port_t port, esl_listen_callback_t callback, int max);
|
||||
/*!
|
||||
\brief Executes application with sendmsg to a specific UUID. Used for outbound socket.
|
||||
\param handle Handle that the msg will be sent
|
||||
|
|
|
@ -48,7 +48,7 @@ static void mycallback(esl_socket_t server_sock, esl_socket_t client_sock, struc
|
|||
int main(void)
|
||||
{
|
||||
esl_global_set_default_logger(7);
|
||||
esl_listen("localhost", 8084, mycallback, 100000);
|
||||
esl_listen_threaded("localhost", 8084, mycallback, 100000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue