#include "file_opener.h"
#include <fcntl.h>

file_opener::file_opener(const char* filename, int flags, int dirfd)
{
    errno = 0;
    m_fd = syscall(__NR_openat, dirfd, filename, flags, 0);
    // Using the macro that deals with ENOSYS produces a build issue since GTEST_SKIP returns value in a ctor.
    _assert_syscall_state(SYSCALL_SUCCESS, "openat", m_fd, NOT_EQUAL, -1);
    m_tmpfile_supported = (errno == EOPNOTSUPP);
    if(flags & O_DIRECTORY && strcmp(filename, ".") == 0)
    {
        m_pathname = m_tmpfile_supported? std::string(".tmpfile") : std::string(".");
    }
    else
    {
        m_pathname = std::string(filename);
    }

    m_flags = flags;

    if(!m_tmpfile_supported && m_flags & O_TMPFILE)
    {
        m_flags ^= O_TMPFILE;
        m_flags |= O_CREAT;
    }
}

file_opener::~file_opener()
{
    close();
}

void file_opener::close()
{
    syscall(__NR_close, m_fd);
    if(m_tmpfile_supported)
    {
        unlink(m_pathname.c_str());
    }
}

 bool file_opener::is_tmpfile_supported() const
{
    return m_tmpfile_supported;
}

 int file_opener::get_fd() const
{
    return m_fd;
}

 int file_opener::get_flags() const
{
    return m_flags;
}

const char* file_opener::get_pathname() const
{
    return m_pathname.c_str();
}
