2 * Copyright 2017 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <folly/File.h>
19 #include <folly/String.h>
20 #include <folly/portability/Fcntl.h>
21 #include <folly/portability/GTest.h>
23 using namespace folly;
26 void expectWouldBlock(ssize_t r) {
27 int savedErrno = errno;
29 EXPECT_EQ(EAGAIN, savedErrno) << errnoStr(savedErrno);
31 void expectOK(ssize_t r) {
32 int savedErrno = errno;
33 EXPECT_LE(0, r) << ": errno=" << errnoStr(savedErrno);
38 // Open a file, ensure it's indeed open for reading
42 EXPECT_NE(-1, f.fd());
43 EXPECT_EQ(1, ::read(f.fd(), &buf, 1));
45 EXPECT_EQ(-1, f.fd());
49 TEST(File, SimpleStringPiece) {
51 File f(StringPiece("/etc/hosts"));
52 EXPECT_NE(-1, f.fd());
53 EXPECT_EQ(1, ::read(f.fd(), &buf, 1));
55 EXPECT_EQ(-1, f.fd());
59 // Wrap a file descriptor, make sure that ownsFd works
60 // We'll test that the file descriptor is closed by closing the writing
61 // end of a pipe and making sure that a non-blocking read from the reading
67 int flags = ::fcntl(p[0], F_GETFL);
69 expectOK(::fcntl(p[0], F_SETFL, flags | O_NONBLOCK));
70 expectWouldBlock(::read(p[0], &buf, 1));
73 EXPECT_EQ(p[1], f.fd());
75 // Ensure that moving the file doesn't close it
78 EXPECT_EQ(p[1], f.fd());
79 File f1(std::move(f));
80 EXPECT_EQ(-1, f.fd());
81 EXPECT_EQ(p[1], f1.fd());
83 expectWouldBlock(::read(p[0], &buf, 1)); // not closed
86 EXPECT_EQ(p[1], f.fd());
88 ssize_t r = ::read(p[0], &buf, 1); // eof
95 File in(STDOUT_FILENO, false);
96 CHECK_EQ(STDOUT_FILENO, in.release());
97 CHECK_EQ(-1, in.release());
100 #define EXPECT_CONTAINS(haystack, needle) \
101 EXPECT_NE(::std::string::npos, ::folly::StringPiece(haystack).find(needle)) \
102 << "Haystack: '" << haystack << "'\nNeedle: '" << needle << "'";
104 TEST(File, UsefulError) {
106 File("does_not_exist.txt", 0, 0666);
107 } catch (const std::runtime_error& e) {
108 EXPECT_CONTAINS(e.what(), "does_not_exist.txt");
109 EXPECT_CONTAINS(e.what(), "0666");
114 File temp = File::temporary();
116 EXPECT_TRUE(bool(temp));
124 if (File file = File::temporary()) {
130 EXPECT_FALSE(bool(File()));
134 if (File notOpened = File()) {