diff --git a/CMakeLists.txt b/CMakeLists.txt index 7da9be8..5e691bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,7 +50,7 @@ set( sources src/ssh.cpp src/process.cpp src/http_connection.cpp - src/http_server.cpp +# src/http_server.cpp src/json_rpc_connection.cpp src/json_rpc_stream_connection.cpp src/json_rpc_tcp_connection.cpp diff --git a/include/fc/iostream_wrapper.hpp b/include/fc/iostream_wrapper.hpp index ed3affa..a369916 100644 --- a/include/fc/iostream_wrapper.hpp +++ b/include/fc/iostream_wrapper.hpp @@ -64,14 +64,18 @@ namespace fc { virtual ~istream_wrapper(){}; - virtual size_t readsome( char* buf, size_t len ) { return my->readsome(buf,len); } + virtual size_t readsome( char* buf, size_t len ) { + return my->readsome(buf,len); + } virtual istream& read( char* buf, size_t len ) { + // slog( "%p %lld", my.get(), len ); my->read(buf,len); return *this; } virtual void close() { } virtual bool eof()const{ return my->eof(); } + /* virtual istream& read( int64_t& ) { return *this; } virtual istream& read( uint64_t& ) { return *this; } virtual istream& read( int32_t& ) { return *this; } @@ -85,6 +89,7 @@ namespace fc { virtual istream& read( bool& ) { return *this; } virtual istream& read( char& ) { return *this; } virtual istream& read( fc::string& ) { return *this; } + */ protected: struct impl_base : public fc::retainable { diff --git a/include/fc/json_rpc_process_client.hpp b/include/fc/json_rpc_process_client.hpp index 6886a30..d1022e5 100644 --- a/include/fc/json_rpc_process_client.hpp +++ b/include/fc/json_rpc_process_client.hpp @@ -42,6 +42,11 @@ namespace fc { namespace json { void on_close( T&& f) { _con->on_close( fc::forward(f) ); } const fc::json::rpc_stream_connection::ptr& connection()const { return _con; } + + ~rpc_process_client() { + if(_con) + _con->close(); + } private: fc::process _proc; fc::json::rpc_stream_connection::ptr _con; diff --git a/src/context.hpp b/src/context.hpp index 57086fd..fb1cfe4 100644 --- a/src/context.hpp +++ b/src/context.hpp @@ -34,7 +34,6 @@ namespace fc { cur_task(0) { my_context.fc_stack.base = alloc.allocate( bc::default_stacksize() ); - // slog( "new stack %1% bytes at %2%", bc::default_stacksize(), my_context.fc_stack.base ); my_context.fc_stack.limit = static_cast( my_context.fc_stack.base) - bc::default_stacksize(); make_fcontext( &my_context, sf ); diff --git a/src/json.cpp b/src/json.cpp index 2105a97..895d743 100644 --- a/src/json.cpp +++ b/src/json.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include @@ -918,15 +919,18 @@ fc::string pretty_print( fc::vector&& v, uint8_t indent ) { value from_file( const fc::path& local_path ) { if( !exists(local_path) ) { - FC_THROW_MSG( "Source file '%s' does not exist", local_path.string() ); + slog("..."); + FC_THROW_REPORT( "Source file '${filename}' does not exist", value().set("filename",local_path.string()) ); } if( is_directory( local_path ) ) { + wlog("..."); FC_THROW_MSG( "Source path '%s' is a directory, expected a file.", local_path.string() ); } // memory map the file - file_mapping fmap( local_path.string().c_str(), read_only ); size_t fsize = static_cast(file_size(local_path)); + if( fsize == 0 ) { return value(); } + file_mapping fmap( local_path.string().c_str(), read_only ); mapped_region mr( fmap, fc::read_only, 0, fsize ); diff --git a/src/json_rpc_stream_connection.cpp b/src/json_rpc_stream_connection.cpp index f173b82..cacd983 100644 --- a/src/json_rpc_stream_connection.cpp +++ b/src/json_rpc_stream_connection.cpp @@ -28,21 +28,24 @@ namespace fc { namespace json { fc::future _read_loop_complete; void read_loop() { - fc::string line; - fc::getline( in, line ); - while( !in.eof() ) { - try { - fc::value v= fc::json::from_string( line ); - //slog( "%s", fc::json::to_string(v).c_str() ); - self.handle_message(v); - } catch (...) { - wlog( "%s", fc::except_str().c_str() ); - return; - } - fc::getline( in, line ); - } - self.cancel_pending_requests(); - if( !!on_close ) on_close(); + try { + fc::string line; + fc::getline( in, line ); + while( !in.eof() ) { + try { + fc::value v= fc::json::from_string( line ); + self.handle_message(v); + } catch (...) { + wlog( "%s", fc::except_str().c_str() ); + return; + } + fc::getline( in, line ); + } + } catch ( ... ) { + wlog( "%s", fc::except_str().c_str() ); + } + self.cancel_pending_requests(); + if( !!on_close ) on_close(); } }; @@ -80,24 +83,28 @@ namespace fc { namespace json { ss<<"{\"id\":"<out.write( o.c_str(), o.size() ); + my->out.flush(); } void rpc_stream_connection::send_notice( const fc::string& m, value&& param ) { fc::stringstream ss; ss<<"{\"method\":\""<out.write( o.c_str(), o.size() ); + my->out.flush(); } void rpc_stream_connection::send_error( uint64_t id, const json::error_object& eo ) { fc::stringstream ss; ss<<"{\"id\":"<out.write( o.c_str(), o.size() ); + my->out.flush(); } void rpc_stream_connection::send_result( uint64_t id, value&& r ) { fc::stringstream ss; ss<<"{\"id\":"<out.write( o.c_str(), o.size() ); + my->out.flush(); } } } // fc::json diff --git a/src/process.cpp b/src/process.cpp index 3f4d42a..d87ee71 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -43,9 +43,13 @@ namespace fc { try { return static_cast(fc::asio::read_some( *m_pi, boost::asio::buffer( s, static_cast(n) ) )); } catch ( const boost::system::system_error& e ) { + wlog( "%s", fc::except_str().c_str() ); if( e.code() == boost::asio::error::eof ) return -1; throw; + } catch ( ... ) { + wlog( "%s", fc::except_str().c_str() ); + return -1; } } private: @@ -69,9 +73,13 @@ FC_START_SHARED_IMPL( fc::process ) if( inp ) { inp->close(); } - child->terminate(); + if( _exited.valid() && !_exited.ready()) { + slog( "terminate..."); + child->terminate(); + _exited.wait(); + } }catch(...) { - wlog( "caught exception cleaning up process" ); + wlog( "caught exception cleaning up process: %s", fc::except_str().c_str() ); } } @@ -88,6 +96,8 @@ FC_START_SHARED_IMPL( fc::process ) io::stream std_err; io::stream std_in; + fc::future _exited; + // adapt to ostream and istream interfaces fc::ostream_wrapper _ins; fc::istream_wrapper _outs; @@ -163,8 +173,7 @@ fc::future process::exec( const fc::path& exe, fc::vector&& arg } else p->set_exception( fc::copy_exception( boost::system::system_error(ec) ) ); }); - return p; - + return my->_exited = p; } /**