Unverified Commit 80c1e9b0 authored by Tommaso Tocci's avatar Tommaso Tocci
Browse files

intercept fcntl

fcntl now is intercept and support the F_GETFD/F_SETFD command.
parent f165baa2
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ enum class OpenFile_flags {
    rdonly,
    wronly,
    rdwr,
    cloexec,
    flag_count // this is purely used as a size variable of this enum class
};

+2 −0
Original line number Diff line number Diff line
@@ -66,6 +66,8 @@ extern void* libc_fdatasync;
extern void* libc_truncate;
extern void* libc_ftruncate;

extern void* libc_fcntl;

extern void* libc_dup;
extern void* libc_dup2;
extern void* libc_dup3;
+41 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include <preload/passthrough.hpp>
#include <preload/adafs_functions.hpp>
#include <preload/intcp_functions.hpp>
#include <preload/open_dir.hpp>


using namespace std;
@@ -731,6 +732,46 @@ int ftruncate(int fd, off_t length) __THROW {
    return (reinterpret_cast<decltype(&ftruncate)>(libc_ftruncate))(fd, length);
}

int fcntl(int fd, int cmd, ...) {
    init_passthrough_if_needed();
    va_list ap;
    void *arg;

    va_start (ap, cmd);
    arg = va_arg (ap, void *);
    va_end (ap);

    if(CTX->initialized()) {
        CTX->log()->trace("{}() called with fd {}", __func__, fd);
        if (CTX->file_map()->exist(fd)) {
            switch(cmd) {
                case F_GETFD:
                    CTX->log()->trace("{}() F_GETFD on fd {}", __func__, fd);
                    if(CTX->file_map()->get(fd)
                            ->get_flag(OpenFile_flags::cloexec)) {
                        return FD_CLOEXEC;
                    } else {
                        return 0;
                    }
                case F_SETFD: {
                    va_start (ap, cmd);
                    int flags = va_arg (ap, int);
                    va_end (ap);
                    CTX->log()->trace("{}() [fd: {}, cmd: F_SETFD, FD_CLOEXEC: {}", __func__, fd, (flags & FD_CLOEXEC));
                    CTX->file_map()->get(fd)
                        ->set_flag(OpenFile_flags::cloexec, (flags & FD_CLOEXEC));
                    return 0;
                }
                default:
                    CTX->log()->error("{}() unrecognized command {} on fd {}", __func__, cmd, fd);
                    errno = ENOTSUP;
                    return -1;
            }
        }
    }
    return (reinterpret_cast<decltype(&fcntl)>(libc_fcntl))(fd, cmd, arg);
}

int dup(int oldfd) __THROW {
    init_passthrough_if_needed();
    if(CTX->initialized()) {
+4 −0
Original line number Diff line number Diff line
@@ -71,6 +71,8 @@ void* libc_fdatasync;
void* libc_truncate;
void* libc_ftruncate;

void* libc_fcntl;

void* libc_dup;
void* libc_dup2;
void* libc_dup3;
@@ -150,6 +152,8 @@ void init_passthrough_() {
    libc_truncate = dlsym(libc, "truncate");
    libc_ftruncate = dlsym(libc, "ftruncate");

    libc_fcntl = dlsym(libc, "fcntl");

    libc_dup = dlsym(libc, "dup");
    libc_dup2 = dlsym(libc, "dup2");
    libc_dup3 = dlsym(libc, "dup3");