LCOV - code coverage report
Current view: directory - src/trusted/nonnacl_util - launcher_factory.cc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 24 20 83.3 %
Date: 2014-06-18 Functions: 0 0 -

       1                 : /* -*- c++ -*- */
       2                 : /*
       3                 :  * Copyright (c) 2013 The Native Client Authors. All rights reserved.
       4                 :  * Use of this source code is governed by a BSD-style license that can be
       5                 :  * found in the LICENSE file.
       6                 :  */
       7                 : 
       8                 : #include "native_client/src/trusted/nonnacl_util/launcher_factory.h"
       9                 : 
      10                 : #include <vector>
      11                 : 
      12                 : #include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h"
      13                 : 
      14                 : #if NACL_LINUX || NACL_OSX
      15                 : # define NACL_NEED_ZYGOTE 1
      16                 : #elif NACL_WINDOWS
      17                 : # define NACL_NEED_ZYGOTE 0
      18                 : #else
      19                 : # error "What OS?!?"
      20                 : #endif
      21                 : 
      22                 : #include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher_zygote.h"
      23                 : 
      24                 : namespace nacl {
      25                 : 
      26                 : using std::vector;
      27                 : 
      28                 : #if NACL_NEED_ZYGOTE
      29              52 : class SelLdrLauncherStandaloneProxy : public SelLdrLauncherStandalone {
      30                 :  public:
      31                 :   explicit SelLdrLauncherStandaloneProxy(Zygote* zygote);
      32                 : 
      33                 :   virtual bool StartViaCommandLine(
      34                 :       const vector<nacl::string>& prefix,
      35                 :       const vector<nacl::string>& sel_ldr_argv,
      36                 :       const vector<nacl::string>& app_argv);
      37                 :   // This version of StartViaCommandLine essentially splits
      38                 :   // SelLdrLauncherStandalone's version in half: we transfer the 3
      39                 :   // arguments to the zygote, where the zygote will create its own
      40                 :   // SelLdrLauncherStandalone object where the process creation
      41                 :   // occurs.  Note that InitCommandLine and BuildCommandLine will
      42                 :   // execute in the zygote's copy of the object, and it is in
      43                 :   // InitCommandLine where the CreateBootstrapSocket's dest_fd get
      44                 :   // pushed into the command line being built (preceded with "-X").
      45                 :   // After the zygote's copy of
      46                 :   // SelLdrLauncherStandalone::StartViaCommandLine has executed, the
      47                 :   // channel_ member has the desired communication channel needed to
      48                 :   // get (receive) the command channel and application channel socket
      49                 :   // addresses, and we send this channel_ back in the RPC to forcibly
      50                 :   // stuff into the SelLdrLauncherStandaloneProxy object.  Since the
      51                 :   // three argv objects are needed after this, the fact that they
      52                 :   // aren't initialized won't matter.  Ditto for close_after_launch_
      53                 :   // etc.
      54                 :   //
      55                 :   // NB: the zygote's copy of SelLdrLauncherStandalone must have its
      56                 :   // child_process_ pid set the NACL_INVALID_HANDLE before being
      57                 :   // dtor'd, since otherwise the newly launched process will
      58                 :   // immediately get killed.  The pid is retrieved along with the
      59                 :   // channel from the zygote, and we stuff that into the proxy object
      60                 :   // as well, so that the dtor semantics will work out.
      61                 :  private:
      62                 :   Zygote* zygote_;
      63                 : };
      64                 : 
      65              32 : SelLdrLauncherStandaloneProxy::SelLdrLauncherStandaloneProxy(Zygote* zygote)
      66              32 :     : zygote_(zygote) {}
      67                 : 
      68                 : bool SelLdrLauncherStandaloneProxy::StartViaCommandLine(
      69              16 :     const vector<nacl::string>& prefix,
      70              16 :     const vector<nacl::string>& sel_ldr_argv,
      71              16 :     const vector<nacl::string>& app_argv) {
      72              16 :   NaClHandle bootstrap_channel;
      73              16 :   int channel_id;
      74              16 :   int pid;
      75                 : 
      76              16 :   if (!zygote_->SpawnNaClSubprocess(prefix, sel_ldr_argv, app_argv,
      77                 :                                    &bootstrap_channel, &channel_id, &pid)) {
      78               0 :     return false;
      79                 :   }
      80              16 :   if (!zygote_->ReleaseChannelById(channel_id)) {
      81               0 :     (void) close(bootstrap_channel);
      82                 :     // On Unix-like OSes, closing the bootstrap channel suffices to
      83                 :     // ensure that the spawned subprocess will exit: the bootstrap
      84                 :     // channel contains the socketaddress socketpair endpoints for
      85                 :     // trusted and untrusted connections, and if the zygote had
      86                 :     // crashed, the last reference to the sockpair endpoints will
      87                 :     // disappear with the close, and the imc_accept would get an EOF.
      88                 :     // On Windows, we may be leaking a process, since the IMC channels
      89                 :     // are implemented with named pipes, and there won't be any EOF
      90                 :     // indication.  Since this code should never run unless the zygote
      91                 :     // process crashed and thus is hard to test, we leave this
      92                 :     // commented out.
      93                 :     //
      94                 :     // child_process_ = pid;
      95                 :     // KillChildProcess();
      96               0 :     return false;
      97                 :   }
      98              16 :   channel_ = bootstrap_channel;
      99              16 :   child_process_ = pid;
     100              16 :   return true;
     101              16 : }
     102                 : #endif
     103                 : 
     104                 : SelLdrLauncherStandaloneFactory::SelLdrLauncherStandaloneFactory(
     105              28 :     ZygoteBase* zygote_interface)
     106              28 :     : zygote_(zygote_interface) {}
     107                 : 
     108              13 : SelLdrLauncherStandaloneFactory::~SelLdrLauncherStandaloneFactory() {
     109              26 : }
     110                 : 
     111                 : #if NACL_NEED_ZYGOTE
     112                 : SelLdrLauncherStandalone* SelLdrLauncherStandaloneFactory::
     113                 : MakeSelLdrLauncherStandalone() {
     114              32 :   return new SelLdrLauncherStandaloneProxy(
     115                 :       reinterpret_cast<ZygotePosix *>(zygote_));
     116               0 : }
     117                 : #else
     118                 : SelLdrLauncherStandalone* SelLdrLauncherStandaloneFactory::
     119                 : MakeSelLdrLauncherStandalone() {
     120                 :   return new SelLdrLauncherStandalone();
     121                 : }
     122                 : #endif
     123                 : 
     124                 : }  // namespace nacl

Generated by: LCOV version 1.7