Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
P
protobuf
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
protobuf
Commits
f15185d3
Commit
f15185d3
authored
Jul 24, 2017
by
Feng Xiao
Committed by
GitHub
Jul 24, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2969 from laszlocsomor/master
Windows: support long paths in open/mkdir/access
parents
eef2edcb
e05e777d
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
970 additions
and
81 deletions
+970
-81
BUILD
BUILD
+14
-0
extract_includes.bat.in
cmake/extract_includes.bat.in
+1
-0
libprotobuf-lite.cmake
cmake/libprotobuf-lite.cmake
+1
-0
libprotoc.cmake
cmake/libprotoc.cmake
+1
-0
tests.cmake
cmake/tests.cmake
+3
-0
Makefile.am
src/Makefile.am
+3
-0
command_line_interface.cc
src/google/protobuf/compiler/command_line_interface.cc
+14
-24
command_line_interface_unittest.cc
...ogle/protobuf/compiler/command_line_interface_unittest.cc
+13
-15
importer.cc
src/google/protobuf/compiler/importer.cc
+10
-8
objectivec_helpers.cc
...google/protobuf/compiler/objectivec/objectivec_helpers.cc
+8
-3
plugin.cc
src/google/protobuf/compiler/plugin.cc
+8
-9
zero_copy_stream_impl.cc
src/google/protobuf/io/zero_copy_stream_impl.cc
+9
-4
zero_copy_stream_unittest.cc
src/google/protobuf/io/zero_copy_stream_unittest.cc
+8
-3
message_unittest.cc
src/google/protobuf/message_unittest.cc
+9
-3
io_win32.cc
src/google/protobuf/stubs/io_win32.cc
+362
-0
io_win32.h
src/google/protobuf/stubs/io_win32.h
+96
-0
io_win32_unittest.cc
src/google/protobuf/stubs/io_win32_unittest.cc
+367
-0
file.cc
src/google/protobuf/testing/file.cc
+13
-6
googletest.cc
src/google/protobuf/testing/googletest.cc
+30
-6
No files found.
BUILD
View file @
f15185d3
...
@@ -108,6 +108,7 @@ cc_library(
...
@@ -108,6 +108,7 @@ cc_library(
"src/google/protobuf/stubs/bytestream.cc",
"src/google/protobuf/stubs/bytestream.cc",
"src/google/protobuf/stubs/common.cc",
"src/google/protobuf/stubs/common.cc",
"src/google/protobuf/stubs/int128.cc",
"src/google/protobuf/stubs/int128.cc",
"src/google/protobuf/stubs/io_win32.cc",
"src/google/protobuf/stubs/once.cc",
"src/google/protobuf/stubs/once.cc",
"src/google/protobuf/stubs/status.cc",
"src/google/protobuf/stubs/status.cc",
"src/google/protobuf/stubs/statusor.cc",
"src/google/protobuf/stubs/statusor.cc",
...
@@ -160,6 +161,7 @@ cc_library(
...
@@ -160,6 +161,7 @@ cc_library(
"src/google/protobuf/service.cc",
"src/google/protobuf/service.cc",
"src/google/protobuf/source_context.pb.cc",
"src/google/protobuf/source_context.pb.cc",
"src/google/protobuf/struct.pb.cc",
"src/google/protobuf/struct.pb.cc",
"src/google/protobuf/stubs/io_win32.cc",
"src/google/protobuf/stubs/mathlimits.cc",
"src/google/protobuf/stubs/mathlimits.cc",
"src/google/protobuf/stubs/substitute.cc",
"src/google/protobuf/stubs/substitute.cc",
"src/google/protobuf/text_format.cc",
"src/google/protobuf/text_format.cc",
...
@@ -471,6 +473,7 @@ COMMON_TEST_SRCS = [
...
@@ -471,6 +473,7 @@ COMMON_TEST_SRCS = [
# AUTOGEN(common_test_srcs)
# AUTOGEN(common_test_srcs)
"src/google/protobuf/arena_test_util.cc",
"src/google/protobuf/arena_test_util.cc",
"src/google/protobuf/map_test_util.cc",
"src/google/protobuf/map_test_util.cc",
"src/google/protobuf/stubs/io_win32.cc",
"src/google/protobuf/test_util.cc",
"src/google/protobuf/test_util.cc",
"src/google/protobuf/testing/file.cc",
"src/google/protobuf/testing/file.cc",
"src/google/protobuf/testing/googletest.cc",
"src/google/protobuf/testing/googletest.cc",
...
@@ -491,6 +494,16 @@ cc_binary(
...
@@ -491,6 +494,16 @@ cc_binary(
],
],
)
)
cc_test(
name = "win32_test",
srcs = ["src/google/protobuf/stubs/io_win32_unittest.cc"],
deps = [
":protobuf_lite",
"//external:gtest_main",
],
tags = ["manual", "windows"],
)
cc_test(
cc_test(
name = "protobuf_test",
name = "protobuf_test",
srcs = COMMON_TEST_SRCS + [
srcs = COMMON_TEST_SRCS + [
...
@@ -537,6 +550,7 @@ cc_test(
...
@@ -537,6 +550,7 @@ cc_test(
"src/google/protobuf/stubs/bytestream_unittest.cc",
"src/google/protobuf/stubs/bytestream_unittest.cc",
"src/google/protobuf/stubs/common_unittest.cc",
"src/google/protobuf/stubs/common_unittest.cc",
"src/google/protobuf/stubs/int128_unittest.cc",
"src/google/protobuf/stubs/int128_unittest.cc",
"src/google/protobuf/stubs/io_win32_unittest.cc",
"src/google/protobuf/stubs/once_unittest.cc",
"src/google/protobuf/stubs/once_unittest.cc",
"src/google/protobuf/stubs/status_test.cc",
"src/google/protobuf/stubs/status_test.cc",
"src/google/protobuf/stubs/statusor_test.cc",
"src/google/protobuf/stubs/statusor_test.cc",
...
...
cmake/extract_includes.bat.in
View file @
f15185d3
...
@@ -100,6 +100,7 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\casts.h" includ
...
@@ -100,6 +100,7 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\casts.h" includ
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\common.h" include\google\protobuf\stubs\common.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\common.h" include\google\protobuf\stubs\common.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\fastmem.h" include\google\protobuf\stubs\fastmem.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\fastmem.h" include\google\protobuf\stubs\fastmem.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\hash.h" include\google\protobuf\stubs\hash.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\hash.h" include\google\protobuf\stubs\hash.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\io_win32.h" include\google\protobuf\stubs\io_win32.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\logging.h" include\google\protobuf\stubs\logging.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\logging.h" include\google\protobuf\stubs\logging.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\macros.h" include\google\protobuf\stubs\macros.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\macros.h" include\google\protobuf\stubs\macros.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\mutex.h" include\google\protobuf\stubs\mutex.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\mutex.h" include\google\protobuf\stubs\mutex.h
...
...
cmake/libprotobuf-lite.cmake
View file @
f15185d3
...
@@ -13,6 +13,7 @@ set(libprotobuf_lite_files
...
@@ -13,6 +13,7 @@ set(libprotobuf_lite_files
${
protobuf_source_dir
}
/src/google/protobuf/stubs/bytestream.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/bytestream.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/common.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/common.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/int128.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/int128.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/io_win32.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/once.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/once.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/status.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/status.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/statusor.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/statusor.cc
...
...
cmake/libprotoc.cmake
View file @
f15185d3
...
@@ -93,6 +93,7 @@ set(libprotoc_files
...
@@ -93,6 +93,7 @@ set(libprotoc_files
${
protobuf_source_dir
}
/src/google/protobuf/compiler/ruby/ruby_generator.cc
${
protobuf_source_dir
}
/src/google/protobuf/compiler/ruby/ruby_generator.cc
${
protobuf_source_dir
}
/src/google/protobuf/compiler/subprocess.cc
${
protobuf_source_dir
}
/src/google/protobuf/compiler/subprocess.cc
${
protobuf_source_dir
}
/src/google/protobuf/compiler/zip_writer.cc
${
protobuf_source_dir
}
/src/google/protobuf/compiler/zip_writer.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/io_win32.cc
)
)
set
(
libprotoc_headers
set
(
libprotoc_headers
...
...
cmake/tests.cmake
View file @
f15185d3
...
@@ -160,6 +160,8 @@ set(tests_files
...
@@ -160,6 +160,8 @@ set(tests_files
${
protobuf_source_dir
}
/src/google/protobuf/stubs/bytestream_unittest.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/bytestream_unittest.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/common_unittest.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/common_unittest.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/int128_unittest.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/int128_unittest.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/io_win32.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/io_win32_unittest.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/once_unittest.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/once_unittest.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/status_test.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/status_test.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/statusor_test.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/statusor_test.cc
...
@@ -198,6 +200,7 @@ target_link_libraries(tests libprotoc libprotobuf gmock_main)
...
@@ -198,6 +200,7 @@ target_link_libraries(tests libprotoc libprotobuf gmock_main)
set
(
test_plugin_files
set
(
test_plugin_files
${
protobuf_source_dir
}
/src/google/protobuf/compiler/mock_code_generator.cc
${
protobuf_source_dir
}
/src/google/protobuf/compiler/mock_code_generator.cc
${
protobuf_source_dir
}
/src/google/protobuf/stubs/io_win32.cc
${
protobuf_source_dir
}
/src/google/protobuf/testing/file.cc
${
protobuf_source_dir
}
/src/google/protobuf/testing/file.cc
${
protobuf_source_dir
}
/src/google/protobuf/testing/file.h
${
protobuf_source_dir
}
/src/google/protobuf/testing/file.h
${
protobuf_source_dir
}
/src/google/protobuf/compiler/test_plugin.cc
${
protobuf_source_dir
}
/src/google/protobuf/compiler/test_plugin.cc
...
...
src/Makefile.am
View file @
f15185d3
...
@@ -198,6 +198,8 @@ libprotobuf_lite_la_SOURCES = \
...
@@ -198,6 +198,8 @@ libprotobuf_lite_la_SOURCES = \
google/protobuf/stubs/hash.h
\
google/protobuf/stubs/hash.h
\
google/protobuf/stubs/int128.cc
\
google/protobuf/stubs/int128.cc
\
google/protobuf/stubs/int128.h
\
google/protobuf/stubs/int128.h
\
google/protobuf/stubs/io_win32.cc
\
google/protobuf/stubs/io_win32.h
\
google/protobuf/stubs/map_util.h
\
google/protobuf/stubs/map_util.h
\
google/protobuf/stubs/mathutil.h
\
google/protobuf/stubs/mathutil.h
\
google/protobuf/stubs/once.cc
\
google/protobuf/stubs/once.cc
\
...
@@ -762,6 +764,7 @@ protobuf_test_SOURCES = \
...
@@ -762,6 +764,7 @@ protobuf_test_SOURCES = \
google/protobuf/stubs/bytestream_unittest.cc
\
google/protobuf/stubs/bytestream_unittest.cc
\
google/protobuf/stubs/common_unittest.cc
\
google/protobuf/stubs/common_unittest.cc
\
google/protobuf/stubs/int128_unittest.cc
\
google/protobuf/stubs/int128_unittest.cc
\
google/protobuf/stubs/io_win32_unittest.cc
\
google/protobuf/stubs/once_unittest.cc
\
google/protobuf/stubs/once_unittest.cc
\
google/protobuf/stubs/statusor_test.cc
\
google/protobuf/stubs/statusor_test.cc
\
google/protobuf/stubs/status_test.cc
\
google/protobuf/stubs/status_test.cc
\
...
...
src/google/protobuf/compiler/command_line_interface.cc
View file @
f15185d3
...
@@ -45,10 +45,7 @@
...
@@ -45,10 +45,7 @@
#endif
#endif
#include <sys/stat.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <fcntl.h>
#ifdef _MSC_VER
#ifndef _MSC_VER
#include <io.h>
#include <direct.h>
#else
#include <unistd.h>
#include <unistd.h>
#endif
#endif
#include <errno.h>
#include <errno.h>
...
@@ -80,6 +77,7 @@
...
@@ -80,6 +77,7 @@
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/stubs/io_win32.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/stubs/substitute.h>
...
@@ -91,22 +89,6 @@ namespace google {
...
@@ -91,22 +89,6 @@ namespace google {
namespace
protobuf
{
namespace
protobuf
{
namespace
compiler
{
namespace
compiler
{
#if defined(_WIN32)
#define mkdir(name, mode) mkdir(name)
#ifndef W_OK
#define W_OK 02 // not defined by MSVC for whatever reason
#endif
#ifndef F_OK
#define F_OK 00 // not defined by MSVC for whatever reason
#endif
#ifndef STDIN_FILENO
#define STDIN_FILENO 0
#endif
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
#endif
#ifndef O_BINARY
#ifndef O_BINARY
#ifdef _O_BINARY
#ifdef _O_BINARY
#define O_BINARY _O_BINARY
#define O_BINARY _O_BINARY
...
@@ -118,6 +100,14 @@ namespace compiler {
...
@@ -118,6 +100,14 @@ namespace compiler {
namespace
{
namespace
{
#if defined(_WIN32) && !defined(__CYGWIN__)
#if defined(_WIN32) && !defined(__CYGWIN__)
static
const
char
*
kPathSeparator
=
";"
;
static
const
char
*
kPathSeparator
=
";"
;
// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import
// them like we do below.
using
google
::
protobuf
::
internal
::
win32
::
access
;
using
google
::
protobuf
::
internal
::
win32
::
close
;
using
google
::
protobuf
::
internal
::
win32
::
mkdir
;
using
google
::
protobuf
::
internal
::
win32
::
open
;
using
google
::
protobuf
::
internal
::
win32
::
setmode
;
using
google
::
protobuf
::
internal
::
win32
::
write
;
#else
#else
static
const
char
*
kPathSeparator
=
":"
;
static
const
char
*
kPathSeparator
=
":"
;
#endif
#endif
...
@@ -141,9 +131,9 @@ static bool IsWindowsAbsolutePath(const string& text) {
...
@@ -141,9 +131,9 @@ static bool IsWindowsAbsolutePath(const string& text) {
void
SetFdToTextMode
(
int
fd
)
{
void
SetFdToTextMode
(
int
fd
)
{
#ifdef _WIN32
#ifdef _WIN32
if
(
_
setmode
(
fd
,
_O_TEXT
)
==
-
1
)
{
if
(
setmode
(
fd
,
_O_TEXT
)
==
-
1
)
{
// This should never happen, I think.
// This should never happen, I think.
GOOGLE_LOG
(
WARNING
)
<<
"
_
setmode("
<<
fd
<<
", _O_TEXT): "
<<
strerror
(
errno
);
GOOGLE_LOG
(
WARNING
)
<<
"setmode("
<<
fd
<<
", _O_TEXT): "
<<
strerror
(
errno
);
}
}
#endif
#endif
// (Text and binary are the same on non-Windows platforms.)
// (Text and binary are the same on non-Windows platforms.)
...
@@ -151,9 +141,9 @@ void SetFdToTextMode(int fd) {
...
@@ -151,9 +141,9 @@ void SetFdToTextMode(int fd) {
void
SetFdToBinaryMode
(
int
fd
)
{
void
SetFdToBinaryMode
(
int
fd
)
{
#ifdef _WIN32
#ifdef _WIN32
if
(
_
setmode
(
fd
,
_O_BINARY
)
==
-
1
)
{
if
(
setmode
(
fd
,
_O_BINARY
)
==
-
1
)
{
// This should never happen, I think.
// This should never happen, I think.
GOOGLE_LOG
(
WARNING
)
<<
"
_
setmode("
<<
fd
<<
", _O_BINARY): "
<<
strerror
(
errno
);
GOOGLE_LOG
(
WARNING
)
<<
"setmode("
<<
fd
<<
", _O_BINARY): "
<<
strerror
(
errno
);
}
}
#endif
#endif
// (Text and binary are the same on non-Windows platforms.)
// (Text and binary are the same on non-Windows platforms.)
...
...
src/google/protobuf/compiler/command_line_interface_unittest.cc
View file @
f15185d3
...
@@ -35,9 +35,7 @@
...
@@ -35,9 +35,7 @@
#include <fcntl.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/types.h>
#ifdef _MSC_VER
#ifndef _MSC_VER
#include <io.h>
#else
#include <unistd.h>
#include <unistd.h>
#endif
#endif
#include <memory>
#include <memory>
...
@@ -65,27 +63,27 @@
...
@@ -65,27 +63,27 @@
#include <gtest/gtest.h>
#include <gtest/gtest.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/io_win32.h>
namespace
google
{
namespace
google
{
namespace
protobuf
{
namespace
protobuf
{
namespace
compiler
{
namespace
compiler
{
#if defined(_WIN32)
// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import
// them like we do below.
using
google
::
protobuf
::
internal
::
win32
::
access
;
using
google
::
protobuf
::
internal
::
win32
::
dup
;
using
google
::
protobuf
::
internal
::
win32
::
dup2
;
using
google
::
protobuf
::
internal
::
win32
::
close
;
using
google
::
protobuf
::
internal
::
win32
::
open
;
using
google
::
protobuf
::
internal
::
win32
::
write
;
#endif
// Disable the whole test when we use tcmalloc for "draconian" heap checks, in
// Disable the whole test when we use tcmalloc for "draconian" heap checks, in
// which case tcmalloc will print warnings that fail the plugin tests.
// which case tcmalloc will print warnings that fail the plugin tests.
#if !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN
#if !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN
#if defined(_WIN32)
#ifndef STDIN_FILENO
#define STDIN_FILENO 0
#endif
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
#ifndef F_OK
#define F_OK 00 // not defined by MSVC for whatever reason
#endif
#endif
namespace
{
namespace
{
bool
FileExists
(
const
string
&
path
)
{
bool
FileExists
(
const
string
&
path
)
{
...
...
src/google/protobuf/compiler/importer.cc
View file @
f15185d3
...
@@ -33,7 +33,7 @@
...
@@ -33,7 +33,7 @@
// Sanjay Ghemawat, Jeff Dean, and others.
// Sanjay Ghemawat, Jeff Dean, and others.
#ifdef _MSC_VER
#ifdef _MSC_VER
#include <
io
.h>
#include <
direct
.h>
#else
#else
#include <unistd.h>
#include <unistd.h>
#endif
#endif
...
@@ -53,19 +53,21 @@
...
@@ -53,19 +53,21 @@
#include <google/protobuf/compiler/parser.h>
#include <google/protobuf/compiler/parser.h>
#include <google/protobuf/io/tokenizer.h>
#include <google/protobuf/io/tokenizer.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/stubs/io_win32.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/strutil.h>
namespace
google
{
namespace
protobuf
{
namespace
compiler
{
#ifdef _WIN32
#ifdef _WIN32
#ifndef F_OK
#define F_OK 00 // not defined by MSVC for whatever reason
#endif
#include <ctype.h>
#include <ctype.h>
// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import
// them like we do below.
using
google
::
protobuf
::
internal
::
win32
::
access
;
using
google
::
protobuf
::
internal
::
win32
::
open
;
#endif
#endif
namespace
google
{
namespace
protobuf
{
namespace
compiler
{
// Returns true if the text looks like a Windows-style absolute path, starting
// Returns true if the text looks like a Windows-style absolute path, starting
// with a drive letter. Example: "C:\foo". TODO(kenton): Share this with
// with a drive letter. Example: "C:\foo". TODO(kenton): Share this with
// copy in command_line_interface.cc?
// copy in command_line_interface.cc?
...
...
src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
View file @
f15185d3
...
@@ -28,9 +28,7 @@
...
@@ -28,9 +28,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifdef _MSC_VER
#ifndef _MSC_VER
#include <io.h>
#else
#include <unistd.h>
#include <unistd.h>
#endif
#endif
#include <climits>
#include <climits>
...
@@ -49,8 +47,15 @@
...
@@ -49,8 +47,15 @@
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/io_win32.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/strutil.h>
#if defined(_WIN32)
// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import
// them like we do below.
using
google
::
protobuf
::
internal
::
win32
::
open
;
#endif
// NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
// NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
// error cases, so it seems to be ok to use as a back door for errors.
// error cases, so it seems to be ok to use as a back door for errors.
...
...
src/google/protobuf/compiler/plugin.cc
View file @
f15185d3
...
@@ -36,18 +36,12 @@
...
@@ -36,18 +36,12 @@
#include <set>
#include <set>
#ifdef _WIN32
#ifdef _WIN32
#include <io.h>
#include <fcntl.h>
#include <fcntl.h>
#ifndef STDIN_FILENO
#define STDIN_FILENO 0
#endif
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
#else
#else
#include <unistd.h>
#include <unistd.h>
#endif
#endif
#include <google/protobuf/stubs/io_win32.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/plugin.pb.h>
#include <google/protobuf/compiler/plugin.pb.h>
...
@@ -55,6 +49,11 @@
...
@@ -55,6 +49,11 @@
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#if defined(_WIN32)
// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import
// them like we do below.
using
google
::
protobuf
::
internal
::
win32
::
setmode
;
#endif
namespace
google
{
namespace
google
{
namespace
protobuf
{
namespace
protobuf
{
...
@@ -150,8 +149,8 @@ int PluginMain(int argc, char* argv[], const CodeGenerator* generator) {
...
@@ -150,8 +149,8 @@ int PluginMain(int argc, char* argv[], const CodeGenerator* generator) {
}
}
#ifdef _WIN32
#ifdef _WIN32
_
setmode
(
STDIN_FILENO
,
_O_BINARY
);
setmode
(
STDIN_FILENO
,
_O_BINARY
);
_
setmode
(
STDOUT_FILENO
,
_O_BINARY
);
setmode
(
STDOUT_FILENO
,
_O_BINARY
);
#endif
#endif
CodeGeneratorRequest
request
;
CodeGeneratorRequest
request
;
...
...
src/google/protobuf/io/zero_copy_stream_impl.cc
View file @
f15185d3
...
@@ -32,9 +32,7 @@
...
@@ -32,9 +32,7 @@
// Based on original Protocol Buffers design by
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Sanjay Ghemawat, Jeff Dean, and others.
#ifdef _MSC_VER
#ifndef _MSC_VER
#include <io.h>
#else
#include <unistd.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/stat.h>
...
@@ -43,9 +41,9 @@
...
@@ -43,9 +41,9 @@
#include <errno.h>
#include <errno.h>
#include <iostream>
#include <iostream>
#include <algorithm>
#include <algorithm>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/io_win32.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/stl_util.h>
#include <google/protobuf/stubs/stl_util.h>
...
@@ -58,6 +56,13 @@ namespace io {
...
@@ -58,6 +56,13 @@ namespace io {
// Win32 lseek is broken: If invoked on a non-seekable file descriptor, its
// Win32 lseek is broken: If invoked on a non-seekable file descriptor, its
// return value is undefined. We re-define it to always produce an error.
// return value is undefined. We re-define it to always produce an error.
#define lseek(fd, offset, origin) ((off_t)-1)
#define lseek(fd, offset, origin) ((off_t)-1)
// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import
// them like we do below.
using
google
::
protobuf
::
internal
::
win32
::
access
;
using
google
::
protobuf
::
internal
::
win32
::
close
;
using
google
::
protobuf
::
internal
::
win32
::
open
;
using
google
::
protobuf
::
internal
::
win32
::
read
;
using
google
::
protobuf
::
internal
::
win32
::
write
;
#endif
#endif
namespace
{
namespace
{
...
...
src/google/protobuf/io/zero_copy_stream_unittest.cc
View file @
f15185d3
...
@@ -47,9 +47,7 @@
...
@@ -47,9 +47,7 @@
// implementations.
// implementations.
#ifdef _MSC_VER
#ifndef _MSC_VER
#include <io.h>
#else
#include <unistd.h>
#include <unistd.h>
#endif
#endif
#include <stdlib.h>
#include <stdlib.h>
...
@@ -72,6 +70,7 @@
...
@@ -72,6 +70,7 @@
#endif
#endif
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/io_win32.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/testing/googletest.h>
#include <google/protobuf/testing/googletest.h>
#include <google/protobuf/testing/file.h>
#include <google/protobuf/testing/file.h>
...
@@ -84,6 +83,12 @@ namespace {
...
@@ -84,6 +83,12 @@ namespace {
#ifdef _WIN32
#ifdef _WIN32
#define pipe(fds) _pipe(fds, 4096, O_BINARY)
#define pipe(fds) _pipe(fds, 4096, O_BINARY)
// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import
// them like we do below.
using
google
::
protobuf
::
internal
::
win32
::
access
;
using
google
::
protobuf
::
internal
::
win32
::
mkdir
;
using
google
::
protobuf
::
internal
::
win32
::
open
;
using
google
::
protobuf
::
internal
::
win32
::
close
;
#endif
#endif
#ifndef O_BINARY
#ifndef O_BINARY
...
...
src/google/protobuf/message_unittest.cc
View file @
f15185d3
...
@@ -37,9 +37,7 @@
...
@@ -37,9 +37,7 @@
#include <sys/types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <fcntl.h>
#ifdef _MSC_VER
#ifndef _MSC_VER
#include <io.h>
#else
#include <unistd.h>
#include <unistd.h>
#endif
#endif
#include <sstream>
#include <sstream>
...
@@ -56,6 +54,7 @@
...
@@ -56,6 +54,7 @@
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/io_win32.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/testing/googletest.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
#include <gtest/gtest.h>
...
@@ -63,6 +62,13 @@
...
@@ -63,6 +62,13 @@
namespace
google
{
namespace
google
{
namespace
protobuf
{
namespace
protobuf
{
#if defined(_WIN32)
// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import
// them like we do below.
using
google
::
protobuf
::
internal
::
win32
::
close
;
using
google
::
protobuf
::
internal
::
win32
::
open
;
#endif
#ifndef O_BINARY
#ifndef O_BINARY
#ifdef _O_BINARY
#ifdef _O_BINARY
#define O_BINARY _O_BINARY
#define O_BINARY _O_BINARY
...
...
src/google/protobuf/stubs/io_win32.cc
0 → 100644
View file @
f15185d3
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: laszlocsomor@google.com (Laszlo Csomor)
//
// Implementation for long-path-aware open/mkdir/etc. on Windows.
//
// These functions convert the input path to an absolute Windows path
// with "\\?\" prefix if necessary, then pass that to _wopen/_wmkdir/etc.
// (declared in <io.h>) respectively. This allows working with files/directories
// whose paths are longer than MAX_PATH (260 chars).
//
// This file is only used on Windows, it's empty on other platforms.
#if defined(_WIN32)
// Comment this out to fall back to using the ANSI versions (open, mkdir, ...)
// instead of the Unicode ones (_wopen, _wmkdir, ...). Doing so can be useful to
// debug failing tests if that's caused by the long path support.
#define SUPPORT_LONGPATHS
#include <ctype.h>
#include <direct.h>
#include <errno.h>
#include <fcntl.h>
#include <io.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <wctype.h>
#include <windows.h>
#include <google/protobuf/stubs/io_win32.h>
#include <cassert>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
namespace
google
{
namespace
protobuf
{
namespace
internal
{
namespace
win32
{
namespace
{
using
std
::
string
;
using
std
::
unique_ptr
;
using
std
::
wstring
;
template
<
typename
char_type
>
struct
CharTraits
{
static
bool
is_alpha
(
char_type
ch
);
};
template
<>
struct
CharTraits
<
char
>
{
static
bool
is_alpha
(
char
ch
)
{
return
isalpha
(
ch
);
}
};
template
<>
struct
CharTraits
<
wchar_t
>
{
static
bool
is_alpha
(
wchar_t
ch
)
{
return
iswalpha
(
ch
);
}
};
// Returns true if the path starts with a drive letter, e.g. "c:".
// Note that this won't check for the "\" after the drive letter, so this also
// returns true for "c:foo" (which is "c:\${PWD}\foo").
// This check requires that a path not have a longpath prefix ("\\?\").
template
<
typename
char_type
>
bool
has_drive_letter
(
const
char_type
*
ch
)
{
return
CharTraits
<
char_type
>::
is_alpha
(
ch
[
0
])
&&
ch
[
1
]
==
':'
;
}
// Returns true if the path starts with a longpath prefix ("\\?\").
template
<
typename
char_type
>
bool
has_longpath_prefix
(
const
char_type
*
path
)
{
return
path
[
0
]
==
'\\'
&&
path
[
1
]
==
'\\'
&&
path
[
2
]
==
'?'
&&
path
[
3
]
==
'\\'
;
}
// Returns true if the path starts with a drive specifier (e.g. "c:\").
template
<
typename
char_type
>
bool
is_path_absolute
(
const
char_type
*
path
)
{
return
has_drive_letter
(
path
)
&&
is_separator
(
path
[
2
]);
}
template
<
typename
char_type
>
bool
is_separator
(
char_type
c
)
{
return
c
==
'/'
||
c
==
'\\'
;
}
template
<
typename
char_type
>
bool
is_drive_relative
(
const
char_type
*
path
)
{
return
has_drive_letter
(
path
)
&&
(
path
[
2
]
==
0
||
!
is_separator
(
path
[
2
]));
}
template
<
typename
char_type
>
void
replace_directory_separators
(
char_type
*
p
)
{
for
(;
*
p
;
++
p
)
{
if
(
*
p
==
'/'
)
{
*
p
=
'\\'
;
}
}
}
string
join_paths
(
const
string
&
path1
,
const
string
&
path2
)
{
if
(
path1
.
empty
()
||
is_path_absolute
(
path2
.
c_str
())
||
has_longpath_prefix
(
path2
.
c_str
()))
{
return
path2
;
}
if
(
path2
.
empty
())
{
return
path1
;
}
if
(
is_separator
(
path1
.
back
()))
{
return
is_separator
(
path2
.
front
())
?
(
path1
+
path2
.
substr
(
1
))
:
(
path1
+
path2
);
}
else
{
return
is_separator
(
path2
.
front
())
?
(
path1
+
path2
)
:
(
path1
+
'\\'
+
path2
);
}
}
string
normalize
(
string
path
)
{
if
(
has_longpath_prefix
(
path
.
c_str
()))
{
path
=
path
.
substr
(
4
);
}
static
const
string
dot
(
"."
);
static
const
string
dotdot
(
".."
);
std
::
vector
<
string
>
segments
;
int
segment_start
=
-
1
;
// Find the path segments in `path` (separated by "/").
for
(
int
i
=
0
;;
++
i
)
{
if
(
!
is_separator
(
path
[
i
])
&&
path
[
i
]
!=
'\0'
)
{
// The current character does not end a segment, so start one unless it's
// already started.
if
(
segment_start
<
0
)
{
segment_start
=
i
;
}
}
else
if
(
segment_start
>=
0
&&
i
>
segment_start
)
{
// The current character is "/" or "\0", so this ends a segment.
// Add that to `segments` if there's anything to add; handle "." and "..".
string
segment
(
path
,
segment_start
,
i
-
segment_start
);
segment_start
=
-
1
;
if
(
segment
==
dotdot
)
{
if
(
!
segments
.
empty
()
&&
(
!
has_drive_letter
(
segments
[
0
].
c_str
())
||
segments
.
size
()
>
1
))
{
segments
.
pop_back
();
}
}
else
if
(
segment
!=
dot
&&
!
segment
.
empty
())
{
segments
.
push_back
(
segment
);
}
}
if
(
path
[
i
]
==
'\0'
)
{
break
;
}
}
// Handle the case when `path` is just a drive specifier (or some degenerate
// form of it, e.g. "c:\..").
if
(
segments
.
size
()
==
1
&&
segments
[
0
].
size
()
==
2
&&
has_drive_letter
(
segments
[
0
].
c_str
()))
{
return
segments
[
0
]
+
'\\'
;
}
// Join all segments.
bool
first
=
true
;
std
::
ostringstream
result
;
for
(
const
auto
&
s
:
segments
)
{
if
(
!
first
)
{
result
<<
'\\'
;
}
first
=
false
;
result
<<
s
;
}
// Preserve trailing separator if the input contained it.
if
(
is_separator
(
path
.
back
()))
{
result
<<
'\\'
;
}
return
result
.
str
();
}
std
::
unique_ptr
<
WCHAR
[]
>
as_wstring
(
const
string
&
s
)
{
int
len
=
::
MultiByteToWideChar
(
CP_UTF8
,
0
,
s
.
c_str
(),
s
.
size
(),
NULL
,
0
);
std
::
unique_ptr
<
WCHAR
[]
>
result
(
new
WCHAR
[
len
+
1
]);
::
MultiByteToWideChar
(
CP_UTF8
,
0
,
s
.
c_str
(),
s
.
size
(),
result
.
get
(),
len
+
1
);
result
.
get
()[
len
]
=
0
;
return
std
::
move
(
result
);
}
wstring
as_wchar_path
(
const
string
&
path
)
{
std
::
unique_ptr
<
WCHAR
[]
>
wbuf
(
as_wstring
(
path
));
replace_directory_separators
(
wbuf
.
get
());
return
wstring
(
wbuf
.
get
());
}
bool
as_windows_path
(
const
string
&
path
,
wstring
*
result
)
{
if
(
path
.
empty
())
{
result
->
clear
();
return
true
;
}
if
(
is_separator
(
path
[
0
])
||
is_drive_relative
(
path
.
c_str
()))
{
return
false
;
}
string
mutable_path
=
path
;
if
(
!
is_path_absolute
(
mutable_path
.
c_str
())
&&
!
has_longpath_prefix
(
mutable_path
.
c_str
()))
{
char
cwd
[
MAX_PATH
];
::
GetCurrentDirectoryA
(
MAX_PATH
,
cwd
);
mutable_path
=
join_paths
(
cwd
,
mutable_path
);
}
*
result
=
as_wchar_path
(
normalize
(
mutable_path
));
if
(
!
has_longpath_prefix
(
result
->
c_str
()))
{
// Add the "\\?\" prefix unconditionally. This way we prevent the Win32 API
// from processing the path and "helpfully" removing trailing dots from the
// path, for example.
// See https://github.com/bazelbuild/bazel/issues/2935
*
result
=
wstring
(
L"
\\\\
?
\\
"
)
+
*
result
;
}
return
true
;
}
}
// namespace
int
open
(
const
char
*
path
,
int
flags
,
int
mode
)
{
#ifdef SUPPORT_LONGPATHS
wstring
wpath
;
if
(
!
as_windows_path
(
path
,
&
wpath
))
{
errno
=
ENOENT
;
return
-
1
;
}
return
::
_wopen
(
wpath
.
c_str
(),
flags
,
mode
);
#else
return
::
_open
(
path
,
flags
,
mode
);
#endif
}
int
mkdir
(
const
char
*
path
,
int
_mode
)
{
#ifdef SUPPORT_LONGPATHS
wstring
wpath
;
if
(
!
as_windows_path
(
path
,
&
wpath
))
{
errno
=
ENOENT
;
return
-
1
;
}
return
::
_wmkdir
(
wpath
.
c_str
());
#else // not SUPPORT_LONGPATHS
return
::
_mkdir
(
path
);
#endif // not SUPPORT_LONGPATHS
}
int
access
(
const
char
*
path
,
int
mode
)
{
#ifdef SUPPORT_LONGPATHS
wstring
wpath
;
if
(
!
as_windows_path
(
path
,
&
wpath
))
{
errno
=
ENOENT
;
return
-
1
;
}
return
::
_waccess
(
wpath
.
c_str
(),
mode
);
#else
return
::
_access
(
path
,
mode
);
#endif
}
int
chdir
(
const
char
*
path
)
{
#ifdef SUPPORT_LONGPATHS
wstring
wpath
;
if
(
!
as_windows_path
(
path
,
&
wpath
))
{
errno
=
ENOENT
;
return
-
1
;
}
return
::
_wchdir
(
wpath
.
c_str
());
#else
return
::
_chdir
(
path
);
#endif
}
int
stat
(
const
char
*
path
,
struct
_stat
*
buffer
)
{
#ifdef SUPPORT_LONGPATHS
wstring
wpath
;
if
(
!
as_windows_path
(
path
,
&
wpath
))
{
errno
=
ENOENT
;
return
-
1
;
}
return
::
_wstat
(
wpath
.
c_str
(),
buffer
);
#else // not SUPPORT_LONGPATHS
return
::
_stat
(
path
,
buffer
);
#endif // not SUPPORT_LONGPATHS
}
FILE
*
fopen
(
const
char
*
path
,
const
char
*
mode
)
{
#ifdef SUPPORT_LONGPATHS
wstring
wpath
;
if
(
!
as_windows_path
(
path
,
&
wpath
))
{
errno
=
ENOENT
;
return
NULL
;
}
std
::
unique_ptr
<
WCHAR
[]
>
wmode
(
as_wstring
(
mode
));
return
::
_wfopen
(
wpath
.
c_str
(),
wmode
.
get
());
#else
return
::
fopen
(
path
,
mode
);
#endif
}
int
close
(
int
fd
)
{
return
::
close
(
fd
);
}
int
dup
(
int
fd
)
{
return
::
_dup
(
fd
);
}
int
dup2
(
int
fd1
,
int
fd2
)
{
return
::
_dup2
(
fd1
,
fd2
);
}
int
read
(
int
fd
,
void
*
buffer
,
size_t
size
)
{
return
::
_read
(
fd
,
buffer
,
size
);
}
int
setmode
(
int
fd
,
int
mode
)
{
return
::
_setmode
(
fd
,
mode
);
}
int
write
(
int
fd
,
const
void
*
buffer
,
size_t
size
)
{
return
::
_write
(
fd
,
buffer
,
size
);
}
wstring
testonly_path_to_winpath
(
const
string
&
path
)
{
wstring
wpath
;
as_windows_path
(
path
,
&
wpath
);
return
wpath
;
}
}
// namespace win32
}
// namespace internal
}
// namespace protobuf
}
// namespace google
#endif // defined(_WIN32)
src/google/protobuf/stubs/io_win32.h
0 → 100644
View file @
f15185d3
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: laszlocsomor@google.com (Laszlo Csomor)
//
// This file contains the declarations for Windows implementations of
// commonly used POSIX functions such as open(2) and access(2), as well
// as macro definitions for flags of these functions.
//
// By including this file you'll redefine open/access/etc. to
// ::google::protobuf::internal::win32::{open/access/etc.}.
// Make sure you don't include a header that attempts to redeclare or
// redefine these functions, that'll lead to confusing compilation
// errors. It's best to #include this file as the last one to ensure that.
//
// This file is only used on Windows, it's empty on other platforms.
#ifndef GOOGLE_PROTOBUF_STUBS_IO_WIN32_H__
#define GOOGLE_PROTOBUF_STUBS_IO_WIN32_H__
#if defined(_WIN32)
#include <string>
namespace
google
{
namespace
protobuf
{
namespace
internal
{
namespace
win32
{
FILE
*
fopen
(
const
char
*
path
,
const
char
*
mode
);
int
access
(
const
char
*
path
,
int
mode
);
int
chdir
(
const
char
*
path
);
int
close
(
int
fd
);
int
dup
(
int
fd
);
int
dup2
(
int
fd1
,
int
fd2
);
int
mkdir
(
const
char
*
path
,
int
_mode
);
int
open
(
const
char
*
path
,
int
flags
,
int
mode
=
0
);
int
read
(
int
fd
,
void
*
buffer
,
size_t
size
);
int
setmode
(
int
fd
,
int
mode
);
int
stat
(
const
char
*
path
,
struct
_stat
*
buffer
);
int
write
(
int
fd
,
const
void
*
buffer
,
size_t
size
);
std
::
wstring
testonly_path_to_winpath
(
const
std
::
string
&
path
);
}
// namespace win32
}
// namespace internal
}
// namespace protobuf
}
// namespace google
#ifndef W_OK
#define W_OK 02 // not defined by MSVC for whatever reason
#endif
#ifndef F_OK
#define F_OK 00 // not defined by MSVC for whatever reason
#endif
#ifndef STDIN_FILENO
#define STDIN_FILENO 0
#endif
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
#endif // defined(_WIN32)
#endif // GOOGLE_PROTOBUF_STUBS_IO_WIN32_H__
src/google/protobuf/stubs/io_win32_unittest.cc
0 → 100644
View file @
f15185d3
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: laszlocsomor@google.com (Laszlo Csomor)
//
// Unit tests for long-path-aware open/mkdir/access on Windows.
//
// This file is only used on Windows, it's empty on other platforms.
#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <wchar.h>
#include <windows.h>
#include <google/protobuf/stubs/io_win32.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
#include <memory>
#include <sstream>
#include <string>
namespace
google
{
namespace
protobuf
{
namespace
internal
{
namespace
win32
{
namespace
{
using
std
::
string
;
using
std
::
unique_ptr
;
using
std
::
wstring
;
class
IoWin32Test
:
public
::
testing
::
Test
{
public
:
void
SetUp
()
override
;
void
TearDown
()
override
;
protected
:
bool
CreateAllUnder
(
wstring
path
);
bool
DeleteAllUnder
(
wstring
path
);
string
test_tmpdir
;
wstring
wtest_tmpdir
;
};
#define ASSERT_INITIALIZED \
{ \
EXPECT_FALSE(test_tmpdir.empty()); \
EXPECT_FALSE(wtest_tmpdir.empty()); \
}
void
IoWin32Test
::
SetUp
()
{
test_tmpdir
=
string
(
TestTempDir
());
wtest_tmpdir
.
clear
();
if
(
test_tmpdir
.
empty
())
{
const
char
*
test_tmpdir_env
=
getenv
(
"TEST_TMPDIR"
);
if
(
test_tmpdir_env
!=
nullptr
&&
*
test_tmpdir_env
)
{
test_tmpdir
=
string
(
test_tmpdir_env
);
}
// Only Bazel defines TEST_TMPDIR, CMake does not, so look for other
// suitable environment variables.
if
(
test_tmpdir
.
empty
())
{
for
(
const
char
*
name
:
{
"TEMP"
,
"TMP"
})
{
test_tmpdir_env
=
getenv
(
name
);
if
(
test_tmpdir_env
!=
nullptr
&&
*
test_tmpdir_env
)
{
test_tmpdir
=
string
(
test_tmpdir_env
);
break
;
}
}
}
// No other temp directory was found. Use the current director
if
(
test_tmpdir
.
empty
())
{
char
buffer
[
MAX_PATH
];
// Use GetCurrentDirectoryA instead of GetCurrentDirectoryW, because the
// current working directory must always be shorter than MAX_PATH, even
// with
// "\\?\" prefix (except on Windows 10 version 1607 and beyond, after
// opting in to long paths by default [1]).
//
// [1] https://msdn.microsoft.com/en-us/library/windows/ \
// desktop/aa365247(v=vs.85).aspx#maxpath
DWORD
result
=
::
GetCurrentDirectoryA
(
MAX_PATH
,
buffer
);
if
(
result
>
0
)
{
test_tmpdir
=
string
(
buffer
);
}
else
{
// Using assertions in SetUp/TearDown seems to confuse the test
// framework, so just leave the member variables empty in case of
// failure.
GOOGLE_CHECK_OK
(
false
);
return
;
}
}
}
while
(
test_tmpdir
.
back
()
==
'/'
||
test_tmpdir
.
back
()
==
'\\'
)
{
test_tmpdir
.
pop_back
();
}
test_tmpdir
+=
"
\\
io_win32_unittest.tmp"
;
// CreateDirectoryA's limit is 248 chars, see MSDN.
// https://msdn.microsoft.com/en-us/library/windows/ \
// desktop/aa363855(v=vs.85).aspx
wtest_tmpdir
=
testonly_path_to_winpath
(
test_tmpdir
);
if
(
!
DeleteAllUnder
(
wtest_tmpdir
)
||
!
CreateAllUnder
(
wtest_tmpdir
))
{
GOOGLE_CHECK_OK
(
false
);
test_tmpdir
.
clear
();
wtest_tmpdir
.
clear
();
}
}
void
IoWin32Test
::
TearDown
()
{
if
(
!
wtest_tmpdir
.
empty
())
{
DeleteAllUnder
(
wtest_tmpdir
);
}
}
bool
IoWin32Test
::
CreateAllUnder
(
wstring
path
)
{
// Prepend UNC prefix if the path doesn't have it already. Don't bother
// checking if the path is shorter than MAX_PATH, let's just do it
// unconditionally.
if
(
path
.
find
(
L"
\\\\
?
\\
"
)
!=
0
)
{
path
=
wstring
(
L"
\\\\
?
\\
"
)
+
path
;
}
if
(
::
CreateDirectoryW
(
path
.
c_str
(),
NULL
)
||
GetLastError
()
==
ERROR_ALREADY_EXISTS
||
GetLastError
()
==
ERROR_ACCESS_DENIED
)
{
return
true
;
}
if
(
GetLastError
()
==
ERROR_PATH_NOT_FOUND
)
{
size_t
pos
=
path
.
find_last_of
(
L'\\'
);
if
(
pos
!=
wstring
::
npos
)
{
wstring
parent
(
path
,
0
,
pos
);
if
(
CreateAllUnder
(
parent
)
&&
CreateDirectoryW
(
path
.
c_str
(),
NULL
))
{
return
true
;
}
}
}
return
false
;
}
bool
IoWin32Test
::
DeleteAllUnder
(
wstring
path
)
{
static
const
wstring
kDot
(
L"."
);
static
const
wstring
kDotDot
(
L".."
);
// Prepend UNC prefix if the path doesn't have it already. Don't bother
// checking if the path is shorter than MAX_PATH, let's just do it
// unconditionally.
if
(
path
.
find
(
L"
\\\\
?
\\
"
)
!=
0
)
{
path
=
wstring
(
L"
\\\\
?
\\
"
)
+
path
;
}
// Append "\" if necessary.
if
(
path
.
back
()
!=
'\\'
)
{
path
.
push_back
(
'\\'
);
}
WIN32_FIND_DATAW
metadata
;
HANDLE
handle
=
::
FindFirstFileW
((
path
+
L"*"
).
c_str
(),
&
metadata
);
if
(
handle
==
INVALID_HANDLE_VALUE
)
{
return
true
;
// directory doesn't exist
}
bool
result
=
true
;
do
{
wstring
childname
=
metadata
.
cFileName
;
if
(
kDot
!=
childname
&&
kDotDot
!=
childname
)
{
wstring
childpath
=
path
+
childname
;
if
((
metadata
.
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
)
!=
0
)
{
// If this is not a junction, delete its contents recursively.
// Finally delete this directory/junction too.
if
(((
metadata
.
dwFileAttributes
&
FILE_ATTRIBUTE_REPARSE_POINT
)
==
0
&&
!
DeleteAllUnder
(
childpath
))
||
!::
RemoveDirectoryW
(
childpath
.
c_str
()))
{
result
=
false
;
break
;
}
}
else
{
if
(
!::
DeleteFileW
(
childpath
.
c_str
()))
{
result
=
false
;
break
;
}
}
}
}
while
(
::
FindNextFileW
(
handle
,
&
metadata
));
::
FindClose
(
handle
);
return
result
;
}
TEST_F
(
IoWin32Test
,
AccessTest
)
{
ASSERT_INITIALIZED
;
string
path
=
test_tmpdir
;
while
(
path
.
size
()
<
MAX_PATH
-
30
)
{
path
+=
"
\\
accesstest"
;
EXPECT_EQ
(
mkdir
(
path
.
c_str
(),
0644
),
0
);
}
string
file
=
path
+
"
\\
file.txt"
;
int
fd
=
open
(
file
.
c_str
(),
O_CREAT
|
O_WRONLY
,
0644
);
if
(
fd
>
0
)
{
EXPECT_EQ
(
close
(
fd
),
0
);
}
else
{
EXPECT_TRUE
(
false
);
}
EXPECT_EQ
(
access
(
test_tmpdir
.
c_str
(),
F_OK
),
0
);
EXPECT_EQ
(
access
(
path
.
c_str
(),
F_OK
),
0
);
EXPECT_EQ
(
access
(
path
.
c_str
(),
W_OK
),
0
);
EXPECT_EQ
(
access
(
file
.
c_str
(),
F_OK
|
W_OK
),
0
);
EXPECT_NE
(
access
((
file
+
".blah"
).
c_str
(),
F_OK
),
0
);
EXPECT_NE
(
access
((
file
+
".blah"
).
c_str
(),
W_OK
),
0
);
EXPECT_EQ
(
access
(
"."
,
F_OK
),
0
);
EXPECT_EQ
(
access
(
"."
,
W_OK
),
0
);
EXPECT_EQ
(
access
((
test_tmpdir
+
"/accesstest"
).
c_str
(),
F_OK
|
W_OK
),
0
);
ASSERT_EQ
(
access
((
test_tmpdir
+
"/./normalize_me/.././accesstest"
).
c_str
(),
F_OK
|
W_OK
),
0
);
EXPECT_NE
(
access
(
"io_win32_unittest.AccessTest.nonexistent"
,
F_OK
),
0
);
EXPECT_NE
(
access
(
"io_win32_unittest.AccessTest.nonexistent"
,
W_OK
),
0
);
ASSERT_EQ
(
access
(
"c:bad"
,
F_OK
),
-
1
);
ASSERT_EQ
(
errno
,
ENOENT
);
ASSERT_EQ
(
access
(
"/tmp/bad"
,
F_OK
),
-
1
);
ASSERT_EQ
(
errno
,
ENOENT
);
ASSERT_EQ
(
access
(
"
\\
bad"
,
F_OK
),
-
1
);
ASSERT_EQ
(
errno
,
ENOENT
);
}
TEST_F
(
IoWin32Test
,
OpenTest
)
{
ASSERT_INITIALIZED
;
string
path
=
test_tmpdir
;
while
(
path
.
size
()
<
MAX_PATH
)
{
path
+=
"
\\
opentest"
;
EXPECT_EQ
(
mkdir
(
path
.
c_str
(),
0644
),
0
);
}
string
file
=
path
+
"
\\
file.txt"
;
int
fd
=
open
(
file
.
c_str
(),
O_CREAT
|
O_WRONLY
,
0644
);
if
(
fd
>
0
)
{
EXPECT_EQ
(
write
(
fd
,
"hello"
,
5
),
5
);
EXPECT_EQ
(
close
(
fd
),
0
);
}
else
{
EXPECT_TRUE
(
false
);
}
ASSERT_EQ
(
open
(
"c:bad.txt"
,
O_CREAT
|
O_WRONLY
,
0644
),
-
1
);
ASSERT_EQ
(
errno
,
ENOENT
);
ASSERT_EQ
(
open
(
"/tmp/bad.txt"
,
O_CREAT
|
O_WRONLY
,
0644
),
-
1
);
ASSERT_EQ
(
errno
,
ENOENT
);
ASSERT_EQ
(
open
(
"
\\
bad.txt"
,
O_CREAT
|
O_WRONLY
,
0644
),
-
1
);
ASSERT_EQ
(
errno
,
ENOENT
);
}
TEST_F
(
IoWin32Test
,
MkdirTest
)
{
ASSERT_INITIALIZED
;
string
path
=
test_tmpdir
;
do
{
path
+=
"
\\
mkdirtest"
;
ASSERT_EQ
(
mkdir
(
path
.
c_str
(),
0644
),
0
);
}
while
(
path
.
size
()
<=
MAX_PATH
);
ASSERT_EQ
(
mkdir
(
"c:bad"
,
0644
),
-
1
);
ASSERT_EQ
(
errno
,
ENOENT
);
ASSERT_EQ
(
mkdir
(
"/tmp/bad"
,
0644
),
-
1
);
ASSERT_EQ
(
errno
,
ENOENT
);
ASSERT_EQ
(
mkdir
(
"
\\
bad"
,
0644
),
-
1
);
ASSERT_EQ
(
errno
,
ENOENT
);
}
TEST_F
(
IoWin32Test
,
ChdirTest
)
{
char
owd
[
MAX_PATH
];
EXPECT_GT
(
::
GetCurrentDirectoryA
(
MAX_PATH
,
owd
),
0
);
string
path
(
"C:
\\
"
);
EXPECT_EQ
(
access
(
path
.
c_str
(),
F_OK
),
0
);
ASSERT_EQ
(
chdir
(
path
.
c_str
()),
0
);
EXPECT_TRUE
(
::
SetCurrentDirectoryA
(
owd
));
// Do not try to chdir into the test_tmpdir, it may already contain directory
// names with trailing dots.
// Instead test here with an obviously dot-trailed path. If the win32_chdir
// function would not convert the path to absolute and prefix with "\\?\" then
// the Win32 API would ignore the trailing dot, but because of the prefixing
// there'll be no path processing done, so we'll actually attempt to chdir
// into "C:\some\path\foo."
path
=
test_tmpdir
+
"/foo."
;
EXPECT_EQ
(
mkdir
(
path
.
c_str
(),
644
),
0
);
EXPECT_EQ
(
access
(
path
.
c_str
(),
F_OK
),
0
);
ASSERT_NE
(
chdir
(
path
.
c_str
()),
0
);
}
TEST_F
(
IoWin32Test
,
AsWindowsPathTest
)
{
DWORD
size
=
GetCurrentDirectoryW
(
0
,
NULL
);
unique_ptr
<
wchar_t
[]
>
cwd_str
(
new
wchar_t
[
size
]);
EXPECT_GT
(
GetCurrentDirectoryW
(
size
,
cwd_str
.
get
()),
0
);
wstring
cwd
=
wstring
(
L"
\\\\
?
\\
"
)
+
cwd_str
.
get
();
ASSERT_EQ
(
testonly_path_to_winpath
(
"relative_mkdirtest"
),
cwd
+
L"
\\
relative_mkdirtest"
);
ASSERT_EQ
(
testonly_path_to_winpath
(
"preserve//
\\
trailing///"
),
cwd
+
L"
\\
preserve
\\
trailing
\\
"
);
ASSERT_EQ
(
testonly_path_to_winpath
(
"./normalize_me
\\
/../blah"
),
cwd
+
L"
\\
blah"
);
std
::
ostringstream
relpath
;
for
(
wchar_t
*
p
=
cwd_str
.
get
();
*
p
;
++
p
)
{
if
(
*
p
==
'/'
||
*
p
==
'\\'
)
{
relpath
<<
"../"
;
}
}
relpath
<<
".
\\
/../
\\
./beyond-toplevel"
;
ASSERT_EQ
(
testonly_path_to_winpath
(
relpath
.
str
()),
wstring
(
L"
\\\\
?
\\
"
)
+
cwd_str
.
get
()[
0
]
+
L":
\\
beyond-toplevel"
);
// Absolute unix paths lack drive letters, driveless absolute windows paths
// do too. Neither can be converted to a drive-specifying absolute Windows
// path.
ASSERT_EQ
(
testonly_path_to_winpath
(
"/absolute/unix/path"
),
L""
);
// Though valid on Windows, we also don't support UNC paths (\\UNC\\blah).
ASSERT_EQ
(
testonly_path_to_winpath
(
"
\\
driveless
\\
absolute"
),
L""
);
// Though valid in cmd.exe, drive-relative paths are not supported.
ASSERT_EQ
(
testonly_path_to_winpath
(
"c:foo"
),
L""
);
ASSERT_EQ
(
testonly_path_to_winpath
(
"c:/foo"
),
L"
\\\\
?
\\
c:
\\
foo"
);
}
}
// namespace
}
// namespace win32
}
// namespace internal
}
// namespace protobuf
}
// namespace google
#endif // defined(_WIN32)
src/google/protobuf/testing/file.cc
View file @
f15185d3
...
@@ -38,24 +38,28 @@
...
@@ -38,24 +38,28 @@
#ifdef _MSC_VER
#ifdef _MSC_VER
#define WIN32_LEAN_AND_MEAN // yeah, right
#define WIN32_LEAN_AND_MEAN // yeah, right
#include <windows.h> // Find*File(). :(
#include <windows.h> // Find*File(). :(
#include <io.h>
// #include <direct.h>
#include <direct.h>
#else
#else
#include <dirent.h>
#include <dirent.h>
#include <unistd.h>
#include <unistd.h>
#endif
#endif
#include <errno.h>
#include <errno.h>
#include <google/protobuf/stubs/io_win32.h>
namespace
google
{
namespace
google
{
namespace
protobuf
{
namespace
protobuf
{
#ifdef _WIN32
#ifdef _WIN32
#define mkdir(name, mode) mkdir(name)
// Windows doesn't have symbolic links.
// Windows doesn't have symbolic links.
#define lstat stat
#define lstat stat
#ifndef F_OK
// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import
#define F_OK 00 // not defined by MSVC for whatever reason
// them like we do below.
#endif
using
google
::
protobuf
::
internal
::
win32
::
access
;
using
google
::
protobuf
::
internal
::
win32
::
chdir
;
using
google
::
protobuf
::
internal
::
win32
::
fopen
;
using
google
::
protobuf
::
internal
::
win32
::
mkdir
;
using
google
::
protobuf
::
internal
::
win32
::
stat
;
#endif
#endif
bool
File
::
Exists
(
const
string
&
name
)
{
bool
File
::
Exists
(
const
string
&
name
)
{
...
@@ -113,6 +117,9 @@ void File::WriteStringToFileOrDie(const string& contents, const string& name) {
...
@@ -113,6 +117,9 @@ void File::WriteStringToFileOrDie(const string& contents, const string& name) {
}
}
bool
File
::
CreateDir
(
const
string
&
name
,
int
mode
)
{
bool
File
::
CreateDir
(
const
string
&
name
,
int
mode
)
{
if
(
!
name
.
empty
())
{
GOOGLE_CHECK_OK
(
name
.
back
()
!=
'.'
);
}
return
mkdir
(
name
.
c_str
(),
mode
)
==
0
;
return
mkdir
(
name
.
c_str
(),
mode
)
==
0
;
}
}
...
...
src/google/protobuf/testing/googletest.cc
View file @
f15185d3
...
@@ -33,14 +33,14 @@
...
@@ -33,14 +33,14 @@
#include <google/protobuf/testing/googletest.h>
#include <google/protobuf/testing/googletest.h>
#include <google/protobuf/testing/file.h>
#include <google/protobuf/testing/file.h>
#include <google/protobuf/stubs/io_win32.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/strutil.h>
#include <sys/stat.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/types.h>
#include <errno.h>
#include <errno.h>
#include <stdlib.h>
#include <stdlib.h>
#ifdef _MSC_VER
#ifdef _MSC_VER
#include <io.h>
// #include <direct.h>
#include <direct.h>
#else
#else
#include <unistd.h>
#include <unistd.h>
#endif
#endif
...
@@ -53,7 +53,13 @@ namespace google {
...
@@ -53,7 +53,13 @@ namespace google {
namespace
protobuf
{
namespace
protobuf
{
#ifdef _WIN32
#ifdef _WIN32
#define mkdir(name, mode) mkdir(name)
// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import
// them like we do below.
using
google
::
protobuf
::
internal
::
win32
::
close
;
using
google
::
protobuf
::
internal
::
win32
::
dup2
;
using
google
::
protobuf
::
internal
::
win32
::
dup
;
using
google
::
protobuf
::
internal
::
win32
::
mkdir
;
using
google
::
protobuf
::
internal
::
win32
::
open
;
#endif
#endif
#ifndef O_BINARY
#ifndef O_BINARY
...
@@ -111,14 +117,32 @@ string GetTemporaryDirectoryName() {
...
@@ -111,14 +117,32 @@ string GetTemporaryDirectoryName() {
char
b
[
L_tmpnam
+
1
];
// HPUX multithread return 0 if s is 0
char
b
[
L_tmpnam
+
1
];
// HPUX multithread return 0 if s is 0
string
result
=
tmpnam
(
b
);
string
result
=
tmpnam
(
b
);
#ifdef _WIN32
#ifdef _WIN32
// Avoid a trailing dot by changing it to an underscore. On Win32 the names of
// files and directories can, but should not, end with dot.
//
// In MS-DOS and FAT16 filesystem the filenames were 8dot3 style so it didn't
// make sense to have a name ending in dot without an extension, so the shell
// silently ignored trailing dots. To this day the Win32 API still maintains
// this behavior and silently ignores trailing dots in path arguments of
// functions such as CreateFile{A,W}. Even POSIX API function implementations
// seem to wrap the Win32 API functions (e.g. CreateDirectoryA) and behave
// this way.
// It's possible to avoid this behavior and create files / directories with
// trailing dots (using CreateFileW / CreateDirectoryW and prefixing the path
// with "\\?\") but these will be degenerate in the sense that you cannot
// chdir into such directories (or navigate into them with Windows Explorer)
// nor can you open such files with some programs (e.g. Notepad).
if
(
result
.
back
()
==
'.'
)
{
result
[
result
.
size
()
-
1
]
=
'_'
;
}
// On Win32, tmpnam() returns a file prefixed with '\', but which is supposed
// On Win32, tmpnam() returns a file prefixed with '\', but which is supposed
// to be used in the current working directory. WTF?
// to be used in the current working directory. WTF?
if
(
HasPrefixString
(
result
,
"
\\
"
))
{
if
(
HasPrefixString
(
result
,
"
\\
"
))
{
result
.
erase
(
0
,
1
);
result
.
erase
(
0
,
1
);
}
}
// The Win32 API accepts forward slashes as a path delimiter
even though
// The Win32 API accepts forward slashes as a path delimiter
as long as the
//
backslashes are standard. Let's avoid confusion and use only forward
//
path doesn't use the "\\?\" prefix.
// slashes.
//
Let's avoid confusion and use only forward
slashes.
result
=
StringReplace
(
result
,
"
\\
"
,
"/"
,
true
);
result
=
StringReplace
(
result
,
"
\\
"
,
"/"
,
true
);
#endif // _WIN32
#endif // _WIN32
return
result
;
return
result
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment