コード例 #1
0
            fc::variants parse_recognized_interactive_command( fc::buffered_istream& argument_stream,
                                                               const rpc_server::method_data& method_data)
            {
              fc::variants arguments;
              for (unsigned i = 0; i < method_data.parameters.size(); ++i)
              {
                try
                {
                  arguments.push_back(_self->parse_argument_of_known_type(argument_stream, method_data, i));
                }
                catch( const fc::eof_exception& e )
                {
                  if (method_data.parameters[i].classification != rpc_server::required_positional)
                    return arguments;
                  else
                    FC_THROW("Missing argument ${argument_number} of command \"${command}\"",
                             ("argument_number", i + 1)("command", method_data.name)("cause",e.to_detail_string()) );
                }
                catch( fc::parse_error_exception& e )
                {
                  FC_RETHROW_EXCEPTION(e, error, "Error parsing argument ${argument_number} of command \"${command}\": ${detail}",
                                        ("argument_number", i + 1)("command", method_data.name)("detail", e.get_log()));
                }

                if (method_data.parameters[i].classification == rpc_server::optional_named)
                  break;
              }
              return arguments;
            }
コード例 #2
0
ファイル: process.cpp プロジェクト: techsharesteam/techshares
   void detail::process_impl::exec(const fc::path& exe, vector<string> args, 
                                   const fc::path& work_dir /* = fc::path() */, 
                                   fc::iprocess::exec_opts opts /* = open_all */) { 
        chan = sshc->my->open_channel(""); 

        sshc->my->call_ssh2_function(boost::bind(libssh2_channel_handle_extended_data2, chan, LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL));

        try {
          fc::scoped_lock<fc::mutex> process_startup_lock(sshc->my->process_startup_mutex);
          fc::string command_line = sshc->my->remote_system_is_windows ? windows_shell_escape_command(exe, args) : unix_shell_escape_command(exe, args);
          sshc->my->call_ssh2_function_throw(boost::bind(libssh2_channel_process_startup, chan, "exec", sizeof("exec") - 1, command_line.c_str(), command_line.size()),
					    "exec failed: ${message}"); // equiv to libssh2_channel_exec(chan, cmd) macro
        } catch (fc::exception& er) {
           elog( "error starting process" );
           FC_RETHROW_EXCEPTION(er, error, "error starting process");
        }
   }
コード例 #3
0
 // Parse the given line into a command and arguments, returning them in the form our 
 // json-rpc server functions require them.
 void parse_json_command(const std::string& line_to_parse, std::string& command, fc::variants& arguments)
 {
   // the first whitespace-separated token on the line should be an un-quoted 
   // JSON-RPC command name
   command.clear();
   arguments.clear();
   std::string::const_iterator iter = std::find_if(line_to_parse.begin(), line_to_parse.end(), ::isspace);
   if (iter != line_to_parse.end())
   {
     // then there are arguments to this function
     size_t first_space_pos = iter - line_to_parse.begin();
     command = line_to_parse.substr(0, first_space_pos);
     fc::istream_ptr argument_stream = std::make_shared<fc::stringstream>((line_to_parse.substr(first_space_pos + 1)));
     fc::buffered_istream buffered_argument_stream(argument_stream);
     while (1)
     {
       try
       {
         arguments.emplace_back(fc::json::from_stream(buffered_argument_stream));
       }
       catch (fc::eof_exception&)
       {
         break;
       }
       catch (fc::parse_error_exception& e)
       {
         FC_RETHROW_EXCEPTION(e, error, "Error parsing argument ${argument_number} of command \"${command}\": ${detail}",
                              ("argument_number", arguments.size() + 1)("command", command)("detail", e.get_log()));
       }
     }
   }
   else
   {
     // no arguments
     command = line_to_parse;
   }
 }
コード例 #4
0
    void message_oriented_connection_impl::read_loop()
    {
      const int BUFFER_SIZE = 16;
      const int LEFTOVER = BUFFER_SIZE - sizeof(message_header);
      assert(BUFFER_SIZE >= sizeof(message_header));

      _connected_time = fc::time_point::now();
      try 
      {
        message m;
        while( true )
        {
          char buffer[BUFFER_SIZE];
          _sock.read(buffer, BUFFER_SIZE);
          _bytes_received += BUFFER_SIZE;
          memcpy((char*)&m, buffer, sizeof(message_header));

          assert( m.size <= MAX_MESSAGE_SIZE );

          size_t remaining_bytes_with_padding = 16 * ((m.size - LEFTOVER + 15) / 16);
          m.data.resize(LEFTOVER + remaining_bytes_with_padding); //give extra 16 bytes to allow for padding added in send call
          std::copy(buffer + sizeof(message_header), buffer + sizeof(buffer), m.data.begin());
          if (remaining_bytes_with_padding)
          {
            _sock.read(&m.data[LEFTOVER], remaining_bytes_with_padding);
            _bytes_received += remaining_bytes_with_padding;
          }
          m.data.resize(m.size); // truncate off the padding bytes

          _last_message_received_time = fc::time_point::now();

          try 
          {
            // message handling errors are warnings...
            _delegate->on_message(_self, m);
          } 
          /// Dedicated catches needed to distinguish from general fc::exception
          catch ( fc::canceled_exception& e ) { throw e; }
          catch ( fc::eof_exception& e ) { throw e; }
          catch ( fc::exception& e ) 
          { 
            /// Here loop should be continued so exception should be just caught locally.
            wlog( "message transmission failed ${er}", ("er", e.to_detail_string() ) );
          }
        }
      } 
      catch ( const fc::canceled_exception& e )
      {
        wlog( "disconnected ${e}", ("e", e.to_detail_string() ) );
        _delegate->on_connection_closed(_self);
      }
      catch ( const fc::eof_exception& e )
      {
        wlog( "disconnected ${e}", ("e", e.to_detail_string() ) );
        _delegate->on_connection_closed(_self);
      }
      catch ( fc::exception& e )
      {
        elog( "disconnected ${er}", ("er", e.to_detail_string() ) );
        _delegate->on_connection_closed(_self);

        FC_RETHROW_EXCEPTION( e, warn, "disconnected ${e}", ("e", e.to_detail_string() ) );
      }
      catch ( ... )
      {
        _delegate->on_connection_closed(_self);
        FC_THROW_EXCEPTION( fc::unhandled_exception, "disconnected: {e}", ("e", fc::except_str() ) );
      }
    }
コード例 #5
0
ファイル: connection.cpp プロジェクト: NimroDeer/BitShares
          void read_loop()
          {
            const int BUFFER_SIZE = 16;
            const int LEFTOVER = BUFFER_SIZE - sizeof(message_header);
            try {
               message m;
               while( !_read_loop_complete.canceled() )
               {
                  char tmp[BUFFER_SIZE];
                  sock->read( tmp, BUFFER_SIZE );
                  memcpy( (char*)&m, tmp, sizeof(message_header) );
                  m.data.resize( m.size + 16 ); //give extra 16 bytes to allow for padding added in send call
                  memcpy( (char*)m.data.data(), tmp + sizeof(message_header), LEFTOVER );
                  sock->read( m.data.data() + LEFTOVER, 16*((m.size -LEFTOVER + 15)/16) );
                  m.data.resize(m.size);

                  try { // message handling errors are warnings... 
                    con_del->on_connection_message( self, m );
                  } 
                  catch ( fc::canceled_exception& e ) { wlog(".");throw; }
                  catch ( fc::eof_exception& e ) { wlog(".");throw; }
                  catch ( fc::exception& e ) 
                  { 
                     wlog( "disconnected ${er}", ("er", e.to_detail_string() ) );
                     return;
                     // TODO: log and potentiall disconnect... for now just warn.
                  }
                  catch( ... )
                  {
                     wlog("...????" );
                     return;
                  }
               }
            } 
            catch ( const fc::canceled_exception& e )
            {
              if( con_del )
              {
                 con_del->on_connection_disconnected( self );
              }
              else
              {
                wlog( "disconnected ${e}", ("e", e.to_detail_string() ) );
              }
              wlog( "exit read loop" );
              return;
            }
            catch ( const fc::eof_exception& e )
            {
              if( con_del )
              {
                 ilog( ".");
                 fc::async( [=](){con_del->on_connection_disconnected( self );} );
                 ilog( ".");
              }
              else
              {
                wlog( "disconnected ${e}", ("e", e.to_detail_string() ) );
              }
            }
            catch ( fc::exception& er )
            {
               wlog( ".." );
              if( con_del )
              {
                elog( "disconnected ${er}", ("er", er.to_detail_string() ) );
                //con_del->on_connection_disconnected( self );
                fc::async( [=](){con_del->on_connection_disconnected( self );} );
              }
              else
              {
                elog( "disconnected ${e}", ("e", er.to_detail_string() ) );
              }
              FC_RETHROW_EXCEPTION( er, warn, "disconnected ${e}", ("e", er.to_detail_string() ) );
            }
            catch ( ... )
            {
               wlog( "unhandled??" );
              // TODO: call con_del->????
              FC_THROW_EXCEPTION( unhandled_exception, "disconnected: {e}", ("e", fc::except_str() ) );
            }
          }
コード例 #6
0
ファイル: gntp.cpp プロジェクト: BestSilent/eos
    void gntp_notifier_impl::send_gntp_message(const std::string& message)
    {
      std::shared_ptr<boost::asio::ip::tcp::socket> sock(new boost::asio::ip::tcp::socket(asio::default_io_service()));

      bool connected = false;
      if (endpoint)
      {
        // we've successfully connected before, connect to the same endpoint that worked last time
        try
        {
          asio::tcp::connect(*sock, *endpoint);
          connected = true;
        }
        catch (exception& er)
        {
          ilog("Failed to connect to GNTP service using an endpoint that previously worked: ${error_report}", 
              ("error_report", er.to_detail_string()));
          sock->close();
          // clear the cached endpoint and fall through to the full connection procedure
          endpoint = optional<boost::asio::ip::tcp::endpoint>();
        }
        catch (...)
        {
          ilog("Failed to connect to GNTP service using an endpoint that previously worked");
          sock->close();
          // clear the cached endpoint and fall through to the full connection procedure
          endpoint = optional<boost::asio::ip::tcp::endpoint>();
        }
      }
      if (!connected)
      {
        // do the full connection procedure
        auto eps = asio::tcp::resolve(hostname, boost::lexical_cast<std::string>(port));
        if (eps.size() == 0)
          FC_THROW("Unable to resolve host '${host}'", ("host", hostname));

        for (uint32_t i = 0; i < eps.size(); ++i)
        {
          try 
          {
            boost::system::error_code ec;
            ilog("Attempting to connect to GNTP srvice");
            asio::tcp::connect(*sock, eps[i]);
            endpoint = eps[i];
            connected = true;
            break;
          }
          catch (const exception& er) 
          {
            ilog("Failed to connect to GNTP service: ${error_reprot}", 
                  ("error_report", er.to_detail_string()) );
            sock->close();
          }
          catch (...)
          {
            ilog("Failed to connect to GNTP service");
            sock->close();
          }
        }
      }
      if (!connected)
        FC_THROW("Unable to connect to any resolved endpoint for ${host}:${port}", 
                  ("host", hostname)("port", port));
      try
      {
        asio::ostream<boost::asio::ip::tcp::socket> write_stream(sock);
        write_stream.write(message.c_str(), message.size());
        write_stream.flush();
        write_stream.close();
      }
      catch (exception& er)
      {
        FC_RETHROW_EXCEPTION(er, warn, "Caught an exception while sending data to GNTP service");
      }
      catch (...)
      {
        FC_THROW("Caught an exception while sending data to GNTP service");
      }
    }
コード例 #7
0
ファイル: mutex.cpp プロジェクト: dbrock/bitshares-fc
void mutex::lock() {
    fc::context* current_context = fc::thread::current().my->current;
    if( !current_context )
        current_context = fc::thread::current().my->current = new fc::context( &fc::thread::current() );

    {
        fc::unique_lock<fc::spin_yield_lock> lock(m_blist_lock);
        if( !m_blist )
        {
            // nobody else owns the mutex, so we get it; add our context as the last and only element on the mutex's list
            m_blist = current_context;
            assert(!current_context->next_blocked_mutex);
            return;
        }

        // allow recusive locks
        fc::context* dummy_context_to_unblock  = 0;
        if ( get_tail( m_blist, dummy_context_to_unblock ) == current_context ) {
            // if we already have the lock (meaning we're on the tail of the list) then
            // we shouldn't be trying to grab the lock again
            assert(false);
            // EMF: I think recursive locks are currently broken -- we need to
            // keep track of how many times this mutex has been locked by the
            // current context.  Unlocking should decrement this count and unblock
            // the next context only if the count drops to zero
            return;
        }
        // add ourselves to the head of the list
        current_context->next_blocked_mutex = m_blist;
        m_blist = current_context;

#if 0
        int cnt = 0;
        auto i = m_blist;
        while( i ) {
            i = i->next_blocked_mutex;
            ++cnt;
        }
        //wlog( "wait queue len %1%", cnt );
#endif
    }

    try
    {
        fc::thread::current().yield(false);
        // if yield() returned normally, we should now own the lock (we should be at the tail of the list)
        BOOST_ASSERT( current_context->next_blocked_mutex == 0 );
    }
    catch ( exception& e )
    {
        wlog( "lock threw: ${e}", ("e", e));
        cleanup( *this, m_blist_lock, m_blist, current_context);
        FC_RETHROW_EXCEPTION(e, warn, "lock threw: ${e}", ("e", e));
    }
    catch ( ... )
    {
        wlog( "lock threw unexpected exception" );
        cleanup( *this, m_blist_lock, m_blist, current_context);
        throw;
    }
}
コード例 #8
0
            fc::variant parse_argument_of_known_type( fc::buffered_istream& argument_stream,
                                                      const rpc_server::method_data& method_data,
                                                      unsigned parameter_index)
            {
              const rpc_server::parameter_data& this_parameter = method_data.parameters[parameter_index];
              if (this_parameter.type == "asset")
              {
                // for now, accept plain int, assume it's always in the base asset
                uint64_t amount_as_int;
                try
                {
                  fc::variant amount_as_variant = fc::json::from_stream(argument_stream);
                  amount_as_int = amount_as_variant.as_uint64();
                }
                catch( fc::bad_cast_exception& e )
                {
                  FC_RETHROW_EXCEPTION(e, error, "Error parsing argument ${argument_number} of command \"${command}\": ${detail}",
                                        ("argument_number", parameter_index + 1)("command", method_data.name)("detail", e.get_log()));
                }
                catch( fc::parse_error_exception& e )
                {
                  FC_RETHROW_EXCEPTION(e, error, "Error parsing argument ${argument_number} of command \"${command}\": ${detail}",
                                        ("argument_number", parameter_index + 1)("command", method_data.name)("detail", e.get_log()));
                }
                return fc::variant(bts::blockchain::asset(amount_as_int));
              }
              else if (this_parameter.type == "address")
              {
                // allow addresses to be un-quoted
                while( isspace(argument_stream.peek()) )
                  argument_stream.get();
                fc::stringstream address_stream;
                try
                {
                  while( !isspace(argument_stream.peek()) )
                    address_stream.put(argument_stream.get());
                }
                catch( const fc::eof_exception& )
                {
                   // expected and ignored
                }
                std::string address_string = address_stream.str();

                try
                {
                  bts::blockchain::address::is_valid(address_string);
                }
                catch( fc::exception& e )
                {
                  FC_RETHROW_EXCEPTION(e, error, "Error parsing argument ${argument_number} of command \"${command}\": ${detail}",
                                        ("argument_number", parameter_index + 1)("command", method_data.name)("detail", e.get_log()));
                }
                return fc::variant( bts::blockchain::address(address_string) );
              }
              else
              {
                // assume it's raw JSON
                try
                {
                  return fc::json::from_stream( argument_stream );
                }
                catch( fc::parse_error_exception& e )
                {
                  FC_RETHROW_EXCEPTION(e, error, "Error parsing argument ${argument_number} of command \"${command}\": ${detail}",
                                        ("argument_number", parameter_index + 1)("command", method_data.name)("detail", e.get_log()));
                }
              }
            }