예제 #1
0
파일: path.cpp 프로젝트: yesoce/appleseed
void split_paths(
    const filesystem::path&     p1,
    const filesystem::path&     p2,
    filesystem::path&           common,
    filesystem::path&           r1,
    filesystem::path&           r2)
{
    assert(common.empty());
    assert(r1.empty());
    assert(r2.empty());

    filesystem::path::const_iterator i1 = p1.begin();
    filesystem::path::const_iterator i2 = p2.begin();

    while (i1 != p1.end() && i2 != p2.end())
    {
        if (*i1 != *i2)
            break;

        if ((p1.has_filename() && succ(i1) == p1.end()) ||
            (p2.has_filename() && succ(i2) == p2.end()))
            break;

        common /= *i1;

        ++i1, ++i2;
    }

    while (i1 != p1.end())
        r1 /= *i1++;

    while (i2 != p2.end())
        r2 /= *i2++;
}
예제 #2
0
fs::path mpw_path() {

	static fs::path path;

	if (path.empty()) {
		std::error_code ec;
		const char *cp = getenv("PATH");
		if (!cp) cp = _PATH_DEFPATH;
		std::string s(cp);
		string_splitter ss(s, ':');
		for (; ss; ++ss) {
			if (ss->empty()) continue;
			fs::path p(*ss);
			p /= "mpw";

			if (fs::is_regular_file(p, ec)) {
				path = std::move(p);
				break;
			}
		}
		//also check /usr/local/bin
		if (path.empty()) {
			fs::path p = "/usr/local/bin/mpw";
			if (fs::is_regular_file(p, ec)) {
				path = std::move(p);
			}
		}

		if (path.empty()) {
			fs::path p = root() / "bin/mpw";
			if (fs::is_regular_file(p, ec)) {
				path = std::move(p);
			}
		}

		if (path.empty()) {
			fprintf(stderr, "Unable to find mpw executable\n");
			fprintf(stderr, "PATH = %s\n", s.c_str());
			path = "mpw";
		}
	}

	return path;
}
예제 #3
0
promise< std::pair< std::int64_t, int > >
process::create( const filesystem::path &exe, const std::vector< std::string > &args, const env_t &env, const filesystem::path &working_directory, pid_t &pid, input_f stdin_handler, output_f stdout_handler, output_f stderr_handler )
{
	auto context	= std::unique_ptr< process_s, std::function< void ( process_s* )> >( new process_s(), []( auto handle )
	{
		uv_close( reinterpret_cast< uv_handle_t* >( handle ), []( auto handle )
		{
			auto context = reinterpret_cast< process_s* >( handle );
			delete context;
		} );
	} );
#if defined( WIN32 )
	auto env_vec	= std::vector< std::string >();
#endif
	auto c_args		= std::vector< const char* >();
	auto c_env		= std::vector< const char* >();
	auto ret		= promise< std::pair< std::int64_t, int > >();
	
	context->stdin_handler	= stdin_handler;
	context->stdout_handler	= stdout_handler;
	context->stderr_handler	= stderr_handler;
	context->ret			= ret;
	
	c_args.push_back( exe.c_str() );
	
	for ( auto &arg : args )
	{
		c_args.push_back( arg.c_str() );
	}
	
	c_args.push_back( nullptr );
	
	context->options.file		= exe.c_str();
	context->options.args		= const_cast< char** >( c_args.data() );

#if defined( WIN32 )
	context->options.flags		= UV_PROCESS_DETACHED;
#endif
	
	if ( !env.empty() )
	{
#if defined( WIN32 )
#	undef GetEnvironmentStrings

		auto strings	= GetEnvironmentStrings();
		auto prev		= 0;

		for ( auto i = 0; ; i++ )
		{
			if ( strings[ i ] == '\0' )
			{
				env_vec.emplace_back( strings + prev, strings + i );
				prev = i;

				if ( strings[ i + 1 ] == '\0' )
				{
					break;
				}
			}
		}

		FreeEnvironmentStringsA( strings );

		for ( auto &string : env_vec )
		{
			c_env.push_back( string.c_str() );
		}

#else
		for ( int i = 0; environ[ i ] != nullptr; i++ )
		{
			c_env.push_back( environ[ i ] );
		}
#endif
		
		for ( auto it = env.begin(); it != env.end(); it++ )
		{
			c_env.push_back( it->c_str() );
		}

		c_env.push_back( nullptr );
		
		context->options.env = const_cast< char** >( c_env.data() );
	}
	
	if ( !working_directory.empty() )
	{
		context->options.cwd	= working_directory.c_str();
	}
	
	context->options.exit_cb	= exit_cb;

	auto err = uv_spawn( uv_default_loop(), context.get(), &context->options );
	ncheck_error_action( err == 0, ret.reject( std::error_code( err, libuv::error_category() ) ), exit );
	
	if ( stdin_handler )
	{
		auto str = stdin_handler();
		auto buf = uv_buf_init( const_cast< char* >( str.data() ), str.size() );
		auto req = new uv_write_t;
		auto err = std::error_code( uv_write( req, reinterpret_cast< uv_stream_t* >( context->in ), &buf, 1, on_write ), libuv::error_category() );
	}
	
	err = uv_read_start( reinterpret_cast< uv_stream_t* >( context->out ), on_alloc_stdout, on_read_stdout );
	ncheck_error_action( err == 0, ret.reject( std::error_code( err, libuv::error_category() ) ), exit );
	
	err = uv_read_start( reinterpret_cast< uv_stream_t* >( context->err ), on_alloc_stderr, on_read_stderr );
	ncheck_error_action( err == 0, ret.reject( std::error_code( err, libuv::error_category() ) ), exit );

	pid = context->pid;
	
	context.release();
	
exit:

	return ret;
}