예제 #1
0
inline bool wait_until(
        const child_handle &p,
        int & exit_code,
        const std::chrono::time_point<Clock, Duration>& time_out,
        std::error_code & ec) noexcept
{
    pid_t ret;
    int status;

    bool timed_out;

    do
    {
        ret = ::waitpid(p.pid, &status, WNOHANG);
        if (ret == 0)
        {
            timed_out = Clock::now() >= time_out;
            if (timed_out)
                return false;
        }
    }
    while ((ret == 0) ||
          (((ret == -1) && errno == EINTR) ||
           ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status))));

    if (ret == -1)
        ec = boost::process::detail::get_last_error();
    else
    {
        ec.clear();
        exit_code = status;
    }

    return true;
}
예제 #2
0
	addrinfo_ptr getaddrinfo(const char * host, const char * service, std::error_code & err)
	{
		addrinfo_type hints;

		std::memset(&hints, 0, sizeof(hints));
		hints.ai_family = AF_UNSPEC;
		hints.ai_protocol = IPPROTO_TCP;
		hints.ai_socktype = SOCK_STREAM;

		int res;
		addrinfo_type * ptr;
		do res = ::getaddrinfo(host, service, &hints, &ptr); while (res == EAI_AGAIN);
		if (res == 0)
		{
			err.clear();
			return addrinfo_ptr(ptr);
		}

		if (res == EAI_SYSTEM)
		{
			err.assign(errno, std::generic_category());
			return addrinfo_ptr(nullptr);
		}
		else
		{
			err.assign(res, gai_error_category());
			return addrinfo_ptr(nullptr);
		}
	}
예제 #3
0
파일: gl.cpp 프로젝트: nyorain/ny
bool GlContext::makeNotCurrent(std::error_code& ec)
{
	ec.clear();

	std::mutex* mutex;
	auto threadid = std::this_thread::get_id();
	auto& map = contextCurrentMap(mutex);
	decltype(map.begin()) thisThreadIt {};

	//check if it is already not current
	{
		std::lock_guard<std::mutex> lock(*mutex);

		thisThreadIt = map.find(threadid);
		if(thisThreadIt == map.end()) thisThreadIt = map.insert({threadid, {}}).first;

		if(thisThreadIt->second.first != this)
		{
			ec = Errc::contextAlreadyNotCurrent;
			return true;
		}
	}

	if(!makeNotCurrentImpl(ec)) return false;

	std::lock_guard<std::mutex> lock(*mutex);
	thisThreadIt->second = {nullptr, nullptr};
	return true;
}
예제 #4
0
파일: Filesystem.cpp 프로젝트: Elzevir/xbmc
space_info space(const std::string& path, std::error_code& ec)
{
  using WINDOWS::ToW;

  ec.clear();
  space_info sp;
  auto pathW = ToW(path);

  ULARGE_INTEGER capacity;
  ULARGE_INTEGER available;
  ULARGE_INTEGER free;
  auto result = GetDiskFreeSpaceExW(pathW.c_str(), &available, &capacity, &free);

  if (result == FALSE)
  {
    ec.assign(GetLastError(), std::system_category());
    sp.available = static_cast<uintmax_t>(-1);
    sp.capacity = static_cast<uintmax_t>(-1);
    sp.free = static_cast<uintmax_t>(-1);
    return sp;
  }

  sp.available = static_cast<uintmax_t>(available.QuadPart);
  sp.capacity = static_cast<uintmax_t>(capacity.QuadPart);
  sp.free = static_cast<uintmax_t>(free.QuadPart);

  return sp;
}
inline bool wait_until(
        child_handle &p,
        int & exit_code,
        const std::chrono::time_point<Clock, Duration>& timeout_time,
        std::error_code &ec) noexcept
{
    std::chrono::milliseconds ms =
            std::chrono::duration_cast<std::chrono::milliseconds>(
                    timeout_time - std::chrono::system_clock::now());

    ::boost::detail::winapi::DWORD_ _exit_code = 1;

    if (::boost::detail::winapi::WaitForSingleObject(p.process_handle(),
            static_cast<::boost::detail::winapi::DWORD_>(ms.count()))
                == ::boost::detail::winapi::wait_failed)
        ec = std::error_code(
            ::boost::detail::winapi::GetLastError(),
            std::system_category());
    else if (!::boost::detail::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code))
        ec = std::error_code(
            ::boost::detail::winapi::GetLastError(),
            std::system_category());
    else
        ec.clear();

    exit_code = static_cast<int>(exit_code);
    ::boost::detail::winapi::CloseHandle(p.proc_info.hProcess);
    p.proc_info.hProcess = ::boost::detail::winapi::INVALID_HANDLE_VALUE_;
    return true;
;
}
예제 #6
0
파일: glx.cpp 프로젝트: nyorain/ny
bool GlxContext::swapInterval(int interval, std::error_code& ec) const
{
	//TODO: check for interval < 0 and tear extensions not supported.
	ec.clear();

	if(!GLAD_GLX_EXT_swap_control || !glXSwapIntervalEXT)
	{
		ec = {GlContextErrc::extensionNotSupported};
		return false;
	}

	const GlSurface* currentSurface;
	GlContext::current(&currentSurface);

	auto currentGlxSurface = dynamic_cast<const GlxSurface*>(currentSurface);
	if(!currentGlxSurface)
	{
		// ec = {GlContextErrorCode::surfaceNotCurrent}; //TODO: add error for this case
		return false;
	}

	::glXSwapIntervalEXT(xDisplay(), currentGlxSurface->xDrawable(), interval);

	//TODO: handle possible error into ec

	return true;
}
예제 #7
0
inline void terminate(const group_handle &p, std::error_code &ec) noexcept
{
    if (!::boost::winapi::TerminateJobObject(p.handle(), EXIT_FAILURE))
        ec = boost::process::detail::get_last_error();
    else
        ec.clear();
}
예제 #8
0
 file_status link_status(path p, struct stat& st, std::error_code& ec)
 {
   if (::stat(p.c_str(), &st) != 0) {
     if (errno == ENOENT) {
       ec.clear();
       return file_status{file_type::not_found, perms::none};
     } else {
       ec = {errno, std::system_category()};
       return {};
     }
   }
   ec.clear();
   file_type type = to_file_type(st, ec);
   perms prms     = static_cast<perms>(st.st_mode) & perms::mask;
   return file_status{type, prms};
 }
예제 #9
0
  bool copy_file(const path& from,
                 const path& to,
                 copy_options options,
                 std::error_code& ec) noexcept
  {
    auto t = status(to, ec);
    if (!is_regular_file(from) ||
        (t.type() != file_type::not_found &&
         (t.type() != file_type::regular || equivalent(from, to) ||
          (options &
           (copy_options::skip_existing | copy_options::overwrite_existing |
            copy_options::update_existing)) == copy_options::none))) {
      ec.assign(EEXIST, std::system_category());
    } else {
      if (t.type() == file_type::not_found ||
          (options & copy_options::overwrite_existing) != copy_options::none ||
          ((options & copy_options::update_existing) != copy_options::none &&
           last_write_time(from) > last_write_time(to))) {
        std::ifstream src(from, std::ios::binary);
        std::ofstream dst(to, std::ios::binary | std::ios::trunc);

        dst << src.rdbuf();
        if (errno != 0) {
          ec = {errno, std::system_category()};
        } else {
          ec.clear();
          return true;
        }
      }
    }
    return false;
  }
예제 #10
0
inline bool wait_for(
        const group_handle &p,
        const std::chrono::duration<Rep, Period>& rel_time,
        std::error_code & ec) noexcept
{

    pid_t ret;
    int status;

    auto start = std::chrono::system_clock::now();
    auto time_out = start + rel_time;

    bool time_out_occured = false;
    do
    {
        ret = ::waitpid(-p.grp, &status, WUNTRACED | WNOHANG);
        if (std::chrono::system_clock::now() >= time_out)
        {
            time_out_occured = true;
            break;
        }
    } 
    while (((ret == -1) && errno == EINTR)       || 
           ((ret != -1) && !WIFEXITED(status)));


    if (ret == -1)
        ec = boost::process::detail::get_last_error();
    else
        ec.clear();

    return !time_out_occured;
}
예제 #11
0
 void resize_file(const path& p, uintmax_t size, std::error_code& ec) noexcept
 {
   if (::truncate(p.c_str(), static_cast<off_t>(size))) {
     ec = {errno, std::system_category()};
   } else {
     ec.clear();
   }
 }
예제 #12
0
 void rename(const path& from, const path& to, std::error_code& ec) noexcept
 {
   if (::rename(from.c_str(), to.c_str())) {
     ec = {errno, std::system_category()};
   } else {
     ec.clear();
   }
 }
예제 #13
0
 void current_path(const path& p, std::error_code& ec) noexcept
 {
   if (chdir(p.c_str()) == 0) {
     ec = {errno, std::system_category()};
   } else {
     ec.clear();
   }
 }
예제 #14
0
 uintmax_t hard_link_count(struct stat st, std::error_code& ec)
 {
   if (ec.value() == 0) {
     ec.clear();
   } else {
     return 0;
   }
   return st.st_nlink;
 }
예제 #15
0
void
state_machine_t::shutdown(std::error_code ec) {
    if (shutdowned.exchange(true)) {
        return;
    }

    auto state = *this->state.synchronize();
    COCAINE_LOG_DEBUG(log, "slave is shutting down from state %s: %s", state->name(), ec.message());

    state->cancel();
    if(state->terminating()) {
        // We don't consider any reason for termination in "terminating" state as an error
        ec.clear();
    }
    migrate(std::make_shared<stopped_t>(ec));

    fetcher.apply([&](std::shared_ptr<fetcher_t>& fetcher) {
        fetcher->close();
        fetcher.reset();
    });

    if (ec && ec != error::overseer_shutdowning) {
        dump();
    }

    data.channels.apply([&](channels_map_t& channels) {
        const auto size = channels.size();
        if (size > 0) {
            COCAINE_LOG_WARNING(log, "slave is dropping %d sessions", size);
        }

        for (auto& channel : channels) {
            loop.post([=]() {
                channel.second->close_both();
            });
        }

        channels.clear();
    });

    // Check if the slave has been terminated externally. If so, do not call the cleanup callback.
    if (closed) {
        return;
    }

    // NOTE: To prevent deadlock between session.channels and overseer.pool. Consider some
    // other solution.
    const auto cleanup_handler = cleanup;
    loop.post([=]() {
        try {
            cleanup_handler(ec);
        } catch (const std::exception& err) {
            // Just eat an exception, we don't care why the cleanup handler failed to do its job.
            COCAINE_LOG_WARNING(log, "unable to cleanup after slave's death: %s", err.what());
        }
    });
}
예제 #16
0
 uintmax_t file_size(struct stat st, std::error_code& ec)
 {
   if (ec.value() == 0) {
     ec.clear();
   } else {
     return 0;
   }
   return st.st_size;
 }
예제 #17
0
 path current_path(std::error_code& ec)
 {
   char temp[PATH_MAX];
   if (::getcwd(temp, PATH_MAX) == nullptr) {
     ec = {errno, std::system_category()};
   } else {
     ec.clear();
   }
   return path(temp);
 }
예제 #18
0
 path canonical(const path& p, std::error_code& ec)
 {
   char tmp[PATH_MAX];
   if (realpath(p.c_str(), tmp) == nullptr) {
     ec = {errno, std::system_category()};
   } else {
     ec.clear();
   }
   return path(tmp);
 }
예제 #19
0
inline void terminate(const child_handle &p, std::error_code &ec) noexcept
{
    if (::kill(p.pid, SIGKILL) == -1)
        ec = boost::process::detail::get_last_error();
    else
        ec.clear();

    int status;
    ::waitpid(p.pid, &status, 0); //just to clean it up
}
예제 #20
0
 bool create_directory(const path& p, std::error_code& ec) noexcept
 {
   auto error = mkdir(p.c_str(), static_cast<int>(perms::all));
   if (error && !is_directory(p)) {
     ec = {errno, std::system_category()};
   } else {
     ec.clear();
   }
   return !error;
 }
예제 #21
0
 struct stat lstat(path p, std::error_code& ec)
 {
   struct stat st;
   if (::lstat(p.c_str(), &st) != 0) {
     ec = {errno, std::system_category()};
   } else {
     ec.clear();
   }
   return st;
 }
예제 #22
0
inline void terminate(child_handle &p, std::error_code &ec) noexcept
{
    if (!::boost::detail::winapi::TerminateProcess(p.process_handle(), EXIT_FAILURE))
        ec = boost::process::detail::get_last_error();
    else
    {
        ec.clear();
        ::boost::detail::winapi::CloseHandle(p.proc_info.hProcess);
        p.proc_info.hProcess = ::boost::detail::winapi::INVALID_HANDLE_VALUE_;
    }
}
예제 #23
0
 /// Manually close the file descriptor
 void close(std::error_code& ec) noexcept
 {
     ec.clear();
     errno = 0;
     if (::close(fd_) == 0) {
         fd_ = -1;
         delete_ = false;
     } else {
         ec.assign(errno, std::system_category());
     }
 }
예제 #24
0
 bool remove(const path& p, std::error_code& ec) noexcept
 {
   if (!exists(p, ec)) return false;
   if (::remove(p.c_str())) {
     ec = {errno, std::system_category()};
     return false;
   } else {
     ec.clear();
     return true;
   }
 }
예제 #25
0
 bool equivalent(const path& p1, const path& p2, std::error_code& ec) noexcept
 {
   struct stat st1;
   struct stat st2;
   if (::stat(p1.c_str(), &st1) || ::stat(p2.c_str(), &st2)) {
     ec = {errno, std::system_category()};
     return false;
   } else {
     ec.clear();
     return st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino;
   }
 }
예제 #26
0
파일: glx.cpp 프로젝트: nyorain/ny
bool GlxContext::makeNotCurrentImpl(std::error_code& ec)
{
	ec.clear();

    if(!::glXMakeCurrent(xDisplay(), 0, nullptr))
    {
		//TODO: handle error into ec
		warning("ny::GlxContext::makeNotCurrentImpl (glXMakeCurrent) failed");
        return false;
    }

    return true;
}
예제 #27
0
파일: glx.cpp 프로젝트: nyorain/ny
bool GlxContext::makeCurrentImpl(const GlSurface& surface, std::error_code& ec)
{
	ec.clear();

	auto drawable = dynamic_cast<const GlxSurface*>(&surface)->xDrawable();
    if(!::glXMakeCurrent(xDisplay(), drawable, glxContext_))
    {
		//TODO: handle error into ec
		warning("ny::GlxContext::makeCurrentImpl (glXMakeCurrent) failed");
        return false;
    }

    return true;
}
예제 #28
0
::std::string font_resource_factory::font_family(::std::error_code& ec) const noexcept {
	::std::string s;
	try {
		s = _Family;
	}
	catch (const ::std::bad_alloc&) {
		ec = make_error_code(errc::not_enough_memory);
		return s;
	}
	catch (const ::std::length_error&) {
		ec = make_error_code(errc::not_enough_memory);
		return s;
	}
	ec.clear();
	return s;
}
예제 #29
0
    file_time_type last_write_time(struct stat st, std::error_code& ec)
    {
      if (ec.value() == 0) {
        ec.clear();
      } else {
        return {};
      }
#if __APPLE__
      return file_time_type() +
             std::chrono::duration_cast<file_time_type::duration>(
               std::chrono::nanoseconds(st.st_mtimespec.tv_nsec));
#else
      return file_time_type() +
             std::chrono::duration_cast<file_time_type::duration>(
               std::chrono::nanoseconds(st.st_mtim.tv_nsec));
#endif
    }
예제 #30
0
inline bool is_running(const child_handle &p, int & exit_code, std::error_code &ec) noexcept
{
    ::boost::detail::winapi::DWORD_ code;
    //single value, not needed in the winapi.
    if (!::boost::detail::winapi::GetExitCodeProcess(p.process_handle(), &code))
        ec = ::boost::process::detail::get_last_error();
    else
        ec.clear();

    if (code == still_active)
        return true;
    else
    {
        exit_code = code;
        return false;
    }    
}