1 /* $Id$ */
2 /*
3 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20 #include "pjsua_app.h"
21
22 #define THIS_FILE "main.c"
23
24 static pj_bool_t running = PJ_TRUE;
25 static pj_status_t receive_end_sig;
26 static pj_thread_t *sig_thread;
27 static pjsua_app_cfg_t cfg;
28
29 /* Called when CLI (re)started */
on_app_started(pj_status_t status,const char * msg)30 void on_app_started(pj_status_t status, const char *msg)
31 {
32 pj_perror(3, THIS_FILE, status, (msg)?msg:"");
33 }
34
on_app_stopped(pj_bool_t restart,int argc,char ** argv)35 void on_app_stopped(pj_bool_t restart, int argc, char** argv)
36 {
37 if (argv) {
38 cfg.argc = argc;
39 cfg.argv = argv;
40 }
41
42 running = restart;
43 }
44
45 #if defined(PJ_WIN32) && PJ_WIN32!=0
46 #include <windows.h>
47
48 static pj_thread_desc handler_desc;
49
CtrlHandler(DWORD fdwCtrlType)50 static BOOL WINAPI CtrlHandler(DWORD fdwCtrlType)
51 {
52 switch (fdwCtrlType)
53 {
54 // Handle the CTRL+C signal.
55
56 case CTRL_C_EVENT:
57 case CTRL_CLOSE_EVENT:
58 case CTRL_BREAK_EVENT:
59 case CTRL_LOGOFF_EVENT:
60 case CTRL_SHUTDOWN_EVENT:
61 pj_thread_register("ctrlhandler", handler_desc, &sig_thread);
62 PJ_LOG(3,(THIS_FILE, "Ctrl-C detected, quitting.."));
63 receive_end_sig = PJ_TRUE;
64 pjsua_app_destroy();
65 ExitProcess(1);
66 PJ_UNREACHED(return TRUE;)
67
68 default:
69
70 return FALSE;
71 }
72 }
73
setup_socket_signal()74 static void setup_socket_signal()
75 {
76 }
77
setup_signal_handler(void)78 static void setup_signal_handler(void)
79 {
80 SetConsoleCtrlHandler(&CtrlHandler, TRUE);
81 }
82
83 #elif PJ_LINUX || PJ_DARWINOS
84
85 #include <execinfo.h>
86 #include <signal.h>
87 #include <stdio.h>
88 #include <stdlib.h>
89 #include <unistd.h>
print_stack(int sig)90 static void print_stack(int sig)
91 {
92 void *array[16];
93 size_t size;
94
95 size = backtrace(array, 16);
96 fprintf(stderr, "Error: signal %d:\n", sig);
97 backtrace_symbols_fd(array, size, STDERR_FILENO);
98 exit(1);
99 }
100
setup_socket_signal()101 static void setup_socket_signal()
102 {
103 signal(SIGPIPE, SIG_IGN);
104 }
105
setup_signal_handler(void)106 static void setup_signal_handler(void)
107 {
108 signal(SIGSEGV, &print_stack);
109 signal(SIGABRT, &print_stack);
110 }
111
112 #else
113
114 #include <signal.h>
115
setup_socket_signal()116 static void setup_socket_signal()
117 {
118 signal(SIGPIPE, SIG_IGN);
119 }
120
setup_signal_handler(void)121 static void setup_signal_handler(void) {}
122
123 #endif
124
main_func(int argc,char * argv[])125 int main_func(int argc, char *argv[])
126 {
127 pj_status_t status = PJ_TRUE;
128
129 pj_bzero(&cfg, sizeof(cfg));
130 cfg.on_started = &on_app_started;
131 cfg.on_stopped = &on_app_stopped;
132 cfg.argc = argc;
133 cfg.argv = argv;
134
135 setup_signal_handler();
136 setup_socket_signal();
137
138 while (running) {
139 status = pjsua_app_init(&cfg);
140 if (status == PJ_SUCCESS) {
141 status = pjsua_app_run(PJ_TRUE);
142 } else {
143 running = PJ_FALSE;
144 }
145
146 if (!receive_end_sig) {
147 pjsua_app_destroy();
148
149 /* This is on purpose */
150 pjsua_app_destroy();
151 } else {
152 pj_thread_join(sig_thread);
153 }
154 }
155 return 0;
156 }
157
main(int argc,char * argv[])158 int main(int argc, char *argv[])
159 {
160 return pj_run_app(&main_func, argc, argv, 0);
161 }
162