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