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

📄 unix_hurl.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
字号:
/* ***** BEGIN LICENSE BLOCK ***** 
 * Version: RCSL 1.0/RPSL 1.0 
 *  
 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
 *      
 * The contents of this file, and the files included with this file, are 
 * subject to the current version of the RealNetworks Public Source License 
 * Version 1.0 (the "RPSL") available at 
 * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 * the file under the RealNetworks Community Source License Version 1.0 
 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
 * in which case the RCSL will apply. You may also obtain the license terms 
 * directly from RealNetworks.  You may not use this file except in 
 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
 * applicable to this file, the RCSL.  Please see the applicable RPSL or 
 * RCSL for the rights, obligations and limitations governing use of the 
 * contents of the file.  
 *  
 * This file is part of the Helix DNA Technology. RealNetworks is the 
 * developer of the Original Code and owns the copyrights in the portions 
 * it created. 
 *  
 * This file, and the files included with this file, is distributed and made 
 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
 * 
 * Technology Compatibility Kit Test Suite(s) Location: 
 *    http://www.helixcommunity.org/content/tck 
 * 
 * Contributor(s): 
 *  
 * ***** END LICENSE BLOCK ***** */ 

#ifndef _UNIX
#error This is the UNIX hypernav stuff!!
#endif

#include <signal.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <stdlib.h>	// for exit() prototype
#include <string.h>
#include <stdio.h>

#include "hxassert.h"
#include "hxstrutl.h"
#include "unix_hurl.h"

#include "cunixprefutils.h"

//Globals for the url passing to child proc in UNIX.
#define MAX_URL_LEN 1024
#define MAX_EXEC_LEN 1024
int zn_anHURLPipe[2] = { -1, -1 };
int zm_nHurlProcID = -1;
int zn_anExecPipe[2] = { -1, -1 };
int zm_nExecProcID = -1;

char g_pURL[MAX_URL_LEN]; /* Flawfinder: ignore */
pid_t g_childPID;

void InitHurlListener()
{
    zn_anHURLPipe[0] = -1;
    zn_anHURLPipe[1] = -1;
    zn_anExecPipe[0] = -1;
    zn_anExecPipe[1] = -1;
}

void browse_child(int status)
{
    int chstatus;
    pid_t childPID;

    while((childPID = waitpid(0, &chstatus, WNOHANG)) > 0)
    {
	if(g_childPID == childPID)
	{
	    g_childPID = 0;

	    if(WEXITSTATUS(chstatus) != 0)
	    {
		if(fork() == 0)
		{
		    CUnixPrefUtils::CleanEnv();
		    execlp("netscape", "netscape", g_pURL, NULL);
		    _exit(0);
		}
	    }
	}
    }
}

void _ListenForHurlRequests()
{
    int  status = 0;
    char szURL[MAX_URL_LEN+1]; /* Flawfinder: ignore */

    char szBuff[MAX_URL_LEN+1]; /* Flawfinder: ignore */

    //If its there grab it.
    szBuff[0]= '\0';
    szURL[0]= '\0';
    status = 1;
    while( status != 0 )
    {
        status = ::read(zn_anHURLPipe[0], szBuff, MAX_URL_LEN);
        
        if( status > 0 )
        {
            if( (strlen(szURL)+status)<MAX_URL_LEN )
            {
                strncat( szURL, szBuff, status ); szURL[status] = '\0'; /* Flawfinder: ignore */
            }
            else
            {
                //URL is too long. We don't want to over run.
                HX_ASSERT( "URL exceeds MAX_URL_LEN" == NULL );
                //Reset everything and keep looping.
                status    = -1;
                errno     = EAGAIN;
                szURL[0]  ='\0';
                szBuff[0] ='\0';
            }
        }
        
        //Did we find an error?
        if( status < 0)
        {
            if( errno != EINTR && errno != EAGAIN )
            {
                //A really bad error....
                HX_ASSERT( "a really bad error" == NULL );
            }
            //otherwise just ignore it. We were just nonblocking or interupted
            //by a signal.
        }
        
        if( status > 0 && szBuff[status-1]=='\0' )
        {
            //We just received a newline for our URL. That means we are
            //ready to hurl it.
            char browsercmd[MAX_URL_LEN+100]; /* Flawfinder: ignore */
            if((g_childPID = fork()) == 0)
            {
                SafeSprintf(browsercmd, MAX_URL_LEN+100, "netscape -remote 'openURL(%s)' >/dev/null  2>&1", szURL);
		CUnixPrefUtils::CleanEnv();
                execlp("sh",  "sh", "-c", browsercmd, NULL);
                _exit(0);
            }
            else
            {
                SafeStrCpy(g_pURL, szURL, MAX_URL_LEN);
                signal(SIGCHLD, browse_child);
            }

            //Reset everything and keep looping.
            status = -1;
            szURL[0]='\0';
            szBuff[0]='\0';
        }
        
    } //while(status)

    ::close( zn_anHURLPipe[0] );
    zn_anHURLPipe[0]=-1;
    _exit(0);
}
void _ListenForExecRequests()
{
    int  status = 0;
    char szExec[MAX_EXEC_LEN+1]; /* Flawfinder: ignore */

    char szBuff[MAX_EXEC_LEN+1]; /* Flawfinder: ignore */

    //If its there grab it.
    szBuff[0]= '\0';
    szExec[0]= '\0';
    status = 1;
    while( status != 0 )
    {
        status = ::read(zn_anExecPipe[0], szBuff, MAX_EXEC_LEN);
        
        if( status > 0 )
        {
            if( (strlen(szExec)+status)<MAX_EXEC_LEN )
            {
                strncat( szExec, szBuff, status ); szExec[status] = '\0'; /* Flawfinder: ignore */
            }
            else
            {
                //URL is too long. We don't want to over run.
                HX_ASSERT( "EXEC string exceeds MAX_EXEC_LEN" == NULL );
                //Reset everything and keep looping.
                status     = -1;
                errno      = EAGAIN;
                szExec[0]  ='\0';
                szBuff[0]  ='\0';
            }
        }
        
        //Did we find an error?
        if( status < 0)
        {
            if( errno != EINTR && errno != EAGAIN )
            {
                //A really bad error....
                HX_ASSERT( "a really bad error" == NULL );
                _exit(0);
            }
            //otherwise just ignore it. We were just nonblocking or interupted
            //by a signal.
        }
        
        if( status > 0 && szBuff[status-1]=='\0' )
        {
            //We just received a newline for our exec string. We can exec now....
            char browsercmd[MAX_EXEC_LEN+100]; /* Flawfinder: ignore */
	    signal(SIGCHLD, browse_child);

            if(fork() == 0)
            {
		CUnixPrefUtils::CleanEnv();
                execlp("sh",  "sh", "-c", szExec, NULL);
                _exit(0);
            }

            //Reset everything and keep looping.
            status = -1;
            szExec[0]='\0';
            szBuff[0]='\0';
        }
        
    } //while(status)

    ::close( zn_anExecPipe[0] );
    zn_anExecPipe[0]=-1;
    _exit(0);
}

void ShutdownHurlListener()
{
    if( zn_anHURLPipe[0] != -1 )
        close( zn_anHURLPipe[0] );
    if( zn_anHURLPipe[1] != -1 )
        close( zn_anHURLPipe[1] );
    if( zn_anExecPipe[0] != -1 )
        close( zn_anExecPipe[0] );
    if( zn_anExecPipe[1] != -1 )
        close( zn_anExecPipe[1] );
    
    zn_anHURLPipe[0] = -1;
    zn_anHURLPipe[1] = -1; 
    zn_anExecPipe[0] = -1;
    zn_anExecPipe[1] = -1;
}

void StartHurlListener()
{
    if ( 0 != pipe(zn_anHURLPipe) )
    {
	//Can't create pipe.
	zn_anHURLPipe[0] = -1;
	zn_anHURLPipe[1] = -1;
        HX_ASSERT( "Can't create pipe for hurling...." == NULL );
    }

    //First create the hurling process.
    if( 0 > (zm_nHurlProcID = fork()))
    {
	//Error trying to fork.
	//What should we do?
        HX_ASSERT( "Can't fork for hurling....." == NULL );
    }
    if( 0 == zm_nHurlProcID )
    {
	//This is the child proc. Its life is the life of the parent so
        //we don't need to do a waitpid unless we want to.

	//Close the write end of the pipe.
	if ( 0 != ::close( zn_anHURLPipe[1]) )
	{
	    //close, error. Kill this child proc.
            //XXXGfw non fatal for now.
            HX_ASSERT( "Can't close pipe in child." == NULL );
	    //_exit(1);
	}
        zn_anHURLPipe[1]=-1;
        //
        // Enter a loop here that just looks for hurling requests
        // on the pipe and does a fork/exec for each one.
        //
        // zn_anHURLPipe[0] == Read end of pipe.
        // zn_anHURLPipe[1] == Write end of pipe.
        //
        // All urls are null terminated.
        // All reads are blocking. No reason no to be.

        //We never return from the following.
        _ListenForHurlRequests();
    }
    //Leave the exec pipe open for..........
    //The parent just returns after closing the read end of the pipe....
    //Close the read end of the pipe.
    if ( 0 != ::close( zn_anHURLPipe[0]) )
    {
        HX_ASSERT( "Can't close pipe in parent." == NULL );
    }
    zn_anHURLPipe[0]=-1;
    if ( 0 != pipe(zn_anExecPipe) )
    {
	//Can't create pipe.
	zn_anExecPipe[0] = -1;
	zn_anExecPipe[1] = -1;
        HX_ASSERT( "Can't create pipe for execing...." == NULL );
    }

    
    //Now create the process for execing.....
    if( 0 > (zm_nExecProcID = fork()))
    {
	//Error trying to fork.
	//What should we do?
        HX_ASSERT( "Can't fork for execing....." == NULL );
    }
    if( 0 == zm_nExecProcID )
    {
	//This is the child proc. Its life is the life of the parent so
        //we don't need to do a waitpid unless we want to.

	//Close the write end of the pipe.
	if ( 0 != ::close( zn_anExecPipe[1]) )
	{
	    //close, error. Kill this child proc.
            //XXXGfw non fatal for now.
            HX_ASSERT( "Can't close pipe in exec child." == NULL );
	    //_exit(1);
	}
        zn_anExecPipe[1]=-1;
        //
        // zn_anExecPipe[0] == Read end of pipe.
        // zn_anExecPipe[1] == Write end of pipe.
        //
        // All execs are null terminated.
        // All reads are blocking. No reason no to be.

        //We never return from the following.
        _ListenForExecRequests();
    }

    if ( 0 != ::close( zn_anExecPipe[0]) )
    {
        HX_ASSERT( "Can't close pipe in parent." == NULL );
    }
    zn_anExecPipe[0]=-1;
}

void SendHurlRequest(const char *pszURL)
{
    //We have started a child proc to do the hurling for us. If this is
    //the core thread we just send the request to the child proct via the
    //open pipe. If this is the child proc then we actually do it.
    if( pszURL && strlen(pszURL) && zn_anHURLPipe[1]>=0 )
        ::write( zn_anHURLPipe[1], pszURL, strlen(pszURL)+1 );
}
void SendExecRequest(const char *pszExec)
{
    //We have started a child proc to do the Exec for us. If this is
    //the core thread we just send the request to the child proct via the
    //open pipe. If this is the child proc then we actually do it.
    if( pszExec && strlen(pszExec) && zn_anExecPipe[1]>=0 )
    {
        ::write( zn_anExecPipe[1], pszExec, strlen(pszExec)+1 );
    }
}

⌨️ 快捷键说明

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