diff options
| author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2018-06-27 16:59:37 +0200 | 
|---|---|---|
| committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2018-06-27 16:59:37 +0200 | 
| commit | 8111b77e95b083137faf888aeb5892073adf7ab4 (patch) | |
| tree | ed3896dfd2c2bbd9cc41f0bfcab1ee2a41c1cc77 /lib/spdlog/fmt/bundled/posix.cc | |
| parent | e767091d649df311dd221e243ab2ce54776ae779 (diff) | |
New upstream version 2.0.0upstream/2.0.0
Diffstat (limited to 'lib/spdlog/fmt/bundled/posix.cc')
| -rw-r--r-- | lib/spdlog/fmt/bundled/posix.cc | 241 | 
1 files changed, 241 insertions, 0 deletions
diff --git a/lib/spdlog/fmt/bundled/posix.cc b/lib/spdlog/fmt/bundled/posix.cc new file mode 100644 index 0000000..356668c --- /dev/null +++ b/lib/spdlog/fmt/bundled/posix.cc @@ -0,0 +1,241 @@ +/* + A C++ interface to POSIX functions. + + Copyright (c) 2012 - 2016, Victor Zverovich + All rights reserved. + + For the license information refer to format.h. + */ + +// Disable bogus MSVC warnings. +#ifndef _CRT_SECURE_NO_WARNINGS +# define _CRT_SECURE_NO_WARNINGS +#endif + +#include "posix.h" + +#include <limits.h> +#include <sys/types.h> +#include <sys/stat.h> + +#ifndef _WIN32 +# include <unistd.h> +#else +# ifndef WIN32_LEAN_AND_MEAN +#  define WIN32_LEAN_AND_MEAN +# endif +# include <windows.h> +# include <io.h> + +# define O_CREAT _O_CREAT +# define O_TRUNC _O_TRUNC + +# ifndef S_IRUSR +#  define S_IRUSR _S_IREAD +# endif + +# ifndef S_IWUSR +#  define S_IWUSR _S_IWRITE +# endif + +# ifdef __MINGW32__ +#  define _SH_DENYNO 0x40 +# endif + +#endif  // _WIN32 + +#ifdef fileno +# undef fileno +#endif + +namespace { +#ifdef _WIN32 +// Return type of read and write functions. +typedef int RWResult; + +// On Windows the count argument to read and write is unsigned, so convert +// it from size_t preventing integer overflow. +inline unsigned convert_rwcount(std::size_t count) { +  return count <= UINT_MAX ? static_cast<unsigned>(count) : UINT_MAX; +} +#else +// Return type of read and write functions. +typedef ssize_t RWResult; + +inline std::size_t convert_rwcount(std::size_t count) { return count; } +#endif +} + +fmt::BufferedFile::~BufferedFile() FMT_NOEXCEPT { +  if (file_ && FMT_SYSTEM(fclose(file_)) != 0) +    fmt::report_system_error(errno, "cannot close file"); +} + +fmt::BufferedFile::BufferedFile( +    fmt::CStringRef filename, fmt::CStringRef mode) { +  FMT_RETRY_VAL(file_, FMT_SYSTEM(fopen(filename.c_str(), mode.c_str())), 0); +  if (!file_) +    FMT_THROW(SystemError(errno, "cannot open file {}", filename)); +} + +void fmt::BufferedFile::close() { +  if (!file_) +    return; +  int result = FMT_SYSTEM(fclose(file_)); +  file_ = FMT_NULL; +  if (result != 0) +    FMT_THROW(SystemError(errno, "cannot close file")); +} + +// A macro used to prevent expansion of fileno on broken versions of MinGW. +#define FMT_ARGS + +int fmt::BufferedFile::fileno() const { +  int fd = FMT_POSIX_CALL(fileno FMT_ARGS(file_)); +  if (fd == -1) +    FMT_THROW(SystemError(errno, "cannot get file descriptor")); +  return fd; +} + +fmt::File::File(fmt::CStringRef path, int oflag) { +  int mode = S_IRUSR | S_IWUSR; +#if defined(_WIN32) && !defined(__MINGW32__) +  fd_ = -1; +  FMT_POSIX_CALL(sopen_s(&fd_, path.c_str(), oflag, _SH_DENYNO, mode)); +#else +  FMT_RETRY(fd_, FMT_POSIX_CALL(open(path.c_str(), oflag, mode))); +#endif +  if (fd_ == -1) +    FMT_THROW(SystemError(errno, "cannot open file {}", path)); +} + +fmt::File::~File() FMT_NOEXCEPT { +  // Don't retry close in case of EINTR! +  // See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html +  if (fd_ != -1 && FMT_POSIX_CALL(close(fd_)) != 0) +    fmt::report_system_error(errno, "cannot close file"); +} + +void fmt::File::close() { +  if (fd_ == -1) +    return; +  // Don't retry close in case of EINTR! +  // See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html +  int result = FMT_POSIX_CALL(close(fd_)); +  fd_ = -1; +  if (result != 0) +    FMT_THROW(SystemError(errno, "cannot close file")); +} + +fmt::LongLong fmt::File::size() const { +#ifdef _WIN32 +  // Use GetFileSize instead of GetFileSizeEx for the case when _WIN32_WINNT +  // is less than 0x0500 as is the case with some default MinGW builds. +  // Both functions support large file sizes. +  DWORD size_upper = 0; +  HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd_)); +  DWORD size_lower = FMT_SYSTEM(GetFileSize(handle, &size_upper)); +  if (size_lower == INVALID_FILE_SIZE) { +    DWORD error = GetLastError(); +    if (error != NO_ERROR) +      FMT_THROW(WindowsError(GetLastError(), "cannot get file size")); +  } +  fmt::ULongLong long_size = size_upper; +  return (long_size << sizeof(DWORD) * CHAR_BIT) | size_lower; +#else +  typedef struct stat Stat; +  Stat file_stat = Stat(); +  if (FMT_POSIX_CALL(fstat(fd_, &file_stat)) == -1) +    FMT_THROW(SystemError(errno, "cannot get file attributes")); +  FMT_STATIC_ASSERT(sizeof(fmt::LongLong) >= sizeof(file_stat.st_size), +      "return type of File::size is not large enough"); +  return file_stat.st_size; +#endif +} + +std::size_t fmt::File::read(void *buffer, std::size_t count) { +  RWResult result = 0; +  FMT_RETRY(result, FMT_POSIX_CALL(read(fd_, buffer, convert_rwcount(count)))); +  if (result < 0) +    FMT_THROW(SystemError(errno, "cannot read from file")); +  return internal::to_unsigned(result); +} + +std::size_t fmt::File::write(const void *buffer, std::size_t count) { +  RWResult result = 0; +  FMT_RETRY(result, FMT_POSIX_CALL(write(fd_, buffer, convert_rwcount(count)))); +  if (result < 0) +    FMT_THROW(SystemError(errno, "cannot write to file")); +  return internal::to_unsigned(result); +} + +fmt::File fmt::File::dup(int fd) { +  // Don't retry as dup doesn't return EINTR. +  // http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html +  int new_fd = FMT_POSIX_CALL(dup(fd)); +  if (new_fd == -1) +    FMT_THROW(SystemError(errno, "cannot duplicate file descriptor {}", fd)); +  return File(new_fd); +} + +void fmt::File::dup2(int fd) { +  int result = 0; +  FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd))); +  if (result == -1) { +    FMT_THROW(SystemError(errno, +      "cannot duplicate file descriptor {} to {}", fd_, fd)); +  } +} + +void fmt::File::dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT { +  int result = 0; +  FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd))); +  if (result == -1) +    ec = ErrorCode(errno); +} + +void fmt::File::pipe(File &read_end, File &write_end) { +  // Close the descriptors first to make sure that assignments don't throw +  // and there are no leaks. +  read_end.close(); +  write_end.close(); +  int fds[2] = {}; +#ifdef _WIN32 +  // Make the default pipe capacity same as on Linux 2.6.11+. +  enum { DEFAULT_CAPACITY = 65536 }; +  int result = FMT_POSIX_CALL(pipe(fds, DEFAULT_CAPACITY, _O_BINARY)); +#else +  // Don't retry as the pipe function doesn't return EINTR. +  // http://pubs.opengroup.org/onlinepubs/009696799/functions/pipe.html +  int result = FMT_POSIX_CALL(pipe(fds)); +#endif +  if (result != 0) +    FMT_THROW(SystemError(errno, "cannot create pipe")); +  // The following assignments don't throw because read_fd and write_fd +  // are closed. +  read_end = File(fds[0]); +  write_end = File(fds[1]); +} + +fmt::BufferedFile fmt::File::fdopen(const char *mode) { +  // Don't retry as fdopen doesn't return EINTR. +  FILE *f = FMT_POSIX_CALL(fdopen(fd_, mode)); +  if (!f) +    FMT_THROW(SystemError(errno, "cannot associate stream with file descriptor")); +  BufferedFile file(f); +  fd_ = -1; +  return file; +} + +long fmt::getpagesize() { +#ifdef _WIN32 +  SYSTEM_INFO si; +  GetSystemInfo(&si); +  return si.dwPageSize; +#else +  long size = FMT_POSIX_CALL(sysconf(_SC_PAGESIZE)); +  if (size < 0) +    FMT_THROW(SystemError(errno, "cannot get memory page size")); +  return size; +#endif +}  | 
