158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger/*
258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * Copyright 2013 Google Inc.
358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger *
458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * found in the LICENSE file.
658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger */
758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkOSFile.h"
958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
1058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkTFitsIn.h"
1158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
1258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include <stdio.h>
1358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include <sys/mman.h>
1458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include <sys/stat.h>
1558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include <sys/types.h>
1658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
1758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergertypedef struct {
1858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    dev_t dev;
1958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    ino_t ino;
2058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} SkFILEID;
2158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
2258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic bool sk_ino(SkFILE* a, SkFILEID* id) {
2358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    int fd = fileno((FILE*)a);
2458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (fd < 0) {
2558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        return 0;
2658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
2758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    struct stat status;
2858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (0 != fstat(fd, &status)) {
2958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        return 0;
3058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
3158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    id->dev = status.st_dev;
3258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    id->ino = status.st_ino;
3358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    return true;
3458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
3558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
3658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerbool sk_fidentical(SkFILE* a, SkFILE* b) {
3758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkFILEID aID, bID;
3858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    return sk_ino(a, &aID) && sk_ino(b, &bID)
3958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger           && aID.ino == bID.ino
4058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger           && aID.dev == bID.dev;
4158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
4258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
4358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergervoid sk_fmunmap(const void* addr, size_t length) {
4458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    munmap(const_cast<void*>(addr), length);
4558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
4658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
4758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergervoid* sk_fdmmap(int fd, size_t* size) {
4858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    struct stat status;
4958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (0 != fstat(fd, &status)) {
5058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        return NULL;
5158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
5258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (!S_ISREG(status.st_mode)) {
5358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        return NULL;
5458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
5558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (!SkTFitsIn<size_t>(status.st_size)) {
5658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        return NULL;
5758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
5858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    size_t fileSize = static_cast<size_t>(status.st_size);
5958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
6058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    void* addr = mmap(NULL, fileSize, PROT_READ, MAP_PRIVATE, fd, 0);
6158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (MAP_FAILED == addr) {
6258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        return NULL;
6358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
6458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
6558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    *size = fileSize;
6658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    return addr;
6758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
6858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
6958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerint sk_fileno(SkFILE* f) {
7058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    return fileno((FILE*)f);
7158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
7258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
7358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergervoid* sk_fmmap(SkFILE* f, size_t* size) {
7458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    int fd = sk_fileno(f);
7558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (fd < 0) {
7658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        return NULL;
7758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
7858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
7958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    return sk_fdmmap(fd, size);
8058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
81