LCOV - code coverage report
Current view: directory - src/trusted/nonnacl_util - sel_ldr_launcher.h (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 9 8 88.9 %
Date: 2012-02-16 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2011 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can be
       4                 :  * found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : 
       8                 : // Utility class for launching sel_ldr.
       9                 : 
      10                 : #ifndef NATIVE_CLIENT_SRC_TRUSTED_NONNACL_UTIL_SEL_LDR_LAUNCHER_H_
      11                 : #define NATIVE_CLIENT_SRC_TRUSTED_NONNACL_UTIL_SEL_LDR_LAUNCHER_H_
      12                 : 
      13                 : #include <vector>
      14                 : 
      15                 : #include "native_client/src/include/nacl_scoped_ptr.h"
      16                 : #include "native_client/src/include/nacl_string.h"
      17                 : #include "native_client/src/include/portability.h"
      18                 : #include "native_client/src/shared/imc/nacl_imc.h"
      19                 : #include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
      20                 : #include "native_client/src/trusted/service_runtime/nacl_error_code.h"
      21                 : 
      22                 : struct NaClSrpcChannel;
      23                 : struct NaClDesc;
      24                 : 
      25                 : namespace nacl {
      26                 : // TODO(robertm): Move this to new header if it becomes more popular.
      27              22 : template <class T> nacl::string ToString(const T& t) {
      28              22 :   nacl::stringstream ss;
      29              22 :   ss << t;
      30              22 :   return ss.str();
      31                 : }
      32                 : 
      33                 : /*
      34                 :  * This class defines an interface that locates sel_ldr.
      35                 :  */
      36                 : class SelLdrLocator {
      37                 :  public:
      38                 :   // Returns a directory with sel_ldr.
      39                 :   virtual void GetDirectory(char* buffer, size_t len) = 0;
      40                 : 
      41              12 :   SelLdrLocator() {}
      42                 : 
      43               0 :   virtual ~SelLdrLocator() {}
      44                 : 
      45                 :   DISALLOW_COPY_AND_ASSIGN(SelLdrLocator);
      46                 : };
      47                 : 
      48                 : /*
      49                 :  * Default implementation of SelLdrLocator which tries to
      50                 :  * locate a browser plugin. Default constructor of SelLdrLauncher use it.
      51                 :  */
      52              11 : class PluginSelLdrLocator : public SelLdrLocator {
      53                 :  public:
      54                 :   // We have different implementations for all platforms.
      55                 :   virtual void GetDirectory(char* buffer, size_t len);
      56                 : 
      57              12 :   PluginSelLdrLocator() {}
      58                 : 
      59                 :   DISALLOW_COPY_AND_ASSIGN(PluginSelLdrLocator);
      60                 : };
      61                 : 
      62                 : /*
      63                 :  * This class encapsulates the process of launching an instance of sel_ldr
      64                 :  * to communicate with the NaCl plugin over an IMC channel.
      65                 :  *
      66                 :  * The sel_ldr process can be forked directly using a command line of args
      67                 :  * or by sending a message to the (Chrome) browser process.
      68                 :  */
      69                 : struct SelLdrLauncher {
      70                 :  public:
      71                 :   SelLdrLauncher();
      72                 : 
      73                 :   explicit SelLdrLauncher(SelLdrLocator* sel_ldr_locator);
      74                 :   ~SelLdrLauncher();
      75                 : 
      76                 :   Handle child_process() const { return child_process_; }
      77                 : 
      78                 :   /////////////////////////////////////////////////////////////////////////////
      79                 :   // Command line start-up: (Only used by sel_universal.)
      80                 :   //
      81                 :   // The command line must include a file path for the nexe application or an
      82                 :   // indicator that a reference will be supplied after the launch over RPC.
      83                 :   /////////////////////////////////////////////////////////////////////////////
      84                 : 
      85                 :   // Creates a socket pair.  Maps the first socket into the NaCl
      86                 :   // subprocess's FD table as dest_fd. Sets the corresponding command line arg.
      87                 :   // Returns the second socket. Returns kInvalidHandle on failure.
      88                 :   Handle ExportImcFD(int dest_fd);
      89                 : 
      90                 :   // Sets up the command line to start a sel_ldr.  Specifies |imc_fd| to
      91                 :   // use for bootstrapping. |sel_ldr_argv| specifies the arguments to be
      92                 :   // passed to sel_ldr itself, while |application_argv| specifies the arguments
      93                 :   // to be passed to the nexe.
      94                 :   void InitCommandLine(int imc_fd,
      95                 :                        const std::vector<nacl::string>& sel_ldr_argv,
      96                 :                        const std::vector<nacl::string>& application_argv);
      97                 : 
      98                 :   // If subprocess creation fails, both child_process_ and channel_ are set to
      99                 :   // kInvalidHandle. We have different implementations for posix and win.
     100                 :   // You must call InitCommandLine() before calling this function.
     101                 :   bool LaunchFromCommandLine();
     102                 : 
     103                 :   // Builds a command line out of the prepopulated args.
     104                 :   void BuildCommandLine(std::vector<nacl::string>* command);
     105                 : 
     106                 :   // Sets up the command channel |command| and sends the SRPC to load |nexe|.
     107                 :   bool SetupCommandAndLoad(NaClSrpcChannel* command,
     108                 :                            DescWrapper* nexe);
     109                 : 
     110                 :   // Sends the SRPC to start the nexe over |command| and sets up the application
     111                 :   // SRPC chanel |out_app_chan|.
     112                 :   bool StartModuleAndSetupAppChannel(NaClSrpcChannel* command,
     113                 :                                      NaClSrpcChannel* out_app_chan);
     114                 : 
     115                 :   // Add a prefix shell program, like 'time', to run the sel_ldr in
     116                 :   // This is primarily intended to provide a hook for qemu emulation
     117                 :   void SetCommandPrefix(const nacl::string& prefix);
     118                 : 
     119                 :   // Kill the child process.  The channel() remains valid, but nobody
     120                 :   // is talking on the other end.  Returns true if successful.
     121                 :   bool KillChildProcess();
     122                 : 
     123                 :   // User is responsible for invoking channel() and then taking
     124                 :   // ownership of the handle prior to the Dtor firing.
     125                 :   Handle channel() const { return channel_; }
     126                 : 
     127                 :   // Returns the socket address used to connect to the sel_ldr.
     128              10 :   DescWrapper* socket_addr() const { return socket_addr_.get(); }
     129                 : 
     130                 :   // Wraps a raw NaClDesc descriptor.  If NULL is returned, caller retains
     131                 :   // ownership of the reference.
     132                 :   DescWrapper* Wrap(NaClDesc* raw_desc);
     133                 : 
     134                 :   // As above, but raw_desc is Unref'd on failure.
     135                 :   DescWrapper* WrapCleanup(NaClDesc* raw_desc);
     136                 : 
     137                 :   /////////////////////////////////////////////////////////////////////////////
     138                 :   // Start the sel_ldr process.  No nexe information is passed at this point.
     139                 :   // It will be supplied over RPC after start-up.
     140                 :   /////////////////////////////////////////////////////////////////////////////
     141                 : 
     142                 :   bool Start(int socket_count, Handle* result_sockets);
     143                 : 
     144                 :  private:
     145                 :   // OpenSrpcChannels is essentially the following sequence of
     146                 :   // (lower-level) operations.
     147                 : 
     148                 :   // BEGIN EQUIVALENT SEQUENCE
     149                 : 
     150                 :   bool SetupBootstrapChannel();
     151                 :   bool GetLdrSocketAddress();
     152                 :   bool SetupCommandChannel(NaClSrpcChannel* command);
     153                 : 
     154                 :   // LoadModule supplies, via the |command| channel, the |nexe| file
     155                 :   // for the service runtime to load.
     156                 :   bool LoadModule(NaClSrpcChannel* command, DescWrapper* nexe);
     157                 : 
     158                 :   // ----
     159                 : 
     160                 :   // Tell the service runtime to start the NaCl module via the
     161                 :   // |command| channel.  If |error| is non-NULL, any failures will
     162                 :   // cause the error code to be written there.
     163                 :   bool StartModule(NaClSrpcChannel* command, NaClErrorCode* error);
     164                 : 
     165                 :   bool SetupApplicationChannel(NaClSrpcChannel* app_channel);
     166                 : 
     167                 :   // END EQUIVALENT SEQUENCE
     168                 : 
     169                 :   void GetPluginDirectory(char* buffer, size_t len);
     170                 :   nacl::string GetSelLdrPathName();
     171                 :   nacl::string GetSelLdrBootstrapPathName();
     172                 :   void CloseHandlesAfterLaunch();
     173                 : 
     174                 :   Handle child_process_;
     175                 :   Handle channel_;
     176                 :   int channel_number_;  // IMC file descriptor.
     177                 : 
     178                 :   // The following members are used to initialize and build the command line.
     179                 :   // The detailed magic is in BuildCommandLine() but roughly we run
     180                 :   // <prefix> <sel_ldr> <extra stuff> -f <nexe> <sel_ldr_argv> -- <nexe_args>
     181                 :   // Path to prefix tool or empty if not used
     182                 :   nacl::string command_prefix_;
     183                 :   nacl::string sel_ldr_bootstrap_;
     184                 :   // Path to the sel_ldr executable
     185                 :   nacl::string sel_ldr_;
     186                 :   // arguments to sel_ldr
     187                 :   std::vector<nacl::string> sel_ldr_argv_;
     188                 :   // arguments to the nexe
     189                 :   std::vector<nacl::string> application_argv_;
     190                 : 
     191                 :   std::vector<Handle> close_after_launch_;
     192                 : 
     193                 :   // lifetime of bootstrap_socket_ must be at least that of factory_
     194                 :   scoped_ptr<DescWrapperFactory> factory_;
     195                 :   scoped_ptr<DescWrapper> bootstrap_socket_;
     196                 :   // The socket address returned from sel_ldr for connects.
     197                 :   scoped_ptr<DescWrapper> socket_addr_;
     198                 :   scoped_ptr<SelLdrLocator> sel_ldr_locator_;
     199                 : };
     200                 : 
     201                 : }  // namespace nacl
     202                 : 
     203                 : #endif  // NATIVE_CLIENT_SRC_TRUSTED_NONNACL_UTIL_SEL_LDR_LAUNCHER_H_

Generated by: LCOV version 1.7