]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
include,common: Add functions missing on Windows
authorLucian Petrut <lpetrut@cloudbasesolutions.com>
Fri, 11 Oct 2019 14:21:45 +0000 (17:21 +0300)
committerLucian Petrut <lpetrut@cloudbasesolutions.com>
Wed, 8 Jul 2020 06:38:27 +0000 (06:38 +0000)
The following functions are not avaialble on Windows, so we'll
need to define them.

* strptime
* pipe (defined as _pipe)
* lrand48
* posix_memalign
* pread, pwrite, fsync
* readv, writev

Signed-off-by: Lucian Petrut <lpetrut@cloudbasesolutions.com>
src/common/buffer.cc
src/common/compat.cc
src/include/compat.h
src/include/mempool.h
src/include/utime.h
src/include/win32/sys/uio.h [new file with mode: 0644]

index 1751f8e8058cc31e7f8e7394d33efc5615a908f8..695767cc4cd0d7a9e2a7622eab47b937451dd767 100644 (file)
@@ -1869,6 +1869,7 @@ static int do_writev(int fd, struct iovec *vec, uint64_t offset, unsigned veclen
   return 0;
 }
 
+#ifndef _WIN32
 int buffer::list::write_fd(int fd) const
 {
   // use writev!
@@ -1948,6 +1949,36 @@ int buffer::list::write_fd(int fd, uint64_t offset) const
   }
   return 0;
 }
+#else
+int buffer::list::write_fd(int fd) const
+{
+  // There's no writev on Windows. WriteFileGather may be an option,
+  // but it has strict requirements in terms of buffer size and alignment.
+  auto p = std::cbegin(_buffers);
+  uint64_t left_pbrs = get_num_buffers();
+  while (left_pbrs) {
+    int written = 0;
+    while (written < p->length()) {
+      int r = ::write(fd, p->c_str(), p->length() - written);
+      if (r < 0)
+        return -errno;
+
+      written += r;
+    }
+  }
+
+  return 0;
+
+}
+int buffer::list::write_fd(int fd, uint64_t offset) const
+{
+  int r = ::lseek64(fd, offset, SEEK_SET);
+  if (r != offset)
+    return -errno;
+
+  return write_fd(fd);
+}
+#endif
 
 __u32 buffer::list::crc32c(__u32 crc) const
 {
index 74e99165572c2ae3d3fea9a7052586bf05c18013..23fe2fa0e9def0c72926d78f982248ca4891d7ad 100644 (file)
@@ -213,6 +213,9 @@ char *ceph_strerror_r(int errnum, char *buf, size_t buflen)
 
 #ifdef _WIN32
 
+#include <iomanip>
+#include <ctime>
+
 // chown is not available on Windows. Plus, changing file owners is not
 // a common practice on Windows.
 int chown(const char *path, uid_t owner, gid_t group) {
@@ -227,4 +230,117 @@ int lchown(const char *path, uid_t owner, gid_t group) {
   return 0;
 }
 
-#endif /* _WIN32 */
\ No newline at end of file
+int posix_memalign(void **memptr, size_t alignment, size_t size) {
+  *memptr = _aligned_malloc(size, alignment);
+  return *memptr ? 0 : errno;
+}
+
+char *strptime(const char *s, const char *format, struct tm *tm) {
+  std::istringstream input(s);
+  input.imbue(std::locale(setlocale(LC_ALL, nullptr)));
+  input >> std::get_time(tm, format);
+  if (input.fail()) {
+    return nullptr;
+  }
+  return (char*)(s + input.tellg());
+}
+
+int pipe(int pipefd[2]) {
+  // We'll use the same pipe size as Linux (64kb).
+  return _pipe(pipefd, 0x10000, O_NOINHERIT);
+}
+
+// lrand48 is not available on Windows. We'll generate a pseudo-random
+// value in the 0 - 2^31 range by calling rand twice.
+long int lrand48(void) {
+  long int val;
+  val = (long int) rand();
+  val << 16;
+  val += (long int) rand();
+  return val;
+}
+
+int fsync(int fd) {
+  HANDLE handle = (HANDLE*)_get_osfhandle(fd);
+  if (handle == INVALID_HANDLE_VALUE)
+    return -1;
+  if (!FlushFileBuffers(handle))
+    return -1;
+  return 0;
+}
+
+ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset) {
+  DWORD bytes_written = 0;
+
+  HANDLE handle = (HANDLE*)_get_osfhandle(fd);
+  if (handle == INVALID_HANDLE_VALUE)
+    return -1;
+
+  OVERLAPPED overlapped = { 0 };
+  ULARGE_INTEGER offsetUnion;
+  offsetUnion.QuadPart = offset;
+
+  overlapped.Offset = offsetUnion.LowPart;
+  overlapped.OffsetHigh = offsetUnion.HighPart;
+
+  if (!WriteFile(handle, buf, count, &bytes_written, &overlapped))
+    // we may consider mapping error codes, although that may
+    // not be exhaustive.
+    return -1;
+
+  return bytes_written;
+}
+
+ssize_t pread(int fd, void *buf, size_t count, off_t offset) {
+  DWORD bytes_read = 0;
+
+  HANDLE handle = (HANDLE*)_get_osfhandle(fd);
+  if (handle == INVALID_HANDLE_VALUE)
+    return -1;
+
+  OVERLAPPED overlapped = { 0 };
+  ULARGE_INTEGER offsetUnion;
+  offsetUnion.QuadPart = offset;
+
+  overlapped.Offset = offsetUnion.LowPart;
+  overlapped.OffsetHigh = offsetUnion.HighPart;
+
+  if (!ReadFile(handle, buf, count, &bytes_read, &overlapped)) {
+    if (GetLastError() != ERROR_HANDLE_EOF)
+      return -1;
+  }
+
+  return bytes_read;
+}
+
+ssize_t preadv(int fd, const struct iovec *iov, int iov_cnt) {
+  ssize_t read = 0;
+
+  for (int i = 0; i < iov_cnt; i++) {
+    int r = ::read(fd, iov[i].iov_base, iov[i].iov_len);
+    if (r < 0)
+      return r;
+    read += r;
+    if (r < iov[i].iov_len)
+      break;
+  }
+
+  return read;
+}
+
+ssize_t writev(int fd, const struct iovec *iov, int iov_cnt) {
+  ssize_t written = 0;
+
+  for (int i = 0; i < iov_cnt; i++) {
+    int r = ::write(fd, iov[i].iov_base, iov[i].iov_len);
+    if (r < 0)
+      return r;
+    written += r;
+    if (r < iov[i].iov_len)
+      break;
+  }
+
+  return written;
+}
+
+#endif /* _WIN32 */
index 9197863e32b0672e6a0220e1f8ab4c24b87107e6..334d60eeace7933a99f68c45325f41b82b1c127a 100644 (file)
@@ -227,6 +227,11 @@ typedef union
   size_t _align;
 } cpu_set_t;
 
+struct iovec {
+  void *iov_base;
+  size_t iov_len;
+};
+
 #define SHUT_RD SD_RECEIVE
 #define SHUT_WR SD_SEND
 #define SHUT_RDWR SD_BOTH
@@ -248,15 +253,27 @@ typedef union
 #define ESTALE 256
 #define EREMOTEIO 257
 
-// O_CLOEXEC is not defined on Windows. Since handles aren't inherited
-// with subprocesses unless explicitly requested, we'll define this
-// flag as a no-op.
-#define O_CLOEXEC 0
+#define IOV_MAX 1024
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+ssize_t readv(int fd, const struct iovec *iov, int iov_cnt);
+ssize_t writev(int fd, const struct iovec *iov, int iov_cnt);
+
+int fsync(int fd);
+ssize_t pread(int fd, void *buf, size_t count, off_t offset);
+ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
+
+long int lrand48(void);
+
+int pipe(int pipefd[2]);
+
+int posix_memalign(void **memptr, size_t alignment, size_t size);
+
+char *strptime(const char *s, const char *format, struct tm *tm);
+
 int chown(const char *path, uid_t owner, gid_t group);
 int fchown(int fd, uid_t owner, gid_t group);
 int lchown(const char *path, uid_t owner, gid_t group);
@@ -265,6 +282,11 @@ int lchown(const char *path, uid_t owner, gid_t group);
 }
 #endif
 
+// O_CLOEXEC is not defined on Windows. Since handles aren't inherited
+// with subprocesses unless explicitly requested, we'll define this
+// flag as a no-op.
+#define O_CLOEXEC 0
+
 #endif /* WIN32 */
 
 #endif /* !CEPH_COMPAT_H */
index 8027305688d201bb39c6b3056736791b99c8b96d..79cf862c8cd7b0cec130fbd1c0e1dcb661ad8ae2 100644 (file)
@@ -31,6 +31,7 @@
 #include "include/ceph_assert.h"
 #include "include/compact_map.h"
 #include "include/compact_set.h"
+#include "include/compat.h"
 
 
 /*
index 5e58f1b149e4a14e92efaa49511926740d3ca9cb..ab053433e2a039438f151082ecdc59e19e738bc1 100644 (file)
@@ -24,6 +24,7 @@
 #include <seastar/core/lowres_clock.hh>
 #endif
 
+#include "include/compat.h"
 #include "include/types.h"
 #include "include/timegm.h"
 #include "common/strtol.h"
@@ -466,11 +467,15 @@ public:
       }
     }
 
+    #ifndef _WIN32
     // apply the tm_gmtoff manually below, since none of mktime,
     // gmtime, and localtime seem to do it.  zero it out here just in
     // case some other libc *does* apply it.  :(
     auto gmtoff = tm.tm_gmtoff;
     tm.tm_gmtoff = 0;
+    #else
+    auto gmtoff = _timezone;
+    #endif /* _WIN32 */
 
     time_t t = internal_timegm(&tm);
     if (epoch)
diff --git a/src/include/win32/sys/uio.h b/src/include/win32/sys/uio.h
new file mode 100644 (file)
index 0000000..15e95be
--- /dev/null
@@ -0,0 +1 @@
+#include "include/compat.h"