1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "content/common/font_config_ipc_linux.h" 6 7#include <errno.h> 8#include <fcntl.h> 9#include <sys/mman.h> 10#include <sys/socket.h> 11#include <sys/stat.h> 12#include <sys/uio.h> 13#include <unistd.h> 14 15#include "base/debug/trace_event.h" 16#include "base/file_util.h" 17#include "base/pickle.h" 18#include "base/posix/unix_domain_socket_linux.h" 19#include "skia/ext/refptr.h" 20#include "skia/ext/skia_utils_base.h" 21#include "third_party/skia/include/core/SkData.h" 22#include "third_party/skia/include/core/SkStream.h" 23 24namespace content { 25 26// Return a stream from the file descriptor, or NULL on failure. 27SkStream* StreamFromFD(int fd) { 28 skia::RefPtr<SkData> data = skia::AdoptRef(SkData::NewFromFD(fd)); 29 if (!data) { 30 return NULL; 31 } 32 return new SkMemoryStream(data.get()); 33} 34 35void CloseFD(int fd) { 36 int err = IGNORE_EINTR(close(fd)); 37 DCHECK(!err); 38} 39 40FontConfigIPC::FontConfigIPC(int fd) 41 : fd_(fd) { 42} 43 44FontConfigIPC::~FontConfigIPC() { 45 CloseFD(fd_); 46} 47 48bool FontConfigIPC::matchFamilyName(const char familyName[], 49 SkTypeface::Style requestedStyle, 50 FontIdentity* outFontIdentity, 51 SkString* outFamilyName, 52 SkTypeface::Style* outStyle) { 53 TRACE_EVENT0("sandbox_ipc", "FontConfigIPC::matchFamilyName"); 54 size_t familyNameLen = familyName ? strlen(familyName) : 0; 55 if (familyNameLen > kMaxFontFamilyLength) 56 return false; 57 58 Pickle request; 59 request.WriteInt(METHOD_MATCH); 60 request.WriteData(familyName, familyNameLen); 61 request.WriteUInt32(requestedStyle); 62 63 uint8_t reply_buf[2048]; 64 const ssize_t r = UnixDomainSocket::SendRecvMsg(fd_, reply_buf, 65 sizeof(reply_buf), NULL, 66 request); 67 if (r == -1) 68 return false; 69 70 Pickle reply(reinterpret_cast<char*>(reply_buf), r); 71 PickleIterator iter(reply); 72 bool result; 73 if (!reply.ReadBool(&iter, &result)) 74 return false; 75 if (!result) 76 return false; 77 78 SkString reply_family; 79 FontIdentity reply_identity; 80 uint32_t reply_style; 81 if (!skia::ReadSkString(reply, &iter, &reply_family) || 82 !skia::ReadSkFontIdentity(reply, &iter, &reply_identity) || 83 !reply.ReadUInt32(&iter, &reply_style)) { 84 return false; 85 } 86 87 if (outFontIdentity) 88 *outFontIdentity = reply_identity; 89 if (outFamilyName) 90 *outFamilyName = reply_family; 91 if (outStyle) 92 *outStyle = static_cast<SkTypeface::Style>(reply_style); 93 94 return true; 95} 96 97SkStream* FontConfigIPC::openStream(const FontIdentity& identity) { 98 TRACE_EVENT0("sandbox_ipc", "FontConfigIPC::openStream"); 99 Pickle request; 100 request.WriteInt(METHOD_OPEN); 101 request.WriteUInt32(identity.fID); 102 103 int result_fd = -1; 104 uint8_t reply_buf[256]; 105 const ssize_t r = UnixDomainSocket::SendRecvMsg(fd_, reply_buf, 106 sizeof(reply_buf), 107 &result_fd, request); 108 109 if (r == -1) 110 return NULL; 111 112 Pickle reply(reinterpret_cast<char*>(reply_buf), r); 113 bool result; 114 PickleIterator iter(reply); 115 if (!reply.ReadBool(&iter, &result) || 116 !result) { 117 if (result_fd) 118 CloseFD(result_fd); 119 return NULL; 120 } 121 122 SkStream* stream = StreamFromFD(result_fd); 123 CloseFD(result_fd); 124 return stream; 125} 126 127} // namespace content 128 129