Merge pull request #183 from hughbe/stat-fixes
Fix Windows build with posix specific stat APIs
diff --git a/include/llbuild/Basic/PlatformUtility.h b/include/llbuild/Basic/PlatformUtility.h
index 2415007..c2453d1 100644
--- a/include/llbuild/Basic/PlatformUtility.h
+++ b/include/llbuild/Basic/PlatformUtility.h
@@ -19,27 +19,19 @@
#define LLBUILD_BASIC_PLATFORMUTILITY_H
#include <cstdio>
-#include <sys/stat.h>
namespace llbuild {
namespace basic {
namespace sys {
-#if defined(_WIN32)
-using StatStruct = struct ::_stat;
-#else
-using StatStruct = struct ::stat;
-#endif
bool chdir(const char *fileName);
int close(int fileHandle);
-int lstat(const char *fileName, StatStruct *buf);
bool mkdir(const char *fileName);
int pclose(FILE *stream);
int pipe(int ptHandles[2]);
FILE *popen(const char *command, const char *mode);
int read(int fileHandle, void *destinationBuffer, unsigned int maxCharCount);
int rmdir(const char *path);
-int stat(const char *fileName, StatStruct *buf);
int symlink(const char *source, const char *target);
int unlink(const char *fileName);
int write(int fileHandle, void *destinationBuffer, unsigned int maxCharCount);
diff --git a/include/llbuild/Basic/Stat.h b/include/llbuild/Basic/Stat.h
new file mode 100644
index 0000000..7d79e38
--- /dev/null
+++ b/include/llbuild/Basic/Stat.h
@@ -0,0 +1,77 @@
+//===- Stat.h -------------------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLBUILD_BASIC_STAT_H
+#define LLBUILD_BASIC_STAT_H
+
+#include <sys/stat.h>
+
+#include "llvm/Support/FileSystem.h"
+
+namespace llbuild {
+namespace basic {
+namespace sys {
+
+#if !defined(S_IFBLK)
+#define S_IFBLK 0060000
+#endif
+#if !defined(S_IFIFO)
+#define S_IFIFO 0010000
+#endif
+#if !defined(S_IFSOCK)
+#define S_IFSOCK 00140000
+#endif
+#if !defined(S_IFLNK)
+#define S_IFLNK 0120000
+#endif
+
+#if !defined(S_ISREG)
+#define S_ISREG(mode) ((mode) & _S_IFMT) == S_IFREG
+#endif
+
+#if !defined(S_ISDIR)
+#define S_ISDIR(mode) ((mode) & _S_IFMT) == S_IFDIR
+#endif
+
+#if !defined(S_ISBLK)
+#define S_ISBLK(mode) ((mode) & _S_IFMT) == S_IFBLK
+#endif
+
+#if !defined(S_ISCHR)
+#define S_ISCHR(mode) ((mode) & _S_IFMT) == S_IFCHR
+#endif
+
+#if !defined(S_ISFIFO)
+#define S_ISFIFO(mode) ((mode) & _S_IFMT) == S_IFIFO
+#endif
+
+#if !defined(S_ISSOCK)
+#define S_ISSOCK(mode) ((mode) & _S_IFMT) == S_IFSOCK
+#endif
+
+#if !defined(S_ISLNK)
+#define S_ISLNK(mode) ((mode) & _S_IFMT) == S_IFLNK
+#endif
+
+#if defined(_WIN32)
+using StatStruct = struct ::_stat;
+#else
+using StatStruct = struct ::stat;
+#endif
+
+int lstat(const char *fileName, StatStruct *buf);
+int stat(const char *fileName, StatStruct *buf);
+}
+}
+}
+
+#endif // LLBUILD_BASIC_STAT_H
diff --git a/lib/Basic/FileInfo.cpp b/lib/Basic/FileInfo.cpp
index 7e7d7dd..ec76640 100644
--- a/lib/Basic/FileInfo.cpp
+++ b/lib/Basic/FileInfo.cpp
@@ -12,7 +12,7 @@
#include "llbuild/Basic/FileInfo.h"
-#include "llbuild/Basic/PlatformUtility.h"
+#include "llbuild/Basic/Stat.h"
#include <cassert>
#include <cstring>
diff --git a/lib/Basic/FileSystem.cpp b/lib/Basic/FileSystem.cpp
index 42db497..010348f 100644
--- a/lib/Basic/FileSystem.cpp
+++ b/lib/Basic/FileSystem.cpp
@@ -12,6 +12,7 @@
#include "llbuild/Basic/FileSystem.h"
#include "llbuild/Basic/PlatformUtility.h"
+#include "llbuild/Basic/Stat.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/FileSystem.h"
@@ -27,7 +28,7 @@
using namespace llvm;
using namespace llvm::sys::fs;
- static std::error_code fillStatus(int StatRet, const struct stat &Status,
+ static std::error_code fillStatus(int StatRet, const llbuild::basic::sys::StatStruct &Status,
file_status &Result) {
if (StatRet != 0) {
std::error_code ec(errno, std::generic_category());
@@ -55,10 +56,14 @@
else if (S_ISLNK(Status.st_mode))
Type = file_type::symlink_file;
+#if defined(_WIN32)
+ Result = file_status(Type);
+#else
perms Perms = static_cast<perms>(Status.st_mode);
Result =
file_status(Type, Perms, Status.st_dev, Status.st_ino, Status.st_mtime,
Status.st_uid, Status.st_gid, Status.st_size);
+#endif
return std::error_code();
}
@@ -67,8 +72,8 @@
SmallString<128> PathStorage;
StringRef P = Path.toNullTerminatedStringRef(PathStorage);
- struct stat Status;
- int StatRet = ::lstat(P.begin(), &Status);
+ llbuild::basic::sys::StatStruct Status;
+ int StatRet = llbuild::basic::sys::lstat(P.begin(), &Status);
return fillStatus(StatRet, Status, Result);
}
@@ -167,7 +172,7 @@
}
// Check if `path` is a directory.
- struct stat statbuf;
+ llbuild::basic::sys::StatStruct statbuf;
if (llbuild::basic::sys::lstat(path.c_str(), &statbuf) != 0) {
return false;
}
diff --git a/lib/Basic/PlatformUtility.cpp b/lib/Basic/PlatformUtility.cpp
index 2498e96..0ef78b9 100644
--- a/lib/Basic/PlatformUtility.cpp
+++ b/lib/Basic/PlatformUtility.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llbuild/Basic/PlatformUtility.h"
+#include "llbuild/Basic/Stat.h"
#if defined(_WIN32)
#include "LeanWindows.h"
diff --git a/unittests/Basic/FileSystemTest.cpp b/unittests/Basic/FileSystemTest.cpp
index 65182b6..31c94aa 100644
--- a/unittests/Basic/FileSystemTest.cpp
+++ b/unittests/Basic/FileSystemTest.cpp
@@ -15,6 +15,7 @@
#include "llbuild/Basic/FileSystem.h"
#include "llbuild/Basic/LLVM.h"
#include "llbuild/Basic/PlatformUtility.h"
+#include "llbuild/Basic/Stat.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -94,7 +95,7 @@
bool result = fs->remove(tempDir.c_str());
EXPECT_TRUE(result);
- struct stat statbuf;
+ sys::StatStruct statbuf;
EXPECT_EQ(-1, sys::stat(tempDir.c_str(), &statbuf));
EXPECT_EQ(ENOENT, errno);
}
@@ -144,7 +145,7 @@
bool result = fs->remove(tempDir.c_str());
EXPECT_TRUE(result);
- struct stat statbuf;
+ sys::StatStruct statbuf;
EXPECT_EQ(-1, sys::stat(tempDir.c_str(), &statbuf));
EXPECT_EQ(ENOENT, errno);
// Verify that the symlink target still exists.