Chromium Code Reviews| Index: skia/ext/SkFontHost_fontconfig_ipc.cpp |
| diff --git a/skia/ext/SkFontHost_fontconfig_ipc.cpp b/skia/ext/SkFontHost_fontconfig_ipc.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..e9ca6920ef21231f49c2723d8129b5d76d151d42 |
| --- /dev/null |
| +++ b/skia/ext/SkFontHost_fontconfig_ipc.cpp |
| @@ -0,0 +1,164 @@ |
| +/* 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 <errno.h> |
| +#include <unistd.h> |
| +#include <fcntl.h> |
| +#include <sys/socket.h> |
| +#include <sys/uio.h> |
| + |
| +FontConfigIPC::FontConfigIPC(int fd) |
| + : fd_(fd) { |
| +} |
| + |
| +FontConfigIPC::~FontConfigIPC() { |
| + close(fd_); |
| +} |
| + |
| +static ssize_t SyncIPC(int fd, const struct iovec* output, unsigned output_len, |
| + int* result_fd, const struct iovec* input, |
| + unsigned input_len) { |
| + char cmsg_buf[CMSG_SPACE(sizeof(int))]; |
| + |
| + int fds[2]; |
| + if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fds) == -1) |
| + return false; |
| + |
| + struct msghdr msg = {0}; |
| + msg.msg_iov = const_cast<struct iovec*>(input); |
| + msg.msg_iovlen = input_len; |
| + msg.msg_control = cmsg_buf; |
| + msg.msg_controllen = sizeof(cmsg_buf); |
| + |
| + struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); |
| + cmsg->cmsg_level = SOL_SOCKET; |
| + cmsg->cmsg_type = SCM_RIGHTS; |
| + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); |
| + *(int *) CMSG_DATA(cmsg) = fds[1]; |
| + msg.msg_controllen = cmsg->cmsg_len; |
| + |
| + ssize_t r; |
| + do { |
| + r = sendmsg(fd, &msg, 0); |
| + } while (r == -1 && errno == EINTR); |
| + close(fds[1]); |
| + |
| + if (r == -1) { |
| + close(fds[0]); |
| + return -1; |
| + } |
| + |
| + memset(&msg, 0, sizeof(msg)); |
|
Lei Zhang
2009/06/04 01:30:43
fta reports compile failure. http://paste.ubuntu.c
|
| + |
| + msg.msg_iov = const_cast<struct iovec*>(output); |
| + msg.msg_iovlen = output_len; |
| + msg.msg_control = cmsg_buf; |
| + msg.msg_controllen = sizeof(cmsg_buf); |
| + |
| + do { |
| + r = recvmsg(fds[0], &msg, 0); |
| + } while (r == -1 && errno == EINTR); |
| + close(fds[0]); |
| + |
| + if (r == -1 || msg.msg_flags & (MSG_TRUNC | MSG_CTRUNC)) |
| + return -1; |
| + |
| + cmsg = CMSG_FIRSTHDR(&msg); |
| + if (cmsg && cmsg->cmsg_level == SOL_SOCKET && |
| + cmsg->cmsg_type == SCM_RIGHTS) { |
| + const int fd = *(int*) CMSG_DATA(cmsg); |
| + if (!result_fd) |
| + close(fd); |
| + *result_fd = fd; |
| + } |
| + |
| + 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) { |
| + MatchRequest request; |
| + request.method = METHOD_MATCH; |
| + request.fileid_valid = fileid_valid; |
| + request.fileid = fileid; |
| + request.is_bold = is_bold; |
| + request.is_italic = is_italic; |
| + |
| + if (family.size() > 255) |
| + return false; |
| + request.family_len = family.size(); |
| + |
| + struct iovec out_iov[2]; |
| + out_iov[0].iov_base = &request; |
| + out_iov[0].iov_len = sizeof(request); |
| + if (family.size()) { |
| + out_iov[1].iov_base = const_cast<char*>(family.data()); |
| + out_iov[1].iov_len = family.size(); |
| + } |
| + |
| + MatchReply reply; |
| + char filename_buf[PATH_MAX]; |
|
Lei Zhang
2009/06/04 01:30:43
and limits.h
|
| + |
| + struct iovec in_iov[2]; |
| + in_iov[0].iov_base = &reply; |
| + in_iov[0].iov_len = sizeof(reply); |
| + in_iov[1].iov_base = filename_buf; |
| + in_iov[1].iov_len = sizeof(filename_buf); |
| + |
| + const ssize_t r = SyncIPC(fd_, in_iov, 2, NULL, out_iov, |
| + family.size() ? 2 : 1); |
| + |
| + if (r == -1 || r < sizeof(reply)) |
| + return false; |
| + |
| + if (reply.result == 0) |
| + return false; |
| + |
| + *result_fileid = reply.result_fileid; |
| + if (r != sizeof(reply) + reply.filename_len) |
| + return false; |
| + if (result_family) |
| + *result_family = std::string(filename_buf, reply.filename_len); |
| + |
| + return true; |
| +} |
| + |
| +int FontConfigIPC::Open(unsigned fileid) { |
| + OpenRequest request; |
| + OpenReply reply; |
| + const struct iovec out_iov = {&request, sizeof(request)}; |
| + const struct iovec in_iov = {&reply, sizeof(reply)}; |
| + int result_fd = -1; |
| + |
| + request.method = METHOD_OPEN; |
| + request.fileid = fileid; |
| + const ssize_t r = SyncIPC(fd_, &in_iov, 1, &result_fd, &out_iov, 1); |
| + if (r == -1 || r != sizeof(reply) || reply.result == 0) { |
| + if (result_fd >= 0) |
| + close(result_fd); |
| + return -1; |
| + } |
| + |
| + return result_fd; |
| +} |