#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include "zvfs_hook_mmap.h"
#include "zvfs_hook_init.h"
#include "zvfs_hook_reentrant.h"

#include <errno.h>

/* ------------------------------------------------------------------ */
/* mmap / mmap64                                                        */
/* ------------------------------------------------------------------ */

void *
mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
{
    ZVFS_HOOK_ENTER();

    void *ret;

    /*
     * MAP_ANONYMOUS：不关联任何 fd，直接透传。
     * 非 zvfs fd：直接透传。
     * zvfs fd：返回 ENOTSUP。
     */
    if (ZVFS_IN_HOOK() || (flags & MAP_ANONYMOUS) || !zvfs_is_zvfs_fd(fd)) {
        ret = real_mmap(addr, length, prot, flags, fd, offset);
        ZVFS_HOOK_LEAVE();
        return ret;
    }

    zvfs_ensure_init();

    /* zvfs fd：当前不支持 mmap */
    errno = ENOTSUP;
    ZVFS_HOOK_LEAVE();
    return MAP_FAILED;
}

void *
mmap64(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
{
    /*
     * mmap64 在 64-bit 系统上与 mmap 等价（off_t 已经是 64-bit）。
     * 直接转发。
     */
    return mmap(addr, length, prot, flags, fd, offset);
}

/* ------------------------------------------------------------------ */
/* munmap                                                               */
/* ------------------------------------------------------------------ */

int
munmap(void *addr, size_t length)
{
    ZVFS_HOOK_ENTER();
    /*
     * zvfs 的 mmap 不会成功，所以这里不会有 zvfs 映射需要处理。
     * 直接透传。
     *
     * future：查 mmap_table，命中则 blob_write 写回再透传。
     */
    int r = real_munmap(addr, length);
    ZVFS_HOOK_LEAVE();
    return r;
}

/* ------------------------------------------------------------------ */
/* msync                                                                */
/* ------------------------------------------------------------------ */

int
msync(void *addr, size_t length, int flags)
{
    ZVFS_HOOK_ENTER();
    /*
     * 同 munmap：当前无 zvfs 映射，直接透传。
     *
     * future：查 mmap_table，命中则 blob_write 对应范围。
     */
    int r = real_msync(addr, length, flags);
    ZVFS_HOOK_LEAVE();
    return r;
}
