143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar/*
243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * Copyright (C) 2017 The Android Open Source Project
343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar *
443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * Licensed under the Apache License, Version 2.0 (the "License");
543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * you may not use this file except in compliance with the License.
643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * You may obtain a copy of the License at
743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar *
843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar *      http://www.apache.org/licenses/LICENSE-2.0
943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar *
1043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * Unless required by applicable law or agreed to in writing, software
1143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * distributed under the License is distributed on an "AS IS" BASIS,
1243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * See the License for the specific language governing permissions and
1443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * limitations under the License.
1543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar */
1643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
1743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar#ifndef STAGEFRIGHT_FOUNDATION_FILE_DESCRIPTOR_H_
1843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar#define STAGEFRIGHT_FOUNDATION_FILE_DESCRIPTOR_H_
1943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
2043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar#include <memory>
2143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
2243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarnamespace android {
2343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
2443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar/**
2543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * FileDescriptor is a utility class for managing file descriptors in a scoped way.
2643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar *
2743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * usage:
2843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar *
2943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * status_t function(int fd) {
3043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar *   FileDescriptor::Autoclose managedFd(fd);
3143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar *   if (error_condition)
3243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar *     return ERROR;
3343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar *   next_function(managedFd.release());
3443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar * }
3543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar */
3643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarstruct FileDescriptor {
3743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // created this class with minimal methods. more methods can be added here to manage
3843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    // a shared file descriptor object.
3943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
4043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    /**
4143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * A locally scoped managed file descriptor object. This object is not shareable/copiable and
4243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     * is not thread safe.
4343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar     */
4443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    struct Autoclose {
4543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // created this class with minimal methods
4643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        /**
4743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar         * Creates a locally scoped file descriptor holder object taking ownership of the passed in
4843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar         * file descriptor.
4943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar         */
5043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        Autoclose(int fd)
5143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            : mFd(fd) {
5243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
5343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        }
5443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
5543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        ~Autoclose() {
5643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            if (isValid()) {
5743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                ::close(mFd);
5843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar                mFd = kInvalidFileDescriptor;
5943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            }
6043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        }
6143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
6243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        /**
6343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar         * Releases the managed file descriptor from the holder. This invalidates the (remaining)
6443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar         * file descriptor in this object.
6543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar         */
6643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        int release() {
6743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            int managedFd = mFd;
6843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            mFd = kInvalidFileDescriptor;
6943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            return managedFd;
7043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        }
7143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
7243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        /**
7343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar         * Checks whether the managed file descriptor is valid
7443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar         */
7543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        bool isValid() const {
7643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            return mFd >= 0;
7743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        }
7843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
7943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    private:
8043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        // not yet needed
8143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
8243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        /**
8343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar         * Returns the managed file descriptor from this object without releasing the ownership.
8443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar         * The returned file descriptor has the same lifecycle as the managed file descriptor
8543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar         * in this object. Therefore, care must be taken that it is not closed, and that this
8643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar         * object keeps managing the returned file descriptor for the duration of its use.
8743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar         */
8843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        int get() const {
8943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            return mFd;
9043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        }
9143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
9243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    private:
9343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        int mFd;
9443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
9543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        enum {
9643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar            kInvalidFileDescriptor = -1,
9743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        };
9843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
9943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar        DISALLOW_EVIL_CONSTRUCTORS(Autoclose);
10043fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    };
10143fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
10243fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnarprivate:
10343fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar    std::shared_ptr<Autoclose> mSharedFd;
10443fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar};
10543fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
10643fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar}  // namespace android
10743fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
10843fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar#endif  // STAGEFRIGHT_FOUNDATION_FLAGGED_H_
10943fb79ad6ffecb86d5041afd8c06b764fb6f934fLajos Molnar
110