]> git.sesse.net Git - vlc/blob - src/interface/main.c
.Impl�mentation de intf_WarnMsg( int i_level, char *psz_format, ... ) et
[vlc] / src / interface / main.c
1 /*****************************************************************************
2  * main.c: main vlc source
3  * Includes the main() function for vlc. Parses command line, start interface
4  * and spawn threads.
5  *****************************************************************************
6  * Copyright (C) 1998, 1999, 2000 VideoLAN
7  *
8  * Authors:
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  * 
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include "defs.h"
29
30 #include <signal.h>                               /* SIGHUP, SIGINT, SIGKILL */
31 #include <getopt.h>                                              /* getopt() */
32 #include <stdio.h>                                              /* sprintf() */
33
34 #include <errno.h>                                                 /* ENOMEM */
35 #include <stdlib.h>                                  /* getenv(), strtol(),  */
36 #include <string.h>                                            /* strerror() */
37
38 #include "config.h"
39 #include "common.h"
40 #include "threads.h"
41 #include "mtime.h"
42 #include "tests.h"                                              /* TestMMX() */
43 #include "plugins.h"
44 #include "playlist.h"
45 #include "input_vlan.h"
46 #include "input_ps.h"
47
48 #include "intf_msg.h"
49 #include "interface.h"
50
51 #include "audio_output.h"
52
53 #ifdef SYS_BEOS
54 #include "beos_specific.h"
55 #endif
56
57 #include "main.h"
58
59 /*****************************************************************************
60  * Command line options constants. If something is changed here, be sure that
61  * GetConfiguration and Usage are also changed.
62  *****************************************************************************/
63
64 /* Long options return values - note that values corresponding to short options
65  * chars, and in general any regular char, should be avoided */
66 #define OPT_NOAUDIO             150
67 #define OPT_AOUT                151
68 #define OPT_STEREO              152
69 #define OPT_MONO                153
70
71 #define OPT_NOVIDEO             160
72 #define OPT_VOUT                161
73 #define OPT_DISPLAY             162
74 #define OPT_WIDTH               163
75 #define OPT_HEIGHT              164
76 #define OPT_COLOR               165
77 #define OPT_YUV                 166
78
79 #define OPT_VLANS               170
80 #define OPT_SERVER              171
81 #define OPT_PORT                172
82 #define OPT_BROADCAST           173
83
84 #define OPT_SYNCHRO             180
85
86 #define OPT_WARNING             190
87
88 /* Usage fashion */
89 #define USAGE                     0
90 #define SHORT_HELP                1
91 #define LONG_HELP                 2
92
93 /* Long options */
94 static const struct option longopts[] =
95 {
96     /*  name,               has_arg,    flag,   val */
97
98     /* General/common options */
99     {   "help",             0,          0,      'h' },
100     {   "longhelp",         0,          0,      'H' },
101     {   "version",          0,          0,      'v' },
102
103     /* Audio options */
104     {   "noaudio",          0,          0,      OPT_NOAUDIO },
105     {   "aout",             1,          0,      OPT_AOUT },
106     {   "stereo",           0,          0,      OPT_STEREO },
107     {   "mono",             0,          0,      OPT_MONO },
108
109     /* Video options */
110     {   "novideo",          0,          0,      OPT_NOVIDEO },
111     {   "vout",             1,          0,      OPT_VOUT },
112     {   "display",          1,          0,      OPT_DISPLAY },
113     {   "width",            1,          0,      OPT_WIDTH },
114     {   "height",           1,          0,      OPT_HEIGHT },
115     {   "grayscale",        0,          0,      'g' },
116     {   "color",            0,          0,      OPT_COLOR },
117     {   "yuv",              1,          0,      OPT_YUV },
118
119     /* DVD options */
120     {   "dvdaudio",         1,          0,      'a' },
121     {   "dvdchannel",       1,          0,      'c' },
122     {   "dvdsubtitle",      1,          0,      's' },
123     
124     /* Input options */
125     {   "vlans",            0,          0,      OPT_VLANS },
126     {   "server",           1,          0,      OPT_SERVER },
127     {   "port",             1,          0,      OPT_PORT },
128     {   "broadcast",        0,          0,      OPT_BROADCAST },
129
130     /* Synchro options */
131     {   "synchro",          1,          0,      OPT_SYNCHRO },
132
133     /* Interface messages */
134     {   "warning",          1,          0,      OPT_WARNING },
135     {   0,                  0,          0,      0 }
136 };
137
138 /* Short options */
139 static const char *psz_shortopts = "hHvga:s:c:";
140
141 /*****************************************************************************
142  * Global variable program_data - this is the one and only, see main.h
143  *****************************************************************************/
144 main_t *p_main;
145
146 /*****************************************************************************
147  * Local prototypes
148  *****************************************************************************/
149 static void SetDefaultConfiguration ( void );
150 static int  GetConfiguration        ( int i_argc, char *ppsz_argv[],
151                                       char *ppsz_env[] );
152 static void Usage                   ( int i_fashion );
153 static void Version                 ( void );
154
155 static void InitSignalHandler       ( void );
156 static void SignalHandler           ( int i_signal );
157 #ifdef HAVE_MMX
158        int  TestMMX                 ( void );
159 #endif
160
161 /*****************************************************************************
162  * main: parse command line, start interface and spawn threads
163  *****************************************************************************
164  * Steps during program execution are:
165  *      -configuration parsing and messages interface initialization
166  *      -opening of audio output device and some global modules
167  *      -execution of interface, which exit on error or on user request
168  *      -closing of audio output device and some global modules
169  * On error, the spawned threads are canceled, and the open devices closed.
170  *****************************************************************************/
171 int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
172 {
173     main_t  main_data;                      /* root of all data - see main.h */
174
175     p_main = &main_data;                       /* set up the global variable */
176
177     /*
178      * System specific initialization code
179      */
180 #ifdef SYS_BEOS
181     beos_Create();
182 #endif
183
184     /*
185      * Test if our code is likely to run on this CPU 
186      */
187 #ifdef HAVE_MMX
188     if( !TestMMX() )
189     {
190         fprintf( stderr, "Sorry, this program needs an MMX processor. "
191                          "Please run the non-MMX version.\n" );
192         return( 1 );
193     }
194 #endif
195
196     /*
197      * Initialize messages interface
198      */
199     p_main->p_msg = intf_MsgCreate();
200     if( !p_main->p_msg )                         /* start messages interface */
201     {
202         fprintf( stderr, "error: can't initialize messages interface (%s)\n",
203                 strerror(errno) );
204         return( errno );
205     }
206
207     /*
208      * Read configuration
209      */
210     if( GetConfiguration( i_argc, ppsz_argv, ppsz_env ) )  /* parse cmd line */
211     {
212         intf_MsgDestroy();
213         return( errno );
214     }
215
216     /*
217      * Initialize playlist and get commandline files
218      */
219     p_main->p_playlist = playlist_Create( );
220     if( !p_main->p_playlist )
221     {
222         intf_Msg( "Playlist initialization failed\n" );
223         intf_MsgDestroy();
224         return( errno );
225     }
226     playlist_Init( p_main->p_playlist, optind );
227
228     /*
229      * Initialize plugin bank
230      */
231     p_main->p_bank = bank_Create( );
232     if( !p_main->p_bank )
233     {
234         intf_Msg( "Plugin bank initialization failed\n" );
235         playlist_Destroy( p_main->p_playlist );
236         intf_MsgDestroy();
237         return( errno );
238     }
239     bank_Init( p_main->p_bank );
240
241     /*
242      * Initialize shared resources and libraries
243      */
244     if( p_main->b_vlans && input_VlanCreate() )
245     {
246         /* On error during vlans initialization, switch off vlans */
247         intf_Msg( "Virtual LANs initialization failed : "
248                   "vlans management is deactivated\n" );
249         p_main->b_vlans = 0;
250     }
251
252     /*
253      * Open audio device and start aout thread
254      */
255     if( p_main->b_audio )
256     {
257         p_main->p_aout = aout_CreateThread( NULL );
258         if( p_main->p_aout == NULL )
259         {
260             /* On error during audio initialization, switch off audio */
261             intf_Msg( "Audio initialization failed : audio is deactivated\n" );
262             p_main->b_audio = 0;
263         }
264     }
265
266     /*
267      * Run interface
268      */
269     p_main->p_intf = intf_Create();
270     if( p_main->p_intf != NULL )
271     {
272         InitSignalHandler();             /* prepare signals for interception */
273
274         /*
275          * This is the main loop
276          */
277         intf_Run( p_main->p_intf );
278
279         intf_Destroy( p_main->p_intf );
280     }
281
282     /*
283      * Close audio device
284      */
285     if( p_main->b_audio )
286     {
287         aout_DestroyThread( p_main->p_aout, NULL );
288     }
289
290     /*
291      * Free shared resources and libraries
292      */
293     if( p_main->b_vlans )
294     {
295         input_VlanDestroy();
296     }
297
298     /*
299      * Free plugin bank
300      */
301     bank_Destroy( p_main->p_bank );
302
303     /*
304      * Free playlist
305      */
306     playlist_Destroy( p_main->p_playlist );
307
308 #ifdef SYS_BEOS
309     /*
310      * System specific cleaning code
311      */
312     beos_Destroy();
313 #endif
314
315     /*
316      * Terminate messages interface and program
317      */
318     intf_Msg( "Program terminated.\n" );
319     intf_MsgDestroy();
320
321     return( 0 );
322 }
323
324 /*****************************************************************************
325  * main_GetIntVariable: get the int value of an environment variable
326  *****************************************************************************
327  * This function is used to read some default parameters in modules.
328  *****************************************************************************/
329 int main_GetIntVariable( char *psz_name, int i_default )
330 {
331     char *      psz_env;                                /* environment value */
332     char *      psz_end;                             /* end of parsing index */
333     long int    i_value;                                            /* value */
334
335     psz_env = getenv( psz_name );
336     if( psz_env )
337     {
338         i_value = strtol( psz_env, &psz_end, 0 );
339         if( (*psz_env != '\0') && (*psz_end == '\0') )
340         {
341             return( i_value );
342         }
343     }
344     return( i_default );
345 }
346
347 /*****************************************************************************
348  * main_GetPszVariable: get the string value of an environment variable
349  *****************************************************************************
350  * This function is used to read some default parameters in modules.
351  *****************************************************************************/
352 char * main_GetPszVariable( char *psz_name, char *psz_default )
353 {
354     char *psz_env;
355
356     psz_env = getenv( psz_name );
357     if( psz_env )
358     {
359         return( psz_env );
360     }
361     return( psz_default );
362 }
363
364 /*****************************************************************************
365  * main_PutPszVariable: set the string value of an environment variable
366  *****************************************************************************
367  * This function is used to set some default parameters in modules. The use of
368  * this function will cause some memory leak: since some systems use the pointer
369  * passed to putenv to store the environment string, it can't be freed.
370  *****************************************************************************/
371 void main_PutPszVariable( char *psz_name, char *psz_value )
372 {
373     char *psz_env;
374
375     psz_env = malloc( strlen(psz_name) + strlen(psz_value) + 2 );
376     if( psz_env == NULL )
377     {
378         intf_ErrMsg( "error: %s\n", strerror(ENOMEM) );
379     }
380     else
381     {
382         sprintf( psz_env, "%s=%s", psz_name, psz_value );
383         if( putenv( psz_env ) )
384         {
385             intf_ErrMsg( "error: %s\n", strerror(errno) );
386         }
387     }
388 }
389
390 /*****************************************************************************
391  * main_PutIntVariable: set the integer value of an environment variable
392  *****************************************************************************
393  * This function is used to set some default parameters in modules. The use of
394  * this function will cause some memory leak: since some systems use the pointer
395  * passed to putenv to store the environment string, it can't be freed.
396  *****************************************************************************/
397 void main_PutIntVariable( char *psz_name, int i_value )
398 {
399     char psz_value[ 256 ];                               /* buffer for value */
400
401     sprintf( psz_value, "%d", i_value );
402     main_PutPszVariable( psz_name, psz_value );
403 }
404
405 /* following functions are local */
406
407 /*****************************************************************************
408  * SetDefaultConfiguration: set default options
409  *****************************************************************************
410  * This function is called by GetConfiguration before command line is parsed.
411  * It sets all the default values required later by the program. At this stage,
412  * most structure are not yet allocated, so initialization must be done using
413  * environment.
414  *****************************************************************************/
415 static void SetDefaultConfiguration( void )
416 {
417     /*
418      * All features are activated by default execpted vlans
419      */
420     p_main->b_audio  = 1;
421     p_main->b_video  = 1;
422     p_main->b_vlans  = 0;
423 }
424
425 /*****************************************************************************
426  * GetConfiguration: parse command line
427  *****************************************************************************
428  * Parse command line and configuration file for configuration. If the inline
429  * help is requested, the function Usage() is called and the function returns
430  * -1 (causing main() to exit). The messages interface is initialized at this
431  * stage, but most structures are not allocated, so only environment should
432  * be used.
433  *****************************************************************************/
434 static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
435 {
436     int c, i_opt;
437     char * p_pointer;
438
439     /* Set default configuration and copy arguments */
440     p_main->i_argc    = i_argc;
441     p_main->ppsz_argv = ppsz_argv;
442     p_main->ppsz_env  = ppsz_env;
443     SetDefaultConfiguration();
444
445     intf_MsgImm( COPYRIGHT_MESSAGE "\n" );
446
447     /* Get the executable name (similar to the basename command) */
448     p_main->psz_arg0 = p_pointer = ppsz_argv[ 0 ];
449     while( *p_pointer )
450     {
451         if( *p_pointer == '/' )
452         {
453             p_main->psz_arg0 = ++p_pointer;
454         }
455         else
456         {
457             ++p_pointer;
458         }
459     }
460
461     /* Parse command line options */
462     opterr = 0;
463     while( ( c = getopt_long( i_argc, ppsz_argv, psz_shortopts, longopts, 0 ) ) != EOF )
464     {
465         switch( c )
466         {
467         /* General/common options */
468         case 'h':                                              /* -h, --help */
469             Usage( SHORT_HELP );
470             return( -1 );
471             break;
472         case 'H':                                          /* -H, --longhelp */
473             Usage( LONG_HELP );
474             return( -1 );
475             break;
476         case 'v':                                           /* -v, --version */
477             Version();
478             return( -1 );
479             break;
480
481         /* Audio options */
482         case OPT_NOAUDIO:                                       /* --noaudio */
483             p_main->b_audio = 0;
484             break;
485         case OPT_AOUT:                                             /* --aout */
486             main_PutPszVariable( AOUT_METHOD_VAR, optarg );
487             break;
488         case OPT_STEREO:                                         /* --stereo */
489             main_PutIntVariable( AOUT_STEREO_VAR, 1 );
490             break;
491         case OPT_MONO:                                             /* --mono */
492             main_PutIntVariable( AOUT_STEREO_VAR, 0 );
493             break;
494
495         /* Video options */
496         case OPT_NOVIDEO:                                       /* --novideo */
497             p_main->b_video = 0;
498             break;
499         case OPT_VOUT:                                             /* --vout */
500             main_PutPszVariable( VOUT_METHOD_VAR, optarg );
501             break;
502         case OPT_DISPLAY:                                       /* --display */
503             main_PutPszVariable( VOUT_DISPLAY_VAR, optarg );
504             break;
505         case OPT_WIDTH:                                           /* --width */
506             main_PutPszVariable( VOUT_WIDTH_VAR, optarg );
507             break;
508         case OPT_HEIGHT:                                         /* --height */
509             main_PutPszVariable( VOUT_HEIGHT_VAR, optarg );
510             break;
511
512         case 'g':                                         /* -g, --grayscale */
513             main_PutIntVariable( VOUT_GRAYSCALE_VAR, 1 );
514             break;
515         case OPT_COLOR:                                           /* --color */
516             main_PutIntVariable( VOUT_GRAYSCALE_VAR, 0 );
517             break;
518         case OPT_YUV:                                               /* --yuv */
519             main_PutPszVariable( YUV_METHOD_VAR, optarg );
520             break;
521
522         /* DVD options */
523         case 'a':
524             if ( ! strcmp(optarg, "mpeg") )
525                 main_PutIntVariable( INPUT_DVD_AUDIO_VAR, REQUESTED_MPEG );
526             else if ( ! strcmp(optarg, "lpcm") )
527                 main_PutIntVariable( INPUT_DVD_AUDIO_VAR, REQUESTED_LPCM );
528             else if ( ! strcmp(optarg, "off") )
529                 main_PutIntVariable( INPUT_DVD_AUDIO_VAR, REQUESTED_NOAUDIO );
530             else
531                 main_PutIntVariable( INPUT_DVD_AUDIO_VAR, REQUESTED_AC3 );
532             break;
533         case 'c':
534             main_PutIntVariable( INPUT_DVD_CHANNEL_VAR, atoi(optarg) );
535             break;
536         case 's':
537             main_PutIntVariable( INPUT_DVD_SUBTITLE_VAR, atoi(optarg) );
538             break;
539
540         /* Input options */
541         case OPT_VLANS:                                           /* --vlans */
542             p_main->b_vlans = 1;
543             break;
544         case OPT_SERVER:                                         /* --server */
545             main_PutPszVariable( INPUT_SERVER_VAR, optarg );
546             break;
547         case OPT_PORT:                                             /* --port */
548             main_PutPszVariable( INPUT_PORT_VAR, optarg );
549             break;
550         case OPT_BROADCAST:                                   /* --broadcast */
551             main_PutIntVariable( INPUT_BROADCAST_VAR, 1 );
552             break;
553
554         /* Synchro options */
555         case OPT_SYNCHRO:                                      
556             main_PutPszVariable( VPAR_SYNCHRO_VAR, optarg );
557             break;
558
559         /* Interface warning messages level */
560         case OPT_WARNING:                                       /* --warning */
561             main_PutIntVariable( INTF_WARNING_VAR, atoi(optarg) );
562             break;
563             
564         /* Internal error: unknown option */
565         case '?':
566         default:
567             intf_ErrMsg( "intf error: unknown option `%s'\n", ppsz_argv[optind - 1] );
568             Usage( USAGE );
569             return( EINVAL );
570             break;
571         }
572     }
573
574     /* Parse command line parameters - no check is made for these options */
575     for( i_opt = optind; i_opt < i_argc; i_opt++ )
576     {
577         putenv( ppsz_argv[ i_opt ] );
578     }
579     return( 0 );
580 }
581
582 /*****************************************************************************
583  * Usage: print program usage
584  *****************************************************************************
585  * Print a short inline help. Message interface is initialized at this stage.
586  *****************************************************************************/
587 static void Usage( int i_fashion )
588 {
589     /* Usage */
590     intf_Msg( "Usage: %s [options] [parameters] [file]...\n",
591               p_main->psz_arg0 );
592
593     if( i_fashion == USAGE )
594     {
595         intf_Msg( "Try `%s --help' for more information.\n",
596                   p_main->psz_arg0 );
597         return;
598     }
599
600     /* Options */
601     intf_Msg( "\n"
602               "Options:\n"
603               "      --noaudio                  \tdisable audio\n"
604               "      --aout <plugin>            \taudio output method\n"
605               "      --stereo, --mono           \tstereo/mono audio\n"
606               "\n"
607               "      --novideo                  \tdisable video\n"
608               "      --vout <plugin>            \tvideo output method\n"
609               "      --display <display>        \tdisplay string\n"
610               "      --width <w>, --height <h>  \tdisplay dimensions\n"
611               "  -g, --grayscale                \tgrayscale output\n"
612               "      --color                    \tcolor output\n"
613               "\n"
614               "  -a, --dvdaudio <type>          \tchoose DVD audio type\n"
615               "  -c, --dvdchannel <channel>     \tchoose DVD audio channel\n"
616               "  -s, --dvdsubtitle <channel>    \tchoose DVD subtitle channel\n"
617               "\n"
618               "      --vlans                    \tenable vlans\n"
619               "      --server <host>            \tvideo server address\n"
620               "      --port <port>              \tvideo server port\n"
621               "      --broadcast                \tlisten to a broadcast\n"
622               "\n"
623               "      --synchro <type>           \tforce synchro algorithm\n"
624               "\n"
625               "      --warning <level>          \tdisplay warning messages\n"
626               "\n"
627               "  -h, --help                     \tprint help and exit\n"
628               "  -H, --longhelp                 \tprint long help and exit\n"
629               "  -v, --version                  \toutput version information and exit\n" );
630
631     if( i_fashion == SHORT_HELP )
632         return;
633
634     /* Interface parameters */
635     intf_Msg( "\n"
636               "Interface parameters:\n"
637               "  " INTF_INIT_SCRIPT_VAR "=<filename>               \tinitialization script\n"
638               "  " INTF_CHANNELS_VAR "=<filename>            \tchannels list\n"
639               "  " INTF_WARNING_VAR "=<level>                \twarning level\n" );
640
641     /* Audio parameters */
642     intf_Msg( "\n"
643               "Audio parameters:\n"
644               "  " AOUT_METHOD_VAR "=<method name>        \taudio method\n"
645               "  " AOUT_DSP_VAR "=<filename>              \tdsp device path\n"
646               "  " AOUT_STEREO_VAR "={1|0}                \tstereo or mono output\n"
647               "  " AOUT_RATE_VAR "=<rate>             \toutput rate\n" );
648
649     /* Video parameters */
650     intf_Msg( "\n"
651               "Video parameters:\n"
652               "  " VOUT_METHOD_VAR "=<method name>        \tdisplay method\n"
653               "  " VOUT_DISPLAY_VAR "=<display name>      \tdisplay used\n"
654               "  " VOUT_WIDTH_VAR "=<width>               \tdisplay width\n"
655               "  " VOUT_HEIGHT_VAR "=<height>             \tdislay height\n"
656               "  " VOUT_FB_DEV_VAR "=<filename>           \tframebuffer device path\n"
657               "  " VOUT_GRAYSCALE_VAR "={1|0}             \tgrayscale or color output\n" );
658
659     /* DVD parameters */
660     intf_Msg( "\n"
661               "DVD parameters:\n"
662               "  " INPUT_DVD_AUDIO_VAR "={ac3|lpcm|mpeg|off} \taudio type\n"
663               "  " INPUT_DVD_CHANNEL_VAR "=[0-15]            \taudio channel\n"
664               "  " INPUT_DVD_SUBTITLE_VAR "=[0-31]           \tsubtitle channel\n" );
665
666     /* Input parameters */
667     intf_Msg( "\n"
668               "Input parameters:\n"
669               "  " INPUT_SERVER_VAR "=<hostname>          \tvideo server\n"
670               "  " INPUT_PORT_VAR "=<port>            \tvideo server port\n"
671               "  " INPUT_IFACE_VAR "=<interface>          \tnetwork interface\n"
672               "  " INPUT_BROADCAST_VAR "={1|0}            \tbroadcast mode\n"
673               "  " INPUT_VLAN_SERVER_VAR "=<hostname>     \tvlan server\n"
674               "  " INPUT_VLAN_PORT_VAR "=<port>           \tvlan server port\n" );
675
676     /* Synchro parameters */
677     intf_Msg( "\n"
678               "Synchro parameters:\n"
679               "  " VPAR_SYNCHRO_VAR "={I|I+|IP|IP+|IPB}   \tsynchro algorithm\n");
680 }
681
682 /*****************************************************************************
683  * Version: print complete program version
684  *****************************************************************************
685  * Print complete program version and build number.
686  *****************************************************************************/
687 static void Version( void )
688 {
689     intf_Msg( VERSION_MESSAGE
690               "This program comes with NO WARRANTY, to the extent permitted by law.\n"
691               "You may redistribute it under the terms of the GNU General Public License;\n"
692               "see the file named COPYING for details.\n"
693               "Written by the VideoLAN team at Ecole Centrale, Paris.\n" );
694
695 }
696
697 /*****************************************************************************
698  * InitSignalHandler: system signal handler initialization
699  *****************************************************************************
700  * Set the signal handlers. SIGTERM is not intercepted, because we need at
701  * at least a method to kill the program when all other methods failed, and
702  * when we don't want to use SIGKILL.
703  *****************************************************************************/
704 static void InitSignalHandler( void )
705 {
706     /* Termination signals */
707     signal( SIGHUP,  SignalHandler );
708     signal( SIGINT,  SignalHandler );
709     signal( SIGQUIT, SignalHandler );
710 }
711
712 /*****************************************************************************
713  * SignalHandler: system signal handler
714  *****************************************************************************
715  * This function is called when a signal is received by the program. It tries to
716  * end the program in a clean way.
717  *****************************************************************************/
718 static void SignalHandler( int i_signal )
719 {
720     /* Once a signal has been trapped, the termination sequence will be armed and
721      * following signals will be ignored to avoid sending messages to an interface
722      * having been destroyed */
723     signal( SIGHUP,  SIG_IGN );
724     signal( SIGINT,  SIG_IGN );
725     signal( SIGQUIT, SIG_IGN );
726
727     /* Acknowledge the signal received */
728     intf_ErrMsgImm("intf: signal %d received\n", i_signal );
729
730     /* Try to terminate everything - this is done by requesting the end of the
731      * interface thread */
732     p_main->p_intf->b_die = 1;
733 }
734