1// Copyright 2018 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <fcntl.h> 6#include <unistd.h> 7 8#include <fbl/unique_fd.h> 9#include <fuchsia/io/c/fidl.h> 10#include <lib/async-loop/cpp/loop.h> 11#include <lib/memfs/memfs.h> 12#include <lib/fzl/fdio.h> 13#include <unittest/unittest.h> 14 15namespace { 16 17bool fdio_call_io() { 18 BEGIN_TEST; 19 20 // Create a Memfs filesystem. 21 async::Loop loop(&kAsyncLoopConfigNoAttachToThread); 22 ASSERT_EQ(loop.StartThread(), ZX_OK); 23 ASSERT_EQ(memfs_install_at(loop.dispatcher(), "/my-tmp"), ZX_OK); 24 fbl::unique_fd dir(open("/my-tmp", O_DIRECTORY | O_RDONLY)); 25 ASSERT_TRUE(dir); 26 27 // Open a file within the filesystem. 28 fbl::unique_fd fd(openat(dir.get(), "my-file", O_CREAT | O_RDWR)); 29 ASSERT_TRUE(fd); 30 31 // Try some filesystem operations natively: 32 fzl::FdioCaller caller(fbl::move(fd)); 33 ASSERT_TRUE(caller); 34 35 const char* golden = "foobar"; 36 zx_status_t status; 37 uint64_t actual; 38 ASSERT_EQ(fuchsia_io_FileWrite(caller.borrow_channel(), 39 reinterpret_cast<const uint8_t*>(golden), 40 strlen(golden), &status, &actual), 41 ZX_OK); 42 ASSERT_EQ(status, ZX_OK); 43 ASSERT_EQ(actual, strlen(golden)); 44 45 ASSERT_EQ(fuchsia_io_FileSeek(caller.borrow_channel(), 0L, fuchsia_io_SeekOrigin_START, 46 &status, &actual), 47 ZX_OK); 48 ASSERT_EQ(status, ZX_OK); 49 ASSERT_EQ(actual, 0); 50 51 char buf[256]; 52 ASSERT_EQ(fuchsia_io_FileRead(caller.borrow_channel(), static_cast<uint64_t>(sizeof(buf)), 53 &status, reinterpret_cast<uint8_t*>(buf), sizeof(buf), &actual), 54 ZX_OK); 55 ASSERT_EQ(status, ZX_OK); 56 ASSERT_EQ(actual, strlen(golden)); 57 ASSERT_EQ(memcmp(buf, golden, strlen(golden)), 0); 58 59 // Re-acquire the underlying fd. 60 fd = caller.release(); 61 ASSERT_EQ(close(fd.release()), 0); 62 63 END_TEST; 64} 65 66} // namespace 67 68BEGIN_TEST_CASE(fdio_call_tests) 69RUN_TEST(fdio_call_io) 70END_TEST_CASE(fdio_call_tests) 71 72