Beispiel #1
0
Directory::Directory(const std::string path)
    : path_(path)
{
    dir_ = opendir(path.c_str());
    if (!dir_)
    {
        THROW_SYSTEM_ERROR();
    }
}
Beispiel #2
0
File::File(const std::string path, const std::string name)
    : path_(path)
    , name_(name)
{
    fd_ = open(path.c_str(), O_RDONLY);
    if (fd_ == -1) {
        fd_ = -errno;
        int ret = stat(path.c_str(), &stat_);
        if (ret == -1)
        {
            THROW_SYSTEM_ERROR();
        }
    } else {
        int ret = fstat(fd_, &stat_);
        if (ret == -1)
        {
            THROW_SYSTEM_ERROR();
        }
    }
}
Beispiel #3
0
void graphic_device::create_depth_stencil() {
    ASSERT(m_device);

    // 深度・ステンシル バッファの構築.
    const DXGI_FORMAT buffer_format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    const CD3D11_TEXTURE2D_DESC desc_buffer(
        buffer_format,
        m_screen_width, m_screen_height,
        1, 0, D3D11_BIND_DEPTH_STENCIL);

    const auto hr_buf = m_device->CreateTexture2D(
        &desc_buffer, nullptr, m_depth_stencil_buffer.GetAddressOf());

    if (FAILED(hr_buf)) {
        THROW_SYSTEM_ERROR("Can't create depth/stencil buffer.");
    }

    // 深度・ステンシル ビューの構築.
    const CD3D11_DEPTH_STENCIL_VIEW_DESC desc_view(
        D3D11_DSV_DIMENSION_TEXTURE2D, buffer_format);

    const auto hr_view = m_device->CreateDepthStencilView(
        reinterpret_cast<ID3D11Resource*>(m_depth_stencil_buffer.Get()),
        &desc_view, m_depth_stencil_view.GetAddressOf());

    if (FAILED(hr_view)) {
        THROW_SYSTEM_ERROR("Can't create depth/stencil view.");
    }

    // 深度・ステンシルステートの構築.
    const CD3D11_DEPTH_STENCIL_DESC desc_state(std::move(CD3D11_DEFAULT()));
    const auto hr_state = m_device->CreateDepthStencilState(
        &desc_state, m_depth_stencil_state.GetAddressOf());

    if (FAILED(hr_state)) {
        THROW_SYSTEM_ERROR("Can't create depth/stencil state.");
    }
}
Beispiel #4
0
void graphic_device::create_render_target() {
    ASSERT(m_device);
    ASSERT(m_swap_chain);

    // バックバッファの取得.
    d3d_ptr<ID3D11Texture2D> back_buffer;
    const auto hr_buf = m_swap_chain->GetBuffer(
        0, __uuidof(ID3D11Texture2D),
        reinterpret_cast<void**>(back_buffer.GetAddressOf()));

    if (FAILED(hr_buf)) {
        THROW_SYSTEM_ERROR("Can't get backbuffer from swap-chain.");
    }

    // 描画ターゲットの作成.
    //   バックバッファの全てのサブリソースにアクセス可能.
    const auto hr_view = m_device->CreateRenderTargetView(
        back_buffer.Get(), nullptr, m_render_target_view.GetAddressOf());

    if (FAILED(hr_view)) {
        THROW_SYSTEM_ERROR("Can't create render-targe from backbuffer.");
    }
}
Beispiel #5
0
void Poll::dispatch()
{
	auto events = UNIQ_MEM_PTR(struct epoll_event, kMaxEvents, free);

	while (1)
	{
		int nfds = epoll_wait(fd_, events.get(), kMaxEvents, -1);

		if (nfds == -1 && errno != EINTR)
		{
			THROW_SYSTEM_ERROR();
		}

		for (int i = 0; i < nfds; ++i)
		{
			int fd = events.get()[i].data.fd;

			{
				//TODO: may be we don't need to lock the whole block
				std::unique_lock<std::mutex> lock(mutex_);

				if (handlers_.count(fd) == 0)
					continue;

				SocketPtr socket = std::get<0>(handlers_[fd]);
				PollHandler handler = std::get<1>(handlers_[fd]);

				if (events.get()[i].events & EPOLLIN)
				{
					if (handler(socket, EventType::IN) < 0)
					{
						handlers_.erase(fd);
						continue;
					}
				}
				if (events.get()[i].events & EPOLLOUT)
				{
					if (handler(socket, EventType::OUT) < 0)
					{
						handlers_.erase(fd);
						continue;
					}
				}
			}
		}
	}

}
Beispiel #6
0
void graphic_device::create_device_and_swap(HWND window_handle) {
    ASSERT(!m_swap_chain);
    ASSERT(!m_device);
    ASSERT(!m_immediate_context);

    // スワップチェインの設定.
    //   バックバッファを1つ用意する.
    DXGI_SWAP_CHAIN_DESC desc;
    ZeroMemory(&desc, sizeof(desc));
    desc.BufferCount                        = 1;
    desc.BufferDesc.Width                   = m_screen_width;
    desc.BufferDesc.Height                  = m_screen_height;
    desc.BufferDesc.Format                  = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
    desc.BufferDesc.RefreshRate.Numerator   = 60;
    desc.BufferDesc.RefreshRate.Denominator = 1;
    desc.BufferUsage                        = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    desc.Flags                              = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
    desc.OutputWindow                       = window_handle;
    desc.SampleDesc.Count                   = 1;
    desc.SampleDesc.Quality                 = 0;
    desc.SwapEffect                         = DXGI_SWAP_EFFECT_DISCARD;
    desc.Windowed                           = TRUE;

    // デバイスとスワップチェインを同時作成.
    //   動作種別ごとに作成を試み、最初に成功したデバイスを利用.
    HRESULT hr = S_FALSE;
    for (UINT driver_idx = 0; driver_idx < num_driver_types; ++driver_idx) {
        m_driver_type = expect_driver_types[driver_idx];

        hr = ::D3D11CreateDeviceAndSwapChain(
            //in
            nullptr, m_driver_type,
            nullptr, flags_for_create_device,
            expect_feature_levels, num_feature_levels,
            D3D11_SDK_VERSION, &desc,
            // out
            m_swap_chain.GetAddressOf(), m_device.GetAddressOf(),
            &m_feature_level, m_immediate_context.GetAddressOf());

        if (SUCCEEDED(hr)) { break; }
    }

    if (FAILED(hr)) {
        THROW_SYSTEM_ERROR("Can't create device and swapchain.");
    }
}
Beispiel #7
0
void Poll::addFD(SocketPtr sock, PollHandler handler)
{
	static struct epoll_event ev;

	{
		std::unique_lock<std::mutex> lock(mutex_);
		handlers_[sock->native()] = std::make_tuple(sock, handler);
	}

	ev.events = /*EPOLLET |*/ EPOLLIN | EPOLLOUT;
	ev.data.fd = sock->native();

	int ret = epoll_ctl(fd_, EPOLL_CTL_ADD, sock->native(), &ev);
	if (ret != 0)
	{
		THROW_SYSTEM_ERROR();
	}
}
Beispiel #8
0
FilePtr Directory::nextFile()
{
    struct dirent *epdf;

    errno = 0;
    epdf = readdir(dir_);
    if (epdf == NULL)
    {
        if (errno) {
            THROW_SYSTEM_ERROR();
        }
        return FilePtr();
    }

    FilePtr file = std::make_shared<File>(
                       std::string(path_ + epdf->d_name).c_str(), epdf->d_name);

    return file;
}
Beispiel #9
0
string exec_command( const string& str )
{
  // Construct this before any resources are claimed
  string result; 

  const char *argv[4]; // No ownership of memory

  // Respect the SHELL environment variable,
  // and drop back to using /bin/sh
  argv[0] = getenv("SHELL");
  if ( !argv[0] || !*argv[0] ) 
    argv[0] = "/bin/sh";

  argv[1] = "-c";
  argv[2] = str.c_str();
  argv[3] = NULL;

  // -------
  // From now on we have to be careful about exceptions
  // as we have pipes and child processes hanging around
  //
  int pipedes[2];

  if (pipe(pipedes) == -1 )
    THROW_SYSTEM_ERROR( "pipe" );
 
  int pid = vfork();

  if ( pid == 0 ) {
    close( pipedes[0] ); // reading end

    // Make the writing end of the pipe the new stdout (fd 1) 
    // for the  child process.
    dup2( pipedes[1], 1 );
    close( pipedes[1] );

    // Semantically this is a char const* const*, but POSIX
    // seems to disagree...
    execvp( argv[0], const_cast<char* const*>( argv ) );
    _exit( 127 ); // Can't happen
  }
  else if ( pid == -1 ) {
    close( pipedes[0] );
    close( pipedes[1] );
    THROW_SYSTEM_ERROR( "vfork" );
  }

  close( pipedes[1] ); // writing end 
  int fd = pipedes[0]; // reading end

  try {
    while (true) {
      const size_t buflen(4096);
      char buffer[buflen];
    
      int i = read( fd, buffer, buflen-1 );
      if (i <= 0) break; // TODO: Do something more sensible
      result.append( buffer, i );
    }
  } 
  catch( ... ) {
    close( fd );

    // Reap child processes
    {
      int status, w;
      while ( ( w = wait( &status ) ) == -1 && errno == EINTR );
      if ( w == -1 ) abort();
    }

    throw;
  }

  close( fd );

  // Reap child processes
  {
    int status, w;
    while ( ( w = wait( &status ) ) == -1 && errno == EINTR );
    if ( w == -1 )
      THROW_SYSTEM_ERROR( "wait" );
  }

  if ( result.size() && result[result.size()-1] == '\n' )
    result.erase( result.size()-1 );

  return result;
}
Beispiel #10
0
string exec_command( const string& str )
{
  // Construct this before any resources are claimed
  string result; 

  const char *argv[4]; // No ownership of memory

  // Respect the SHELL environment variable,
  // and drop back to using CMD.EXE
  argv[0] = getenv("SHELL");
  if ( !argv[0] || !*argv[0] ) {
    // TODO: On Windows NT 4, 2K and XP this is correct;
    // on Windows 95, 98 and ME, this should be COMMAND.COM,
    // though that'll probably be unusably slow.
    argv[0] = "CMD.EXE";
    argv[1] = "/C";
  } else {
    //
    argv[1] = "-c";
  }
  argv[2] = str.c_str();
  argv[3] = NULL;

  // -------
  // From now on we have to be careful about exceptions
  // as we have pipes and child processes hanging around
  //
  HANDLE hErr;
  if (DuplicateHandle(GetCurrentProcess(),
                      GetStdHandle(STD_ERROR_HANDLE),
                      GetCurrentProcess(),
                      &hErr,
                      0,
                      TRUE,
                      DUPLICATE_SAME_ACCESS) == FALSE)
    THROW_SYSTEM_ERROR( "DuplicateHandle" );
  

  // Two ends of the pipe:
  HANDLE hChildOutRd, hChildOutWr;
  {
    SECURITY_ATTRIBUTES saAttr;
    saAttr.nLength = sizeof (SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;

    if (!CreatePipe(&hChildOutRd, &hChildOutWr, &saAttr, 0)) {
      CloseHandle(hErr);
      THROW_SYSTEM_ERROR( "CreatePipe" );
    }
  }

  PROCESS_INFORMATION procInfo;

  {
    string command_line( make_command_line( argv[0], argv ) );

    STARTUPINFO startInfo;
    GetStartupInfo(&startInfo);
    startInfo.dwFlags = STARTF_USESTDHANDLES;
    startInfo.lpReserved = 0;
    startInfo.cbReserved2 = 0;
    startInfo.lpReserved2 = 0;
    startInfo.lpTitle = 0;
    startInfo.hStdInput = NULL;
    startInfo.hStdOutput = hChildOutWr;
    startInfo.hStdError = hErr;

    if (CreateProcess(0,
                      // Const correctness -- we've heard of it
                      const_cast< char* >( command_line.c_str() ),
                      NULL,
                      0, // default security attributes for thread
                      TRUE, // inherit handles (e.g. helper pipes)
                      0,
                      NULL,
                      0, // default starting directory
                      &startInfo,
                      &procInfo) == FALSE) {
      CloseHandle(hErr);
      CloseHandle(hChildOutRd);
      CloseHandle(hChildOutWr);
      THROW_SYSTEM_ERROR( "CreateProcess" );
    }

    // Close the thread handle -- we'll just watch the process
    CloseHandle(procInfo.hThread);
  }

  CloseHandle( hErr );
  CloseHandle( hChildOutWr );

  try {
    while (true) {
      const size_t buflen(4096);
      char buffer[buflen];

      // TODO:  Unicode conversions???

      DWORD i;
      ReadFile( hChildOutRd, buffer, buflen, &i, NULL);
      if (i <= 0) break; // TODO: Do something more sensible
      result.append( buffer, i ); // Might throw
    }
  } 
  catch( ... ) {
    CloseHandle( hChildOutRd );

    DWORD rv = WaitForMultipleObjects( 1, &procInfo.hProcess, 
				       FALSE, INFINITE );
    if ( rv == WAIT_FAILED ) abort();

    throw;
  }

  CloseHandle( hChildOutRd );

  DWORD rv = WaitForMultipleObjects( 1, &procInfo.hProcess, FALSE, INFINITE );
  if ( rv == WAIT_FAILED )
    THROW_SYSTEM_ERROR( "WaitForMultipleObjects" );  
  return result;
}