unix_hurl.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:12k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: unix_hurl.cpp,v 1.3.42.3 2004/07/09 01:47:39 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #ifndef _UNIX
  50. #error This is the UNIX hypernav stuff!!
  51. #endif
  52. #include <signal.h>
  53. #include <sys/wait.h>
  54. #include <unistd.h>
  55. #include <errno.h>
  56. #include <sys/types.h>
  57. #include <stdlib.h> // for exit() prototype
  58. #include <string.h>
  59. #include <stdio.h>
  60. #include "hxassert.h"
  61. #include "hxstrutl.h"
  62. #include "unix_hurl.h"
  63. #include "cunixprefutils.h"
  64. //Globals for the url passing to child proc in UNIX.
  65. #define MAX_URL_LEN 1024
  66. #define MAX_EXEC_LEN 1024
  67. int zn_anHURLPipe[2] = { -1, -1 };
  68. int zm_nHurlProcID = -1;
  69. int zn_anExecPipe[2] = { -1, -1 };
  70. int zm_nExecProcID = -1;
  71. char g_pURL[MAX_URL_LEN]; /* Flawfinder: ignore */
  72. pid_t g_childPID;
  73. void InitHurlListener()
  74. {
  75.     zn_anHURLPipe[0] = -1;
  76.     zn_anHURLPipe[1] = -1;
  77.     zn_anExecPipe[0] = -1;
  78.     zn_anExecPipe[1] = -1;
  79. }
  80. void browse_child(int status)
  81. {
  82.     int chstatus;
  83.     pid_t childPID;
  84.     while((childPID = waitpid(0, &chstatus, WNOHANG)) > 0)
  85.     {
  86. if(g_childPID == childPID)
  87. {
  88.     g_childPID = 0;
  89.     if(WEXITSTATUS(chstatus) != 0)
  90.     {
  91. if(fork() == 0)
  92. {
  93.     CUnixPrefUtils::CleanEnv();
  94.     execlp("netscape", "netscape", g_pURL, NULL);
  95.     _exit(0);
  96. }
  97.     }
  98. }
  99.     }
  100. }
  101. void _ListenForHurlRequests()
  102. {
  103.     int  status = 0;
  104.     char szURL[MAX_URL_LEN+1]; /* Flawfinder: ignore */
  105.     char szBuff[MAX_URL_LEN+1]; /* Flawfinder: ignore */
  106.     //If its there grab it.
  107.     szBuff[0]= '';
  108.     szURL[0]= '';
  109.     status = 1;
  110.     while( status != 0 )
  111.     {
  112.         status = ::read(zn_anHURLPipe[0], szBuff, MAX_URL_LEN);
  113.         
  114.         if( status > 0 )
  115.         {
  116.             if( (strlen(szURL)+status)<MAX_URL_LEN )
  117.             {
  118.                 strncat( szURL, szBuff, status ); szURL[status] = ''; /* Flawfinder: ignore */
  119.             }
  120.             else
  121.             {
  122.                 //URL is too long. We don't want to over run.
  123.                 HX_ASSERT( "URL exceeds MAX_URL_LEN" == NULL );
  124.                 //Reset everything and keep looping.
  125.                 status    = -1;
  126.                 errno     = EAGAIN;
  127.                 szURL[0]  ='';
  128.                 szBuff[0] ='';
  129.             }
  130.         }
  131.         
  132.         //Did we find an error?
  133.         if( status < 0)
  134.         {
  135.             if( errno != EINTR && errno != EAGAIN )
  136.             {
  137.                 //A really bad error....
  138.                 HX_ASSERT( "a really bad error" == NULL );
  139.             }
  140.             //otherwise just ignore it. We were just nonblocking or interupted
  141.             //by a signal.
  142.         }
  143.         
  144.         if( status > 0 && szBuff[status-1]=='' )
  145.         {
  146.             //We just received a newline for our URL. That means we are
  147.             //ready to hurl it.
  148.             char browsercmd[MAX_URL_LEN+100]; /* Flawfinder: ignore */
  149.             if((g_childPID = fork()) == 0)
  150.             {
  151.                 SafeSprintf(browsercmd, MAX_URL_LEN+100, "netscape -remote 'openURL(%s)' >/dev/null  2>&1", szURL);
  152. CUnixPrefUtils::CleanEnv();
  153.                 execlp("sh",  "sh", "-c", browsercmd, NULL);
  154.                 _exit(0);
  155.             }
  156.             else
  157.             {
  158.                 SafeStrCpy(g_pURL, szURL, MAX_URL_LEN);
  159.                 signal(SIGCHLD, browse_child);
  160.             }
  161.             //Reset everything and keep looping.
  162.             status = -1;
  163.             szURL[0]='';
  164.             szBuff[0]='';
  165.         }
  166.         
  167.     } //while(status)
  168.     ::close( zn_anHURLPipe[0] );
  169.     zn_anHURLPipe[0]=-1;
  170.     _exit(0);
  171. }
  172. void _ListenForExecRequests()
  173. {
  174.     int  status = 0;
  175.     char szExec[MAX_EXEC_LEN+1]; /* Flawfinder: ignore */
  176.     char szBuff[MAX_EXEC_LEN+1]; /* Flawfinder: ignore */
  177.     //If its there grab it.
  178.     szBuff[0]= '';
  179.     szExec[0]= '';
  180.     status = 1;
  181.     while( status != 0 )
  182.     {
  183.         status = ::read(zn_anExecPipe[0], szBuff, MAX_EXEC_LEN);
  184.         
  185.         if( status > 0 )
  186.         {
  187.             if( (strlen(szExec)+status)<MAX_EXEC_LEN )
  188.             {
  189.                 strncat( szExec, szBuff, status ); szExec[status] = ''; /* Flawfinder: ignore */
  190.             }
  191.             else
  192.             {
  193.                 //URL is too long. We don't want to over run.
  194.                 HX_ASSERT( "EXEC string exceeds MAX_EXEC_LEN" == NULL );
  195.                 //Reset everything and keep looping.
  196.                 status     = -1;
  197.                 errno      = EAGAIN;
  198.                 szExec[0]  ='';
  199.                 szBuff[0]  ='';
  200.             }
  201.         }
  202.         
  203.         //Did we find an error?
  204.         if( status < 0)
  205.         {
  206.             if( errno != EINTR && errno != EAGAIN )
  207.             {
  208.                 //A really bad error....
  209.                 HX_ASSERT( "a really bad error" == NULL );
  210.                 _exit(0);
  211.             }
  212.             //otherwise just ignore it. We were just nonblocking or interupted
  213.             //by a signal.
  214.         }
  215.         
  216.         if( status > 0 && szBuff[status-1]=='' )
  217.         {
  218.             //We just received a newline for our exec string. We can exec now....
  219.             char browsercmd[MAX_EXEC_LEN+100]; /* Flawfinder: ignore */
  220.     signal(SIGCHLD, browse_child);
  221.             if(fork() == 0)
  222.             {
  223. CUnixPrefUtils::CleanEnv();
  224.                 execlp("sh",  "sh", "-c", szExec, NULL);
  225.                 _exit(0);
  226.             }
  227.             //Reset everything and keep looping.
  228.             status = -1;
  229.             szExec[0]='';
  230.             szBuff[0]='';
  231.         }
  232.         
  233.     } //while(status)
  234.     ::close( zn_anExecPipe[0] );
  235.     zn_anExecPipe[0]=-1;
  236.     _exit(0);
  237. }
  238. void ShutdownHurlListener()
  239. {
  240.     if( zn_anHURLPipe[0] != -1 )
  241.         close( zn_anHURLPipe[0] );
  242.     if( zn_anHURLPipe[1] != -1 )
  243.         close( zn_anHURLPipe[1] );
  244.     if( zn_anExecPipe[0] != -1 )
  245.         close( zn_anExecPipe[0] );
  246.     if( zn_anExecPipe[1] != -1 )
  247.         close( zn_anExecPipe[1] );
  248.     
  249.     zn_anHURLPipe[0] = -1;
  250.     zn_anHURLPipe[1] = -1; 
  251.     zn_anExecPipe[0] = -1;
  252.     zn_anExecPipe[1] = -1;
  253. }
  254. void StartHurlListener()
  255. {
  256.     if ( 0 != pipe(zn_anHURLPipe) )
  257.     {
  258. //Can't create pipe.
  259. zn_anHURLPipe[0] = -1;
  260. zn_anHURLPipe[1] = -1;
  261.         HX_ASSERT( "Can't create pipe for hurling...." == NULL );
  262.     }
  263.     //First create the hurling process.
  264.     if( 0 > (zm_nHurlProcID = fork()))
  265.     {
  266. //Error trying to fork.
  267. //What should we do?
  268.         HX_ASSERT( "Can't fork for hurling....." == NULL );
  269.     }
  270.     if( 0 == zm_nHurlProcID )
  271.     {
  272. //This is the child proc. Its life is the life of the parent so
  273.         //we don't need to do a waitpid unless we want to.
  274. //Close the write end of the pipe.
  275. if ( 0 != ::close( zn_anHURLPipe[1]) )
  276. {
  277.     //close, error. Kill this child proc.
  278.             //XXXGfw non fatal for now.
  279.             HX_ASSERT( "Can't close pipe in child." == NULL );
  280.     //_exit(1);
  281. }
  282.         zn_anHURLPipe[1]=-1;
  283.         //
  284.         // Enter a loop here that just looks for hurling requests
  285.         // on the pipe and does a fork/exec for each one.
  286.         //
  287.         // zn_anHURLPipe[0] == Read end of pipe.
  288.         // zn_anHURLPipe[1] == Write end of pipe.
  289.         //
  290.         // All urls are null terminated.
  291.         // All reads are blocking. No reason no to be.
  292.         //We never return from the following.
  293.         _ListenForHurlRequests();
  294.     }
  295.     //Leave the exec pipe open for..........
  296.     //The parent just returns after closing the read end of the pipe....
  297.     //Close the read end of the pipe.
  298.     if ( 0 != ::close( zn_anHURLPipe[0]) )
  299.     {
  300.         HX_ASSERT( "Can't close pipe in parent." == NULL );
  301.     }
  302.     zn_anHURLPipe[0]=-1;
  303.     if ( 0 != pipe(zn_anExecPipe) )
  304.     {
  305. //Can't create pipe.
  306. zn_anExecPipe[0] = -1;
  307. zn_anExecPipe[1] = -1;
  308.         HX_ASSERT( "Can't create pipe for execing...." == NULL );
  309.     }
  310.     
  311.     //Now create the process for execing.....
  312.     if( 0 > (zm_nExecProcID = fork()))
  313.     {
  314. //Error trying to fork.
  315. //What should we do?
  316.         HX_ASSERT( "Can't fork for execing....." == NULL );
  317.     }
  318.     if( 0 == zm_nExecProcID )
  319.     {
  320. //This is the child proc. Its life is the life of the parent so
  321.         //we don't need to do a waitpid unless we want to.
  322. //Close the write end of the pipe.
  323. if ( 0 != ::close( zn_anExecPipe[1]) )
  324. {
  325.     //close, error. Kill this child proc.
  326.             //XXXGfw non fatal for now.
  327.             HX_ASSERT( "Can't close pipe in exec child." == NULL );
  328.     //_exit(1);
  329. }
  330.         zn_anExecPipe[1]=-1;
  331.         //
  332.         // zn_anExecPipe[0] == Read end of pipe.
  333.         // zn_anExecPipe[1] == Write end of pipe.
  334.         //
  335.         // All execs are null terminated.
  336.         // All reads are blocking. No reason no to be.
  337.         //We never return from the following.
  338.         _ListenForExecRequests();
  339.     }
  340.     if ( 0 != ::close( zn_anExecPipe[0]) )
  341.     {
  342.         HX_ASSERT( "Can't close pipe in parent." == NULL );
  343.     }
  344.     zn_anExecPipe[0]=-1;
  345. }
  346. void SendHurlRequest(const char *pszURL)
  347. {
  348.     //We have started a child proc to do the hurling for us. If this is
  349.     //the core thread we just send the request to the child proct via the
  350.     //open pipe. If this is the child proc then we actually do it.
  351.     if( pszURL && strlen(pszURL) && zn_anHURLPipe[1]>=0 )
  352.         ::write( zn_anHURLPipe[1], pszURL, strlen(pszURL)+1 );
  353. }
  354. void SendExecRequest(const char *pszExec)
  355. {
  356.     //We have started a child proc to do the Exec for us. If this is
  357.     //the core thread we just send the request to the child proct via the
  358.     //open pipe. If this is the child proc then we actually do it.
  359.     if( pszExec && strlen(pszExec) && zn_anExecPipe[1]>=0 )
  360.     {
  361.         ::write( zn_anExecPipe[1], pszExec, strlen(pszExec)+1 );
  362.     }
  363. }