/* libs/graphics/ports/SkFontHost_fontconfig_direct.cpp ** ** Copyright 2009, Google Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ // http://code.google.com/p/chromium/wiki/LinuxSandboxIPC #include "SkFontHost_fontconfig_ipc.h" #include #include #include #include #include #include "base/pickle.h" #include "base/unix_domain_socket_posix.h" FontConfigIPC::FontConfigIPC(int fd) : fd_(fd) { } FontConfigIPC::~FontConfigIPC() { close(fd_); } static ssize_t SyncIPC(int fd, uint8_t* reply, unsigned reply_len, int* result_fd, const Pickle& request) { int fds[2]; if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fds) == -1) return false; std::vector fd_vector; fd_vector.push_back(fds[1]); if (!base::SendMsg(fd, request.data(), request.size(), fd_vector)) { close(fds[0]); close(fds[1]); return -1; } close(fds[1]); fd_vector.clear(); const ssize_t r = base::RecvMsg(fds[0], reply, reply_len, &fd_vector); close(fds[0]); if (r == -1) return -1; if ((fd_vector.size() > 0 && result_fd == NULL) || fd_vector.size() > 1) { for (std::vector::const_iterator i = fd_vector.begin(); i != fd_vector.end(); ++i) { close(*i); } return -1; } if (result_fd) { if (fd_vector.size() == 0) { *result_fd = -1; } else { *result_fd = fd_vector[0]; } } return r; } bool FontConfigIPC::Match(std::string* result_family, unsigned* result_fileid, bool fileid_valid, unsigned fileid, const std::string& family, int is_bold, int is_italic) { Pickle request; request.WriteInt(METHOD_MATCH); request.WriteBool(fileid_valid); if (fileid_valid) request.WriteUInt32(fileid); request.WriteBool(is_bold); request.WriteBool(is_italic); request.WriteString(family); uint8_t reply_buf[512]; const ssize_t r = SyncIPC(fd_, reply_buf, sizeof(reply_buf), NULL, request); if (r == -1) return false; Pickle reply(reinterpret_cast(reply_buf), r); void* iter = NULL; bool result; if (!reply.ReadBool(&iter, &result)) return false; if (!result) return false; uint32_t reply_fileid; std::string reply_family; if (!reply.ReadUInt32(&iter, &reply_fileid) || !reply.ReadString(&iter, &reply_family)) { return false; } *result_fileid = reply_fileid; if (result_family) *result_family = reply_family; return true; } int FontConfigIPC::Open(unsigned fileid) { Pickle request; request.WriteInt(METHOD_OPEN); request.WriteUInt32(fileid); int result_fd = -1; uint8_t reply_buf[256]; const ssize_t r = SyncIPC(fd_, reply_buf, sizeof(reply_buf), &result_fd, request); if (r == -1) return -1; Pickle reply(reinterpret_cast(reply_buf), r); bool result; void* iter = NULL; if (!reply.ReadBool(&iter, &result) || !result) { if (result_fd) close(result_fd); return -1; } return result_fd; }