LCOV - code coverage report
Current view: directory - src/trusted/nonnacl_util/posix - sel_ldr_launcher_posix.cc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 58 11 19.0 %
Date: 2014-06-18 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2012 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                 : #include <sys/types.h>
       9                 : #include <sys/wait.h>
      10                 : 
      11                 : #include <assert.h>
      12                 : #include <fcntl.h>
      13                 : #include <libgen.h>
      14                 : #include <signal.h>
      15                 : #include <stdio.h>
      16                 : #include <string.h>
      17                 : #include <sys/param.h>
      18                 : #include <unistd.h>
      19                 : 
      20                 : #include "native_client/src/include/nacl_macros.h"
      21                 : #include "native_client/src/include/nacl_string.h"
      22                 : #include "native_client/src/shared/platform/nacl_check.h"
      23                 : #include "native_client/src/shared/platform/nacl_exit.h"
      24                 : #include "native_client/src/shared/platform/nacl_log.h"
      25                 : #include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h"
      26                 : #include "native_client/src/trusted/desc/nacl_desc_base.h"
      27                 : 
      28                 : 
      29                 : using std::vector;
      30                 : 
      31                 : namespace nacl {
      32                 : 
      33              13 : SelLdrLauncherStandalone::~SelLdrLauncherStandalone() {
      34              13 :   CloseHandlesAfterLaunch();
      35              13 :   if (NACL_INVALID_HANDLE != child_process_) {
      36              13 :     int status;
      37                 :     // Ensure child process (service runtime) is kaput.  NB: we might
      38                 :     // close the command channel (or use the hard_shutdown RPC) rather
      39                 :     // than killing the process to allow the service runtime to do
      40                 :     // clean up, but the plugin should be responsible for that and we
      41                 :     // shouldn't introduce any timeout wait in a dtor.  Currently,
      42                 :     // ServiceRuntime::Shutdown kills the subprocess before closing
      43                 :     // the command channel, so we aren't providing the opportunity for
      44                 :     // a more graceful shutdown.
      45              13 :     KillChildProcess();
      46              13 :     waitpid(child_process_, &status, 0);
      47              13 :   }
      48             104 : }
      49                 : 
      50                 : 
      51                 : nacl::string SelLdrLauncherStandalone::GetSelLdrPathName() {
      52               0 :   char buffer[FILENAME_MAX];
      53               0 :   GetPluginDirectory(buffer, sizeof(buffer));
      54               0 :   return nacl::string(buffer) + "/sel_ldr";
      55               0 : }
      56                 : 
      57                 : nacl::string SelLdrLauncherStandalone::GetSelLdrBootstrapPathName() {
      58                 : #if NACL_LINUX
      59                 :   char buffer[FILENAME_MAX];
      60                 :   GetPluginDirectory(buffer, sizeof(buffer));
      61                 :   return nacl::string(buffer) + "/nacl_helper_bootstrap";
      62                 : #else
      63               0 :   return nacl::string(NACL_NO_FILE_PATH);
      64                 : #endif
      65               0 : }
      66                 : 
      67                 : NaClHandle SelLdrLauncherStandalone::CreateBootstrapSocket(
      68               0 :     nacl::string* dest_fd) {
      69               0 :   NaClHandle pair[2];
      70               0 :   if (NaClSocketPair(pair) == -1) {
      71               0 :     return NACL_INVALID_HANDLE;
      72                 :   }
      73                 : 
      74               0 :   int rc = fcntl(pair[0], F_SETFD, FD_CLOEXEC);
      75               0 :   CHECK(rc == 0);
      76               0 :   close_after_launch_.push_back(pair[1]);
      77                 : 
      78               0 :   *dest_fd = ToString(pair[1]);
      79               0 :   return pair[0];
      80               0 : }
      81                 : 
      82                 : const size_t kMaxExecArgs = 64;
      83                 : 
      84                 : bool SelLdrLauncherStandalone::StartViaCommandLine(
      85               0 :     const vector<nacl::string>& prefix,
      86               0 :     const vector<nacl::string>& sel_ldr_argv,
      87               0 :     const vector<nacl::string>& app_argv) {
      88                 :   // Set up the command line.
      89               0 :   InitCommandLine(prefix, sel_ldr_argv, app_argv);
      90                 :   // complete command line setup
      91               0 :   vector<nacl::string> command;
      92               0 :   BuildCommandLine(&command);
      93               0 :   if (kMaxExecArgs <= command.size()) {
      94                 :     // TODO(robertm): emit error message
      95               0 :     return false;
      96                 :   }
      97                 :   // Set environment variable to keep the Mac sel_ldr from stealing the focus.
      98                 :   // TODO(sehr): change this to use a command line parameter rather than env.
      99               0 :   setenv("NACL_LAUNCHED_FROM_BROWSER", "1", 0);
     100                 :   // Fork the sel_ldr process.
     101               0 :   child_process_ = fork();
     102               0 :   if (child_process_ == -1) {
     103               0 :     return false;
     104                 :   }
     105                 : 
     106               0 :   if (child_process_ == 0) {
     107                 :     // convert vector -> array assuming no more than kMaxArgs
     108                 :     // NOTE: we also check this above so the assert should never fire
     109               0 :     assert(command.size() < kMaxExecArgs);
     110               0 :     const char* argv[kMaxExecArgs];
     111               0 :     for (size_t i = 0; i < command.size(); ++i) {
     112               0 :       argv[i] = command[i].c_str();
     113               0 :     }
     114               0 :     argv[command.size()] = NULL;
     115                 : 
     116               0 :     execv(argv[0], const_cast<char**>(argv));
     117               0 :     NaClLog(LOG_ERROR, "execv failed, args were:\n");
     118               0 :     for (size_t i = 0; i < command.size(); ++i) {
     119               0 :       NaClLog(LOG_ERROR, "%s\n", argv[i]);
     120               0 :     }
     121               0 :     perror("execv");
     122               0 :     NaClExit(EXIT_FAILURE);
     123               0 :   }
     124               0 :   CloseHandlesAfterLaunch();
     125               0 :   return true;
     126               0 : }
     127                 : 
     128                 : bool SelLdrLauncherStandalone::KillChildProcess() {
     129              13 :   if (NACL_INVALID_HANDLE == child_process_) {
     130                 :     // It is incorrect to use the kill syscall on NACL_INVALID_HANDLE
     131                 :     // as the pid, since using -1 as pid is defined by POSIX.1-2001 to
     132                 :     // send the signal (SIGKILL) to every process that the calling
     133                 :     // process may send signals to (except for init), which is
     134                 :     // Definitely Not What Was Intended for this.
     135               0 :     return true;
     136                 :   }
     137              13 :   return 0 == kill(child_process_, SIGKILL);
     138                 :   // We cannot set child_process_ to NACL_INVALID_HANDLE since we will
     139                 :   // want to wait on its exit status.
     140              13 : }
     141                 : 
     142                 : }  // namespace nacl

Generated by: LCOV version 1.7