#include "config.h"
+#include <vlc/vlc.h>
#include <stdio.h> /* fprintf() */
#include <stdlib.h> /* putenv(), strtol(), */
-#ifdef HAVE_SIGNAL_H
-# include <signal.h> /* SIGHUP, SIGINT, SIGKILL */
-#endif
-#ifdef HAVE_TIME_H
-# include <time.h> /* time() */
-#endif
-#ifdef HAVE_PTHREAD_H
-# include <pthread.h>
-#endif
+#include <locale.h>
-#include <vlc/vlc.h>
+/*****************************************************************************
+ * Local prototypes.
+ *****************************************************************************/
#ifdef WIN32
#include <windows.h>
extern void __wgetmainargs(int *argc, wchar_t ***wargv, wchar_t ***wenviron,
int expand_wildcards, int *startupinfo);
-#endif
+static inline void Kill(void) { }
+#else
-/*****************************************************************************
- * Local prototypes.
- *****************************************************************************/
-#if !defined(WIN32) && !defined(UNDER_CE)
-static void *SigHandler ( void *set );
+# include <signal.h>
+# include <time.h>
+# include <pthread.h>
+
+static void Kill (void);
+static void *SigHandler (void *set);
#endif
/*****************************************************************************
{
int i_ret;
+ setlocale (LC_ALL, "");
+
#ifndef __APPLE__
/* This clutters OSX GUI error logs */
fprintf( stderr, "VLC media player %s\n", VLC_Version() );
}
else
{
- ppsz_argv[i] = "";
+ ppsz_argv[i] = strdup ("");
}
}
else
i_ret = VLC_AddIntf( 0, NULL, VLC_TRUE, VLC_TRUE );
-#if !defined(WIN32) && !defined(UNDER_CE)
- pthread_cancel (sigth);
- pthread_join (sigth, NULL);
-#endif
-
/* Finish the threads */
VLC_CleanUp( 0 );
+ Kill ();
+
/* Destroy the libvlc structure */
VLC_Destroy( 0 );
+#if !defined(WIN32) && !defined(UNDER_CE)
+ pthread_cancel (sigth);
+# ifdef __APPLE__
+ /* In Mac OS X up to 10.4.8 sigwait (among others) is not a pthread
+ * cancellation point, so we throw a dummy quit signal to end
+ * sigwait() in the sigth thread */
+ pthread_kill (sigth, SIGQUIT);
+# endif
+ pthread_join (sigth, NULL);
+#endif
+
return i_ret;
}
* This thread receives all handled signals synchronously.
* It tries to end the program in a clean way.
*****************************************************************************/
-static void *SigHandler( void *data )
+static void *SigHandler (void *data)
{
const sigset_t *set = (sigset_t *)data;
time_t abort_time = 0;
vlc_bool_t b_die = VLC_FALSE;
+#ifdef __APPLE__
+ /* We really prefer the "force quit" menu item to act immediately */
+ b_die = VLC_TRUE;
+#endif
+
for (;;)
{
int i_signal, state;
(void)sigwait (set, &i_signal);
+#ifdef __APPLE__
+ /* In Mac OS X up to 10.4.8 sigwait (among others) is not a pthread
+ * cancellation point */
+ pthread_testcancel();
+#endif
+
/* Once a signal has been trapped, the termination sequence will be
* armed and subsequent signals will be ignored to avoid sending
* signals to a libvlc structure having been destroyed */
pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &state);
- if( !b_die )
+ if (!b_die)
{
b_die = VLC_TRUE;
- abort_time = time( NULL );
+ abort_time = time (NULL);
- fprintf( stderr, "signal %d received, terminating vlc - do it "
- "again in case it gets stuck\n", i_signal );
+ fprintf (stderr, "signal %d received, terminating vlc - do it "
+ "again in case it gets stuck\n", i_signal);
/* Acknowledge the signal received */
- VLC_Die( 0 );
+ Kill ();
}
else if( time( NULL ) > abort_time + 2 )
{
/* If user asks again 1 or 2 seconds later, die badly */
pthread_sigmask (SIG_UNBLOCK, set, NULL);
- fprintf( stderr, "user insisted too much, dying badly\n" );
- abort();
+ fprintf (stderr, "user insisted too much, dying badly\n");
+ abort ();
}
pthread_setcancelstate (state, NULL);
}
/* Never reached */
}
+
+
+#include <stdbool.h>
+static void Kill (void)
+{
+ static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+ static bool killed = false;;
+ pthread_mutex_lock (&lock);
+ if (!killed)
+ {
+ VLC_Die (0);
+ killed = true;
+ }
+ pthread_mutex_unlock (&lock);
+}
+
#endif
#if defined(UNDER_CE)