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