⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 externrun.c

📁 video linux conference
💻 C
字号:
/***************************************************************************** * externrun.c: Run extern programs (vlc:run:"theprogram":delayinseconds) ***************************************************************************** * Copyright (C) 2005 VideoLAN * $Id: externrun.c 10634 2005-04-10 14:00:40Z titer $ * * Authors: Sylvain Cadilhac <sylv@via.ecp.fr> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include <stdlib.h>                                      /* malloc(), free() */#include <vlc/vlc.h>#include <vlc/intf.h>#include <string.h>#include <errno.h>#if defined( WIN32 )#include <windows.h>#else# include <sys/types.h># include <unistd.h># include <sys/wait.h>#endif/***************************************************************************** * run_command_t: a command and its delay *****************************************************************************/struct run_command_t{    int                  i_delay;    char                 *psz_torun;    struct run_command_t *p_next;};typedef struct run_command_t run_command_t;/***************************************************************************** * intf_sys_t: description and status of FB interface *****************************************************************************/struct intf_sys_t{    vlc_mutex_t   change_lock;    mtime_t       next_check;    run_command_t *p_first_command;    run_command_t *p_last_command;};/***************************************************************************** * Local prototypes *****************************************************************************/static int  Open    ( vlc_object_t * );static void Close   ( vlc_object_t * );static void Run     ( intf_thread_t * );static int  AddRunCommand( vlc_object_t *, char const *,                           vlc_value_t, vlc_value_t, void * );/***************************************************************************** * Module descriptor *****************************************************************************/vlc_module_begin();    set_category( CAT_INTERFACE );    set_description( _("Execution of extern programs interface function") );    set_capability( "interface", 0 );    set_callbacks( Open, Close );vlc_module_end();/***************************************************************************** * Open: initialize interface *****************************************************************************/static int Open( vlc_object_t *p_this ){    intf_thread_t *p_intf = (intf_thread_t *)p_this;        /* Search for the Playlist object */    playlist_t *p_playlist;        p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );    if( p_playlist == NULL )    {        msg_Err( p_intf, "we are not attached to a playlist" );        return 1;    }        /* Allocate instance and initialize some members */    p_intf->p_sys = malloc( sizeof( intf_sys_t ) );    if( p_intf->p_sys == NULL )    {        msg_Err( p_intf, "out of memory" );        return 1;    }    vlc_mutex_init( p_intf, &p_intf->p_sys->change_lock );        var_Create( p_playlist, "run-program-command", VLC_VAR_STRING );        p_intf->p_sys->p_first_command = NULL;    p_intf->p_sys->p_last_command = NULL;    p_intf->pf_run = Run;    var_AddCallback( p_playlist, "run-program-command", AddRunCommand, p_intf );    vlc_object_release( p_playlist );            return 0;}/***************************************************************************** * Close: destroy interface *****************************************************************************/static void Close( vlc_object_t *p_this ){    intf_thread_t *p_intf = (intf_thread_t *)p_this;    run_command_t *p_command;    run_command_t *p_next;    playlist_t *p_playlist;        p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );    if( p_playlist == NULL )    {        msg_Err( p_intf, "we are not attached to a playlist" );        return;    }         var_Destroy( p_playlist, "run-program-command" );    vlc_object_release( p_playlist );          p_command = p_intf->p_sys->p_first_command;    while( p_command )    {        p_next = p_command->p_next;        free( p_command->psz_torun );        free( p_command );        p_command = p_next;    }    /* Destroy structure */    free( p_intf->p_sys );}/***************************************************************************** * Run: main loop *****************************************************************************/static void Run( intf_thread_t *p_intf ){    run_command_t *p_command;    run_command_t *p_previous;    p_intf->p_sys->next_check = mdate() + 1000000;    while( !p_intf->b_die )    {        vlc_mutex_lock( &p_intf->p_sys->change_lock );        p_command = p_intf->p_sys->p_first_command;        p_previous = NULL;        while( p_command )        {            if( p_command->i_delay > 0 )            {                p_command->i_delay--;                p_previous = p_command;                p_command = p_previous->p_next;            }            else            {#if defined( WIN32 )                STARTUPINFO si;                PROCESS_INFORMATION pi;                msg_Info( p_intf, "running %s", p_command->psz_torun );                ZeroMemory( &si, sizeof(si) );                si.cb = sizeof(si);                ZeroMemory( &pi, sizeof(pi) );                if( !CreateProcess( NULL, p_command->psz_torun, NULL, NULL,                    FALSE, 0, NULL, NULL, &si, &pi ) )                 {                    msg_Err( p_intf, "can't run \"%s\"", p_command->psz_torun );                }    #else                pid_t pid;                msg_Info( p_intf, "running %s", p_command->psz_torun );                pid = fork();                switch( pid )                {                    case -1:                        msg_Err( p_intf, "can't fork: %s", strerror( errno ) );                        break;                    case 0:                        execlp( p_command->psz_torun, p_command->psz_torun,                                NULL );                        msg_Err( p_intf, "can't run \"%s\": %s",                                 p_command->psz_torun, strerror( errno ) );                        exit (1);                    default:                    {                        int i_status;                        /* if we don't do that, we'll get zombies processes                         * FIXME: should still be possible to spawn other                         * proceses*/                        while( waitpid( pid, &i_status, 0 ) != pid );                        if( WIFEXITED( i_status ) )                        {                            i_status = WEXITSTATUS( i_status );                            if( i_status )                                msg_Warn( p_intf, "process %d returned %d",                                          pid, i_status );                        }                        else if( WIFSIGNALED( i_status ) )                        {                            i_status = WTERMSIG( i_status );                            msg_Warn( p_intf,                                      "process %d terminated by signal %d",                                      pid, i_status );                        }                    }                }#endif                if( p_previous )                {                    p_previous->p_next = p_command->p_next;                    free( p_command->psz_torun );                    free( p_command );                    p_command = p_previous->p_next;                }                else                {                    p_intf->p_sys->p_first_command = p_command->p_next;                    free( p_command->psz_torun );                    free( p_command );                    if ( p_intf->p_sys->p_last_command == p_command )                    {                        p_intf->p_sys->p_last_command = p_command->p_next;                    }                     p_command = p_intf->p_sys->p_first_command;                }            }        }        vlc_mutex_unlock( &p_intf->p_sys->change_lock );        mwait( p_intf->p_sys->next_check );        p_intf->p_sys->next_check += 1000000;    }}/***************************************************************************** *  *****************************************************************************/static int AddRunCommand( vlc_object_t *p_this, char const *psz_var,                     vlc_value_t oldval, vlc_value_t newval, void *p_data ){    intf_thread_t *p_intf = (intf_thread_t *)p_data;    run_command_t *p_command;    char *psz_command = NULL;    int i_delay = 0;    char *psz_delay = strrchr( newval.psz_string, ':' );    if ( psz_delay )    {        char *psz_err;        i_delay = ( int )strtol( psz_delay + 1, &psz_err, 10 );        if ( *psz_err == 0 )        {            psz_command = malloc( psz_delay - newval.psz_string );            if ( psz_command == NULL )            {                msg_Err( p_intf, "out of memory: can't add run command" );                return VLC_EGENERIC;            }            strncpy( psz_command, newval.psz_string, psz_delay - newval.psz_string );            psz_command[ psz_delay - newval.psz_string ] = '\0';        }    }    if ( !psz_command )    {        psz_command = malloc( strlen( newval.psz_string ) + 1 );        strcpy( psz_command, newval.psz_string );    }        p_command = malloc( sizeof( run_command_t ) );    if ( p_command == NULL )    {        msg_Err( p_intf, "out of memory: can't add run command" );        return VLC_EGENERIC;        }    p_command->i_delay = i_delay;    p_command->p_next = NULL;    p_command->psz_torun = psz_command;        msg_Info( p_intf, "will run %s in %d seconds", psz_command, i_delay );            vlc_mutex_lock( &p_intf->p_sys->change_lock );    if ( p_intf->p_sys->p_last_command )    {        p_intf->p_sys->p_last_command->p_next = p_command;        p_intf->p_sys->p_last_command = p_command;    }    else    {        p_intf->p_sys->p_last_command = p_command;        p_intf->p_sys->p_first_command = p_command;    }    vlc_mutex_unlock( &p_intf->p_sys->change_lock );    return VLC_SUCCESS;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -