| Index: ppapi/tests/test_file_io.cc
|
| diff --git a/ppapi/tests/test_file_io.cc b/ppapi/tests/test_file_io.cc
|
| index 29348a634c5a719a083db3a659a501243b7797ca..b9cfe5f0615e07b2dab47954b46463223c4394e7 100644
|
| --- a/ppapi/tests/test_file_io.cc
|
| +++ b/ppapi/tests/test_file_io.cc
|
| @@ -4,22 +4,41 @@
|
|
|
| #include "ppapi/tests/test_file_io.h"
|
|
|
| +#include <errno.h>
|
| +#include <fcntl.h>
|
| #include <string.h>
|
| +#include <sys/stat.h>
|
| +#include <sys/types.h>
|
|
|
| #include <vector>
|
|
|
| #include "ppapi/c/dev/ppb_testing_dev.h"
|
| #include "ppapi/c/pp_errors.h"
|
| #include "ppapi/c/ppb_file_io.h"
|
| +#include "ppapi/c/private/pp_file_handle.h"
|
| #include "ppapi/c/trusted/ppb_file_io_trusted.h"
|
| #include "ppapi/cpp/file_io.h"
|
| #include "ppapi/cpp/file_ref.h"
|
| #include "ppapi/cpp/file_system.h"
|
| #include "ppapi/cpp/instance.h"
|
| #include "ppapi/cpp/module.h"
|
| +#include "ppapi/cpp/private/file_io_private.h"
|
| #include "ppapi/tests/test_utils.h"
|
| #include "ppapi/tests/testing_instance.h"
|
|
|
| +#if defined(PPAPI_OS_WIN)
|
| +# include <io.h>
|
| +# include <windows.h>
|
| +// TODO(hamaji): Use standard windows APIs instead of compatibility layer?
|
| +# define lseek _lseek
|
| +# define read _read
|
| +# define write _write
|
| +# define ssize_t int
|
| +#else
|
| +# include <sys/mman.h>
|
| +# include <unistd.h>
|
| +#endif
|
| +
|
| REGISTER_TEST_CASE(FileIO);
|
|
|
| namespace {
|
| @@ -148,6 +167,7 @@ void TestFileIO::RunTests(const std::string& filter) {
|
| RUN_TEST_FORCEASYNC_AND_NOT(ParallelWrites, filter);
|
| RUN_TEST_FORCEASYNC_AND_NOT(NotAllowMixedReadWrite, filter);
|
| RUN_TEST_FORCEASYNC_AND_NOT(WillWriteWillSetLength, filter);
|
| + RUN_TEST_FORCEASYNC_AND_NOT(RequestOSFileHandle, filter);
|
|
|
| // TODO(viettrungluu): add tests:
|
| // - that PP_ERROR_PENDING is correctly returned
|
| @@ -1248,6 +1268,116 @@ std::string TestFileIO::TestWillWriteWillSetLength() {
|
| PASS();
|
| }
|
|
|
| +std::string TestFileIO::TestRequestOSFileHandle() {
|
| + TestCompletionCallback callback(instance_->pp_instance(), callback_type());
|
| +
|
| + pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
|
| + pp::FileRef file_ref(file_system, "/file_os_fd");
|
| +
|
| + callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
|
| + if (callback.result() != PP_OK)
|
| + return ReportError("FileSystem::Open", callback.result());
|
| +
|
| + pp::FileIO_Private file_io(instance_);
|
| + callback.WaitForResult(file_io.Open(file_ref,
|
| + PP_FILEOPENFLAG_CREATE |
|
| + PP_FILEOPENFLAG_TRUNCATE |
|
| + PP_FILEOPENFLAG_READ |
|
| + PP_FILEOPENFLAG_WRITE,
|
| + callback.GetCallback()));
|
| + if (callback.result() != PP_OK)
|
| + return ReportError("FileIO::Open", callback.result());
|
| +
|
| + PP_FileHandle handle = PP_kInvalidFileHandle;
|
| + callback.WaitForResult(
|
| + file_io.RequestOSFileHandle(&handle, callback.GetCallback()));
|
| + if (callback.result() != PP_OK)
|
| + return ReportError("FileIO::RequestOSFileHandle", callback.result());
|
| +
|
| + if (handle == PP_kInvalidFileHandle)
|
| + return "FileIO::RequestOSFileHandle() returned a bad file handle.";
|
| +#if defined(PPAPI_OS_WIN)
|
| + int fd = _open_osfhandle(reinterpret_cast<intptr_t>(handle),
|
| + _O_RDWR | _O_BINARY);
|
| +#else
|
| + int fd = handle;
|
| +#endif
|
| + if (fd < 0)
|
| + return "FileIO::RequestOSFileHandle() returned a bad file descriptor.";
|
| +
|
| + // Check write(2) for the native FD.
|
| + const std::string msg = "foobar";
|
| + ssize_t cnt = write(fd, msg.data(), msg.size());
|
| + if (cnt < 0)
|
| + return ReportError("write for native FD returned error", errno);
|
| + if (cnt != static_cast<ssize_t>(msg.size()))
|
| + return ReportError("write for native FD count mismatch", cnt);
|
| +
|
| + // Check lseek(2) for the native FD.
|
| + off_t off = lseek(fd, 0, SEEK_CUR);
|
| + if (off == static_cast<off_t>(-1))
|
| + return ReportError("lseek for native FD returned error", errno);
|
| + if (off != static_cast<off_t>(msg.size()))
|
| + return ReportError("lseek for native FD offset mismatch", off);
|
| +
|
| + off = lseek(fd, 0, SEEK_SET);
|
| + if (off == static_cast<off_t>(-1))
|
| + return ReportError("lseek for native FD returned error", errno);
|
| + if (off != 0)
|
| + return ReportError("lseek for native FD offset mismatch", off);
|
| +
|
| + // Check read(2) for the native FD.
|
| + std::string buf(msg.size(), '\0');
|
| + cnt = read(fd, &buf[0], msg.size());
|
| + if (cnt < 0)
|
| + return ReportError("read for native FD returned error", errno);
|
| + if (cnt != static_cast<ssize_t>(msg.size()))
|
| + return ReportError("read for native FD count mismatch", cnt);
|
| + if (msg != buf)
|
| + return ReportMismatch("read for native FD", buf, msg);
|
| +
|
| + // TODO(hamaji): Test CreateFileMapping for windows.
|
| +#if !defined(PPAPI_OS_WIN)
|
| + // Check mmap(2) for read.
|
| + char* mapped = reinterpret_cast<char*>(
|
| + mmap(NULL, msg.size(), PROT_READ, MAP_PRIVATE, fd, 0));
|
| + if (mapped == MAP_FAILED)
|
| + return ReportError("mmap(r) for native FD returned errno", errno);
|
| + // Make sure the buffer is cleared.
|
| + buf = std::string(msg.size(), '\0');
|
| + memcpy(&buf[0], mapped, msg.size());
|
| + if (msg != buf)
|
| + return ReportMismatch("mmap(r) for native FD", buf, msg);
|
| + int r = munmap(mapped, msg.size());
|
| + if (r < 0)
|
| + return ReportError("munmap for native FD returned error", errno);
|
| +
|
| + // Check mmap(2) for write.
|
| + mapped = reinterpret_cast<char*>(
|
| + mmap(NULL, msg.size(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
|
| + if (mapped == MAP_FAILED)
|
| + return ReportError("mmap(w) for native FD returned errno", errno);
|
| + // s/foo/baz/
|
| + strcpy(mapped, "baz");
|
| +
|
| + r = munmap(mapped, msg.size());
|
| + if (r < 0)
|
| + return ReportError("munmap for native FD returned error", errno);
|
| +#endif
|
| +
|
| +#if defined(PPAPI_OS_WIN)
|
| + int r = _close(fd);
|
| +#else
|
| + r = close(handle);
|
| +#endif
|
| + if (r < 0)
|
| + return ReportError("close for native FD returned error", errno);
|
| +
|
| + // TODO(hamaji): Check if the file is actually updated?
|
| +
|
| + PASS();
|
| +}
|
| +
|
| std::string TestFileIO::MatchOpenExpectations(pp::FileSystem* file_system,
|
| size_t open_flags,
|
| size_t expectations) {
|
|
|