1 /*
2  * Copyright (C) 2017 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 STAGEFRIGHT_FOUNDATION_FILE_DESCRIPTOR_H_
18 #define STAGEFRIGHT_FOUNDATION_FILE_DESCRIPTOR_H_
19 
20 #include <memory>
21 
22 namespace android {
23 
24 /**
25  * FileDescriptor is a utility class for managing file descriptors in a scoped way.
26  *
27  * usage:
28  *
29  * status_t function(int fd) {
30  *   FileDescriptor::Autoclose managedFd(fd);
31  *   if (error_condition)
32  *     return ERROR;
33  *   next_function(managedFd.release());
34  * }
35  */
36 struct FileDescriptor {
37     // created this class with minimal methods. more methods can be added here to manage
38     // a shared file descriptor object.
39 
40     /**
41      * A locally scoped managed file descriptor object. This object is not shareable/copiable and
42      * is not thread safe.
43      */
44     struct Autoclose {
45         // created this class with minimal methods
46         /**
47          * Creates a locally scoped file descriptor holder object taking ownership of the passed in
48          * file descriptor.
49          */
AutocloseFileDescriptor::Autoclose50         Autoclose(int fd)
51             : mFd(fd) {
52 
53         }
54 
~AutocloseFileDescriptor::Autoclose55         ~Autoclose() {
56             if (isValid()) {
57                 ::close(mFd);
58                 mFd = kInvalidFileDescriptor;
59             }
60         }
61 
62         /**
63          * Releases the managed file descriptor from the holder. This invalidates the (remaining)
64          * file descriptor in this object.
65          */
releaseFileDescriptor::Autoclose66         int release() {
67             int managedFd = mFd;
68             mFd = kInvalidFileDescriptor;
69             return managedFd;
70         }
71 
72         /**
73          * Checks whether the managed file descriptor is valid
74          */
isValidFileDescriptor::Autoclose75         bool isValid() const {
76             return mFd >= 0;
77         }
78 
79     private:
80         // not yet needed
81 
82         /**
83          * Returns the managed file descriptor from this object without releasing the ownership.
84          * The returned file descriptor has the same lifecycle as the managed file descriptor
85          * in this object. Therefore, care must be taken that it is not closed, and that this
86          * object keeps managing the returned file descriptor for the duration of its use.
87          */
getFileDescriptor::Autoclose88         int get() const {
89             return mFd;
90         }
91 
92     private:
93         int mFd;
94 
95         enum {
96             kInvalidFileDescriptor = -1,
97         };
98 
99         DISALLOW_EVIL_CONSTRUCTORS(Autoclose);
100     };
101 
102 private:
103     std::shared_ptr<Autoclose> mSharedFd;
104 };
105 
106 }  // namespace android
107 
108 #endif  // STAGEFRIGHT_FOUNDATION_FLAGGED_H_
109 
110