1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
17 #ifndef MEDIAPROVIDER_PDF_JNI_EXTERNAL_FILE_UTIL_LINUX_FILEOPS_H__
18 #define MEDIAPROVIDER_PDF_JNI_EXTERNAL_FILE_UTIL_LINUX_FILEOPS_H__
19 
20 #include <dirent.h>
21 
22 #include <ostream>
23 
24 namespace pdfClient {
25 // Whether to resolve symbolic links.
26 enum class Resolve {
27     // Do not resolve symbolic links.
28     kNone,
29 
30     // Fully resolve symbolic links.
31     kFull,
32 };
33 
34 // File types returned by GetFileType.  These are compatible with the d_type
35 // field in struct dirent.
36 enum class FileType : unsigned char {
37     kUnknown = DT_UNKNOWN,
38     kPipe = DT_FIFO,
39     kCharacterDevice = DT_CHR,
40     kDirectory = DT_DIR,
41     kBlockDevice = DT_BLK,
42     kRegular = DT_REG,
43     kSymbolicLink = DT_LNK,
44     kSocket = DT_SOCK,
45 };
46 
47 std::ostream& operator<<(std::ostream& stream, FileType type);
48 
49 class LinuxFileOps {
50   public:
51     // Helper class for scoping closes for file descriptors,
52     // like a FileCloser for FD's.
53     class FDCloser {
54       public:
55         explicit FDCloser(int fd = kCanonicalInvalidFd);
56         // Not copyable.
57         FDCloser(const FDCloser&) = delete;
58         FDCloser& operator=(const FDCloser&) = delete;
59         // Move-only. Following the move, the moved-from object 'orig' is guaranteed
60         // to be in the disengaged state, where get() returns an invalid (< 0) file
61         // descriptor.
62         FDCloser(FDCloser&& orig);
63         FDCloser& operator=(FDCloser&& orig);
64         ~FDCloser();
65 
66         // Get the file descriptor which the FDCloser is scoping.
67         int get() const;
68         // Close the file descriptor.
69         bool Close();
70 
71         // Release ownership of the file descriptor and return it.
72         int Release();
73 
74         // Swap the internal state with another FDCloser.
75         void Swap(FDCloser* other);
76 
77       private:
78         // Constant used to represent the disengaged state. The current logic treats
79         // all fd_ values as valid except for -1. However all values < 0 are
80         // invalid per POSIX. See
81         // http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_166
82         static constexpr int kCanonicalInvalidFd = -1;
83 
84         int fd_;
85     };
86 
87     static bool CloseFD(int fd);
88 };
89 
90 }  // namespace pdfClient
91 
92 #endif  // MEDIAPROVIDER_PDF_JNI_EXTERNAL_FILE_UTIL_LINUX_FILEOPS_H__